adc_main.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. /* include path: install_root/linux/include */
  2. #include <linux/module.h>
  3. #include <linux/kernel.h>
  4. #include <linux/init.h>
  5. #include <linux/cdev.h>
  6. #include <linux/fs.h>
  7. #include <linux/errno.h>
  8. #include <linux/device.h>
  9. #include <linux/err.h>
  10. #include <asm/uaccess.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/irqreturn.h>
  13. #include <linux/wait.h>
  14. #include "stm32f4xx.h"
  15. #include "stm32f4xx_hal_rcc.h"
  16. #include "stm32f4xx_hal_gpio.h"
  17. #include "stm32f4xx_hal_adc.h"
  18. #include "stm32f4xx_hal_dma.h"
  19. #include "driver.h"
  20. #include "stm32_hal_legacy.h"
  21. static int major = MAJOR_ADC;
  22. static int minor = 0;
  23. //static dev_t devno;
  24. //static struct cdev *adc_cdev = NULL;
  25. //static int count = 3;
  26. #define NUM_OF_DEVICES 3
  27. //ruct class *my_class = NULL;
  28. //struct device *dev = NULL;
  29. #define DEVNAME "adc"
  30. struct adc_device {
  31. dev_t devno;
  32. struct cdev cdev;
  33. char data[128];
  34. char name[16];
  35. IRQn_Type DMA_IRQn;
  36. } adc_dev[NUM_OF_DEVICES];
  37. uint32_t gAdc1Value[10][4];
  38. static int adc_open(struct inode *inode, struct file *filep);
  39. static int adc_close(struct inode *inode, struct file *filep);
  40. static ssize_t adc_read(struct file *filep, char __user *buf, size_t size, loff_t *offset);
  41. static ssize_t adc_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset);
  42. static int adc_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
  43. static struct file_operations adc_ops =
  44. {
  45. .owner = THIS_MODULE,
  46. .open = adc_open,
  47. .release = adc_close,
  48. .read = adc_read,
  49. .write = adc_write,
  50. .ioctl = adc_ioctl,
  51. };
  52. static int adc_open(struct inode *inode, struct file *filep)
  53. {
  54. int imajor,iminor;
  55. // ADC_HandleTypeDef hadc;
  56. imajor = MAJOR(inode->i_rdev);
  57. iminor = MINOR(inode->i_rdev);
  58. printk("adc open, major %d, minor %d\n", imajor, iminor);
  59. // if(imajor != MAJOR_ADC)
  60. // {
  61. // printk("Error: %s %d adc major fail! %d\n",__FILE__,__LINE__,imajor);
  62. // return -1;
  63. // }
  64. // switch(iminor)
  65. // {
  66. // case 0:
  67. // hadc.Instance = ADC1;
  68. // __HAL_RCC_ADC1_CLK_ENABLE();
  69. // break;
  70. // case 1:
  71. // hadc.Instance = ADC2;
  72. // __HAL_RCC_ADC2_CLK_ENABLE();
  73. // break;
  74. // case 2:
  75. // hadc.Instance = ADC3;
  76. // __HAL_RCC_ADC3_CLK_ENABLE();
  77. // break;
  78. // }
  79. // __HAL_ADC_ENABLE(&hadc);
  80. return 0;
  81. }
  82. static int adc_close(struct inode *inode, struct file *filep)
  83. {
  84. int imajor,iminor;
  85. ADC_HandleTypeDef handle_adc;
  86. imajor = MAJOR(inode->i_rdev);
  87. iminor = MINOR(inode->i_rdev);
  88. if(imajor != MAJOR_ADC)
  89. {
  90. printk("Error: %s %d adc major fail! %d\n",__FILE__,__LINE__,imajor);
  91. return -1;
  92. }
  93. switch(iminor)
  94. {
  95. case 0:
  96. handle_adc.Instance = ADC1;
  97. __HAL_RCC_ADC1_CLK_DISABLE();
  98. break;
  99. case 1:
  100. handle_adc.Instance = ADC2;
  101. __HAL_RCC_ADC1_CLK_DISABLE();
  102. break;
  103. case 2:
  104. handle_adc.Instance = ADC3;
  105. __HAL_RCC_ADC1_CLK_DISABLE();
  106. break;
  107. }
  108. printk("adc close, major %d, minor %d\n", imajor, iminor);
  109. __HAL_ADC_DISABLE(&handle_adc);
  110. return 0;
  111. }
  112. static ssize_t adc_read(struct file *filep, char __user *buf, size_t size, loff_t *offset)
  113. {
  114. //printk("fmc_read!\n");
  115. return 0;
  116. }
  117. static ssize_t adc_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset)
  118. {
  119. /* uint32_t i;
  120. uint8_t tmp_buf[100];
  121. printk("fmc_write");
  122. for(i=0;i<size;i++)
  123. tmp_buf[i] = *(uint8_t*)(offset+i);
  124. copy_to_user();*/
  125. return 0;
  126. }
  127. static int adc_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg)
  128. {
  129. int i;
  130. // if ( copy_from_user(&fmc_arg, (void*)arg, sizeof(fmc_cpld_t)) )
  131. // return -EFAULT;
  132. switch(cmd)
  133. {
  134. case ADC_GET_RESULT:
  135. for(i=0;i<10;i++)
  136. printk("%d : %#x, %#x, %#x, %#x\n", i, gAdc1Value[i][0], gAdc1Value[i][1], gAdc1Value[i][2], gAdc1Value[i][3]);
  137. break;
  138. default:
  139. printk("Invalid command!\n");
  140. break;
  141. }
  142. return 0;
  143. }
  144. ADC_HandleTypeDef hadc;
  145. DMA_HandleTypeDef hdma_adc;
  146. /**
  147. * @brief Handles DMA interrupt request.
  148. * @param hdma pointer to a DMA_HandleTypeDef structure that contains
  149. * the configuration information for the specified DMA Stream.
  150. * @retval None
  151. */
  152. irqreturn_t HAL_DMA_IRQHandler(int irqno, void *dev_id )
  153. {
  154. uint32_t tmpisr;
  155. __IO uint32_t count = 0U;
  156. uint32_t timeout = 18750; //SystemCoreClock / 9600U;
  157. DMA_HandleTypeDef *hdma = &hdma_adc;
  158. /* calculate DMA base and stream number */
  159. DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
  160. tmpisr = regs->ISR;
  161. /* Transfer Error Interrupt management ***************************************/
  162. if ((tmpisr & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex)) != RESET)
  163. {
  164. if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
  165. {
  166. /* Disable the transfer error interrupt */
  167. hdma->Instance->CR &= ~(DMA_IT_TE);
  168. /* Clear the transfer error flag */
  169. regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex;
  170. /* Update error code */
  171. hdma->ErrorCode |= HAL_DMA_ERROR_TE;
  172. }
  173. }
  174. /* FIFO Error Interrupt management ******************************************/
  175. if ((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET)
  176. {
  177. if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
  178. {
  179. /* Clear the FIFO error flag */
  180. regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;
  181. /* Update error code */
  182. hdma->ErrorCode |= HAL_DMA_ERROR_FE;
  183. }
  184. }
  185. /* Direct Mode Error Interrupt management ***********************************/
  186. if ((tmpisr & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex)) != RESET)
  187. {
  188. if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)
  189. {
  190. /* Clear the direct mode error flag */
  191. regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex;
  192. /* Update error code */
  193. hdma->ErrorCode |= HAL_DMA_ERROR_DME;
  194. }
  195. }
  196. /* Half Transfer Complete Interrupt management ******************************/
  197. if ((tmpisr & (DMA_FLAG_HTIF0_4 << hdma->StreamIndex)) != RESET)
  198. {
  199. if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
  200. {
  201. /* Clear the half transfer complete flag */
  202. regs->IFCR = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
  203. /* Multi_Buffering mode enabled */
  204. if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != RESET)
  205. {
  206. /* Current memory buffer used is Memory 0 */
  207. if((hdma->Instance->CR & DMA_SxCR_CT) == RESET)
  208. {
  209. if(hdma->XferHalfCpltCallback != NULL)
  210. {
  211. /* Half transfer callback */
  212. hdma->XferHalfCpltCallback(hdma);
  213. }
  214. }
  215. /* Current memory buffer used is Memory 1 */
  216. else
  217. {
  218. if(hdma->XferM1HalfCpltCallback != NULL)
  219. {
  220. /* Half transfer callback */
  221. hdma->XferM1HalfCpltCallback(hdma);
  222. }
  223. }
  224. }
  225. else
  226. {
  227. /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
  228. if((hdma->Instance->CR & DMA_SxCR_CIRC) == RESET)
  229. {
  230. /* Disable the half transfer interrupt */
  231. hdma->Instance->CR &= ~(DMA_IT_HT);
  232. }
  233. if(hdma->XferHalfCpltCallback != NULL)
  234. {
  235. /* Half transfer callback */
  236. hdma->XferHalfCpltCallback(hdma);
  237. }
  238. }
  239. }
  240. }
  241. /* Transfer Complete Interrupt management ***********************************/
  242. if ((tmpisr & (DMA_FLAG_TCIF0_4 << hdma->StreamIndex)) != RESET)
  243. {
  244. if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
  245. {
  246. /* Clear the transfer complete flag */
  247. regs->IFCR = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;
  248. if(HAL_DMA_STATE_ABORT == hdma->State)
  249. {
  250. /* Disable all the transfer interrupts */
  251. hdma->Instance->CR &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME);
  252. hdma->Instance->FCR &= ~(DMA_IT_FE);
  253. if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
  254. {
  255. hdma->Instance->CR &= ~(DMA_IT_HT);
  256. }
  257. /* Clear all interrupt flags at correct offset within the register */
  258. regs->IFCR = 0x3FU << hdma->StreamIndex;
  259. /* Process Unlocked */
  260. __HAL_UNLOCK(hdma);
  261. /* Change the DMA state */
  262. hdma->State = HAL_DMA_STATE_READY;
  263. if(hdma->XferAbortCallback != NULL)
  264. {
  265. hdma->XferAbortCallback(hdma);
  266. }
  267. return IRQ_HANDLED;
  268. }
  269. if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != RESET)
  270. {
  271. /* Current memory buffer used is Memory 0 */
  272. if((hdma->Instance->CR & DMA_SxCR_CT) == RESET)
  273. {
  274. if(hdma->XferM1CpltCallback != NULL)
  275. {
  276. /* Transfer complete Callback for memory1 */
  277. hdma->XferM1CpltCallback(hdma);
  278. }
  279. }
  280. /* Current memory buffer used is Memory 1 */
  281. else
  282. {
  283. if(hdma->XferCpltCallback != NULL)
  284. {
  285. /* Transfer complete Callback for memory0 */
  286. hdma->XferCpltCallback(hdma);
  287. }
  288. }
  289. }
  290. /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
  291. else
  292. {
  293. if((hdma->Instance->CR & DMA_SxCR_CIRC) == RESET)
  294. {
  295. /* Disable the transfer complete interrupt */
  296. hdma->Instance->CR &= ~(DMA_IT_TC);
  297. /* Process Unlocked */
  298. __HAL_UNLOCK(hdma);
  299. /* Change the DMA state */
  300. hdma->State = HAL_DMA_STATE_READY;
  301. }
  302. if(hdma->XferCpltCallback != NULL)
  303. {
  304. /* Transfer complete callback */
  305. hdma->XferCpltCallback(hdma);
  306. }
  307. }
  308. }
  309. }
  310. /* manage error case */
  311. if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
  312. {
  313. if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != RESET)
  314. {
  315. hdma->State = HAL_DMA_STATE_ABORT;
  316. /* Disable the stream */
  317. __HAL_DMA_DISABLE(hdma);
  318. do
  319. {
  320. if (++count > timeout)
  321. {
  322. break;
  323. }
  324. }
  325. while((hdma->Instance->CR & DMA_SxCR_EN) != RESET);
  326. /* Process Unlocked */
  327. __HAL_UNLOCK(hdma);
  328. /* Change the DMA state */
  329. hdma->State = HAL_DMA_STATE_READY;
  330. }
  331. if(hdma->XferErrorCallback != NULL)
  332. {
  333. /* Transfer error callback */
  334. hdma->XferErrorCallback(hdma);
  335. }
  336. }
  337. return IRQ_HANDLED;
  338. }
  339. int adc_hw_init(void)
  340. {
  341. ADC_ChannelConfTypeDef sConfig;
  342. GPIO_InitTypeDef GPIO_InitStruct;
  343. /* ADC1
  344. * PA3 - ADC1_IN3
  345. * PA4 - ADC1_IN4
  346. * PA5 - ADC1_IN5
  347. * PA6 - ADC1_IN6
  348. */
  349. __HAL_RCC_GPIOA_CLK_ENABLE();
  350. GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6;
  351. GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  352. GPIO_InitStruct.Pull = GPIO_NOPULL;
  353. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  354. hadc.Instance = ADC1;
  355. hadc.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
  356. hadc.Init.Resolution = ADC_RESOLUTION_12B;
  357. hadc.Init.ScanConvMode = ENABLE;
  358. hadc.Init.ContinuousConvMode = ENABLE;
  359. hadc.Init.DiscontinuousConvMode = DISABLE;
  360. hadc.Init.NbrOfDiscConversion = 0;
  361. //hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  362. hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  363. hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  364. hadc.Init.NbrOfConversion = 4;
  365. hadc.Init.DMAContinuousRequests = ENABLE;
  366. hadc.Init.EOCSelection = DISABLE;
  367. if(HAL_ADC_Init(&hadc) != HAL_OK)
  368. {
  369. printk(KERN_ERR"adc hw init error!\n");
  370. }
  371. sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
  372. sConfig.Offset = 0;
  373. sConfig.Rank = 1;
  374. sConfig.Channel = ADC_CHANNEL_3;
  375. if(HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  376. {
  377. printk(KERN_ERR"adc channel3 init error!\n");
  378. }
  379. sConfig.Rank = 2;
  380. sConfig.Channel = ADC_CHANNEL_4;
  381. if(HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  382. {
  383. printk(KERN_ERR"adc channel4 init error!\n");
  384. }
  385. sConfig.Rank = 3;
  386. sConfig.Channel = ADC_CHANNEL_5;
  387. if(HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  388. {
  389. printk(KERN_ERR"adc channel5 init error!\n");
  390. }
  391. sConfig.Rank = 4;
  392. sConfig.Channel = ADC_CHANNEL_6;
  393. if(HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  394. {
  395. printk(KERN_ERR"adc channel6 init error!\n");
  396. }
  397. __HAL_RCC_ADC1_CLK_ENABLE();
  398. __HAL_ADC_ENABLE(&hadc);
  399. // config dma
  400. hdma_adc.Instance = DMA2_Stream0;
  401. hdma_adc.Init.Channel = DMA_CHANNEL_0;
  402. hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
  403. hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
  404. hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
  405. hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  406. hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  407. hdma_adc.Init.Mode = DMA_CIRCULAR;
  408. hdma_adc.Init.Priority = DMA_PRIORITY_HIGH;
  409. hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  410. hdma_adc.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
  411. hdma_adc.Init.MemBurst = DMA_MBURST_SINGLE;
  412. hdma_adc.Init.PeriphBurst = DMA_PBURST_SINGLE;
  413. HAL_DMA_Init(&hdma_adc);
  414. /* Associate the initialized DMA handle to the the ADC handle */
  415. __HAL_LINKDMA(&hadc, DMA_Handle, hdma_adc);
  416. /*##-4- Configure the NVIC for DMA #########################################*/
  417. /* NVIC configuration for DMA transfer complete interrupt */
  418. HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 3, 0);
  419. HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
  420. return 0;
  421. }
  422. static int __init adc_init(void)
  423. {
  424. int ret;
  425. int i;
  426. printk("adc driver init!\n");
  427. for (i = 0; i < NUM_OF_DEVICES; i++)
  428. {
  429. adc_dev[i].devno = MKDEV(MAJOR_ADC, i);
  430. sprintf(adc_dev[i].name, "%s%d", DEVNAME, i+1);
  431. register_chrdev_region(adc_dev[i].devno, 1, adc_dev[i].name);
  432. cdev_add(&adc_dev[i].cdev, adc_dev[i].devno, 1);
  433. cdev_init(&adc_dev[i].cdev, &adc_ops);
  434. }
  435. if(adc_hw_init() != 0)
  436. goto ERR_STEP1;
  437. adc_dev[0].DMA_IRQn = DMA2_Stream0_IRQn;
  438. adc_dev[1].DMA_IRQn = DMA2_Stream2_IRQn;
  439. adc_dev[2].DMA_IRQn = DMA2_Stream1_IRQn;
  440. // register adc1 interrupt
  441. ret = request_irq(adc_dev[0].DMA_IRQn, HAL_DMA_IRQHandler, IRQF_SHARED, adc_dev[0].name, &adc_dev[0].devno);
  442. if(ret) {
  443. printk("request_irq() fialed! %d\n", ret);
  444. goto ERR_STEP1;
  445. }
  446. if(HAL_ADC_Start_DMA(&hadc, (uint32_t*)&gAdc1Value, 40) != HAL_OK)
  447. {
  448. printk("Start DMA error!");
  449. }
  450. return 0;
  451. ERR_STEP1:
  452. unregister_chrdev_region(adc_dev[0].devno, NUM_OF_DEVICES);
  453. //ERR_STEP:
  454. cdev_del(&adc_dev[0].cdev);
  455. return 0;
  456. }
  457. static void __exit adc_exit(void)
  458. {
  459. unregister_chrdev_region(MKDEV(major, minor), NUM_OF_DEVICES);
  460. cdev_del(&adc_dev[0].cdev);
  461. }
  462. module_init(adc_init);
  463. module_exit(adc_exit);
  464. MODULE_LICENSE("GPL");
  465. MODULE_AUTHOR("jimbo_zhang");
  466. MODULE_DESCRIPTION("adc driver");