spi_main.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/init.h>
  4. #include <linux/cdev.h>
  5. #include <linux/fs.h>
  6. #include <linux/errno.h>
  7. #include <asm/current.h>
  8. #include <linux/sched.h>
  9. #include <linux/device.h>
  10. #include <linux/err.h>
  11. #include "asm/uaccess.h"
  12. #include <linux/delay.h>
  13. #include "com_gpio.h"
  14. #include "stm32f4xx.h"
  15. #include "stm32_hal_legacy.h"
  16. #include "stm32f4xx_hal_spi.h"
  17. #include "stm32f4xx_hal_gpio.h"
  18. #include "driver.h"
  19. static int major = MAJOR_SPI;
  20. static int ret=0;
  21. #define DEVNAME "spi"
  22. #define NUM_OF_DEVICES 6
  23. struct spi_device {
  24. dev_t devno;
  25. struct cdev cdev;
  26. char name[16];
  27. //IRQn_Type Event_IRQn;
  28. //IRQn_Type Err_IRQn;
  29. } spi_dev[NUM_OF_DEVICES];
  30. SPI_HandleTypeDef hspi1, hspi2, hspi3, hspi4, hspi5, hspi6;
  31. static int spi_open(struct inode *inode, struct file *filep);
  32. static int spi_close(struct inode *inode, struct file *filep);
  33. static ssize_t spi_read(struct file *filep, char __user *buf, size_t size, loff_t *offset);
  34. static ssize_t spi_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset);
  35. static int spi_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
  36. static struct file_operations spi_ops =
  37. {
  38. .owner = THIS_MODULE,
  39. .open = spi_open,
  40. .release = spi_close,
  41. .ioctl = spi_ioctl,
  42. .read = spi_read,
  43. .write = spi_write,
  44. };
  45. static int spi_open(struct inode *inode, struct file *filep)
  46. {
  47. SPI_HandleTypeDef *pHspi;
  48. int imajor,iminor;
  49. imajor = MAJOR(inode->i_rdev);
  50. iminor = MINOR(inode->i_rdev);
  51. if(imajor != major)
  52. {
  53. printk("Error: %s %d spi major fail! %d\n",__FILE__,__LINE__,imajor);
  54. return -1;
  55. }
  56. //printk("---> open major=%d, minor=%d\n",imajor,iminor);
  57. switch(iminor)
  58. {
  59. case 0:
  60. pHspi = &hspi1;
  61. break;
  62. case 1:
  63. pHspi = &hspi2;
  64. break;
  65. case 2:
  66. pHspi = &hspi3;
  67. break;
  68. case 3:
  69. pHspi = &hspi4;
  70. break;
  71. case 4:
  72. pHspi = &hspi5;
  73. break;
  74. case 5:
  75. pHspi = &hspi6;
  76. break;
  77. default:
  78. printk("Error:%s %d Invalid minor %d",__FILE__,__LINE__,iminor);
  79. return -1;
  80. }
  81. __HAL_SPI_ENABLE(pHspi);
  82. return 0;
  83. }
  84. static int spi_close(struct inode *inode, struct file *filep)
  85. {
  86. SPI_HandleTypeDef *pHspi;
  87. int imajor,iminor;
  88. imajor = MAJOR(inode->i_rdev);
  89. iminor = MINOR(inode->i_rdev);
  90. if(imajor != major)
  91. {
  92. printk("Error: %s %d spi major fail! %d\n",__FILE__,__LINE__,imajor);
  93. return -1;
  94. }
  95. //printk("---> close major=%d, minor=%d\n",imajor,iminor);
  96. switch(iminor)
  97. {
  98. case 0:
  99. pHspi = &hspi1;
  100. break;
  101. case 1:
  102. pHspi = &hspi2;
  103. break;
  104. case 2:
  105. pHspi = &hspi3;
  106. break;
  107. case 3:
  108. pHspi = &hspi4;
  109. break;
  110. case 4:
  111. pHspi = &hspi5;
  112. break;
  113. case 5:
  114. pHspi = &hspi6;
  115. break;
  116. default:
  117. printk("Error:%s %d Invalid minor %d",__FILE__,__LINE__,iminor);
  118. return -1;
  119. }
  120. __HAL_SPI_DISABLE(pHspi);
  121. return 0;
  122. }
  123. static int spi_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg)
  124. {
  125. HAL_StatusTypeDef ret = HAL_OK;
  126. spi_arg_t spi_args;
  127. int imajor,iminor;
  128. SPI_HandleTypeDef *pHspi;
  129. int i;
  130. imajor = MAJOR(inode->i_rdev);
  131. iminor = MINOR(inode->i_rdev);
  132. if(imajor != MAJOR_SPI)
  133. {
  134. printk("Error: %s %d spi major fail! %d\n",__FILE__,__LINE__,imajor);
  135. return -EFAULT;
  136. }
  137. switch(iminor)
  138. {
  139. case 0:
  140. pHspi = &hspi1;
  141. break;
  142. case 1:
  143. pHspi = &hspi2;
  144. break;
  145. case 2:
  146. pHspi = &hspi3;
  147. break;
  148. case 3:
  149. pHspi = &hspi4;
  150. break;
  151. case 4:
  152. pHspi = &hspi5;
  153. break;
  154. case 5:
  155. pHspi = &hspi6;
  156. break;
  157. default:
  158. printk("Error:%s %d Invalid minor %d",__FILE__,__LINE__,iminor);
  159. return -1;
  160. }
  161. if ( copy_from_user(&spi_args, (void*)arg, sizeof(spi_arg_t)) != 0)
  162. {
  163. printk("---> copy form user space fail!\n");
  164. return -1;
  165. }
  166. switch(cmd)
  167. {
  168. case SPI_MASTER_TRANSFER:
  169. // printk("SPI%d_transfer %d: ", iminor+1, spi_args.Size);
  170. // for(i=0;i<spi_args.Size;i++)
  171. // {
  172. // printk("%#x ", spi_args.buf[i]);
  173. // }
  174. // printk("\n");
  175. ret = HAL_SPI_Transmit( pHspi, spi_args.buf, spi_args.Size, HAL_MAX_DELAY);
  176. if(ret != HAL_OK)
  177. {
  178. printk("SPI master transfer error, %d\n", ret);
  179. }
  180. break;
  181. case SPI_MASTER_RECEIVE:
  182. ret = HAL_SPI_Receive(pHspi, spi_args.buf, spi_args.Size, HAL_MAX_DELAY);
  183. if(ret != HAL_OK)
  184. {
  185. printk("SPI master transfer error, %d\n", ret);
  186. }
  187. // printk("SPI%d_receive %d: ", iminor+1, spi_args.Size);
  188. // for(i=0;i<spi_args.Size;i++)
  189. // {
  190. // printk("%#x ", spi_args.buf[i]);
  191. // }
  192. // printk("\n");
  193. if ( copy_to_user((void*)arg, &spi_args, sizeof(spi_arg_t)) != 0)
  194. {
  195. printk("---> copy to user space fail!\n");
  196. return -1;
  197. }
  198. break;
  199. default:
  200. printk("---> Invalid action\n");
  201. ret = -1;
  202. break;
  203. }
  204. return ret;
  205. }
  206. static ssize_t spi_read(struct file *filep, char __user *buf, size_t size, loff_t *offset)
  207. {
  208. return 0;
  209. }
  210. static ssize_t spi_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset)
  211. {
  212. return 0;
  213. }
  214. void spi_hw_init(void)
  215. {
  216. GPIO_InitTypeDef spi_gpio;
  217. //SPI1
  218. //SPI2
  219. __HAL_RCC_GPIOI_CLK_ENABLE();
  220. spi_gpio.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
  221. spi_gpio.Mode = GPIO_MODE_AF_PP;
  222. spi_gpio.Pull = GPIO_PULLUP;
  223. spi_gpio.Speed = GPIO_SPEED_FREQ_HIGH;
  224. spi_gpio.Alternate = GPIO_AF5_SPI2;
  225. HAL_GPIO_Init(GPIOI, &spi_gpio);
  226. //NSS
  227. HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_SET);
  228. spi_gpio.Pin = GPIO_PIN_0;
  229. spi_gpio.Mode = GPIO_MODE_OUTPUT_PP;
  230. spi_gpio.Pull = GPIO_PULLUP;
  231. spi_gpio.Speed = GPIO_SPEED_FREQ_HIGH;
  232. HAL_GPIO_Init(GPIOI, &spi_gpio);
  233. __HAL_RCC_SPI2_CLK_ENABLE();
  234. hspi2.Instance = SPI2;
  235. hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  236. hspi2.Init.Mode = SPI_MODE_MASTER;
  237. hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  238. hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
  239. hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
  240. hspi2.Init.NSS = SPI_NSS_SOFT;
  241. hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
  242. hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  243. hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  244. hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  245. hspi2.Init.CRCPolynomial = 0;
  246. HAL_SPI_Init(&hspi2);
  247. //SPI3
  248. //SPI4
  249. //SPI5
  250. __HAL_RCC_GPIOF_CLK_ENABLE();
  251. spi_gpio.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9;
  252. spi_gpio.Mode = GPIO_MODE_AF_PP;
  253. spi_gpio.Pull = GPIO_PULLUP;
  254. spi_gpio.Speed = GPIO_SPEED_FREQ_HIGH;
  255. spi_gpio.Alternate = GPIO_AF5_SPI5;
  256. HAL_GPIO_Init(GPIOF, &spi_gpio);
  257. //NSS
  258. HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_SET);
  259. spi_gpio.Pin = GPIO_PIN_6;
  260. spi_gpio.Mode = GPIO_MODE_OUTPUT_PP;
  261. spi_gpio.Pull = GPIO_PULLUP;
  262. spi_gpio.Speed = GPIO_SPEED_FREQ_HIGH;
  263. HAL_GPIO_Init(GPIOF, &spi_gpio);
  264. __HAL_RCC_SPI5_CLK_ENABLE();
  265. hspi5.Instance = SPI5;
  266. hspi5.Init.Direction = SPI_DIRECTION_2LINES;
  267. hspi5.Init.Mode = SPI_MODE_MASTER;
  268. hspi5.Init.DataSize = SPI_DATASIZE_8BIT;
  269. hspi5.Init.CLKPolarity = SPI_POLARITY_HIGH;
  270. hspi5.Init.CLKPhase = SPI_PHASE_2EDGE;
  271. hspi5.Init.NSS = SPI_NSS_SOFT;
  272. hspi5.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
  273. hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;
  274. hspi5.Init.TIMode = SPI_TIMODE_DISABLE;
  275. hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  276. hspi5.Init.CRCPolynomial = 0;
  277. HAL_SPI_Init(&hspi5);
  278. //SPI6
  279. }
  280. static int __init spi_init(void)
  281. {
  282. int ret;
  283. //SPI1
  284. //SPI2
  285. printk("spi2 module start ...\n");
  286. spi_dev[1].devno = MKDEV(MAJOR_SPI, 1);
  287. sprintf(spi_dev[1].name, "%s%d", DEVNAME, 2);
  288. register_chrdev_region(spi_dev[1].devno, 1, spi_dev[1].name);
  289. cdev_add(&spi_dev[1].cdev, spi_dev[1].devno, 1);
  290. cdev_init(&spi_dev[1].cdev, &spi_ops);
  291. //SPI3
  292. //SPI4
  293. //SPI5
  294. printk("spi5 module start ...\n");
  295. spi_dev[4].devno = MKDEV(MAJOR_SPI, 4);
  296. sprintf(spi_dev[4].name, "%s%d", DEVNAME, 5);
  297. register_chrdev_region(spi_dev[4].devno, 1, spi_dev[4].name);
  298. cdev_add(&spi_dev[4].cdev, spi_dev[4].devno, 1);
  299. cdev_init(&spi_dev[4].cdev, &spi_ops);
  300. //SPI6
  301. spi_hw_init();
  302. return 0;
  303. ERR_STEP1:
  304. unregister_chrdev_region(spi_dev[1].devno, 1);
  305. unregister_chrdev_region(spi_dev[4].devno, 1);
  306. ERR_STEP:
  307. cdev_del(&spi_dev[1].cdev);
  308. cdev_del(&spi_dev[4].cdev);
  309. return ret;
  310. }
  311. static void __exit spi_exit(void)
  312. {
  313. unregister_chrdev_region(spi_dev[1].devno,1);
  314. cdev_del(&spi_dev[1].cdev);
  315. unregister_chrdev_region(spi_dev[4].devno,1);
  316. cdev_del(&spi_dev[4].cdev);
  317. }
  318. module_init(spi_init);
  319. module_exit(spi_exit);
  320. MODULE_LICENSE("GPL");
  321. MODULE_AUTHOR("jimbo");
  322. MODULE_DESCRIPTION("this is spi module");