drv_adc.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. /**************************************************************************//**
  2. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-12-12 Wayne First version
  9. *
  10. ******************************************************************************/
  11. #include <rtconfig.h>
  12. #if defined(BSP_USING_ADC)
  13. #include <rtdevice.h>
  14. #include "NuMicro.h"
  15. #include "drv_sys.h"
  16. #include "nu_bitutil.h"
  17. #include "drv_adc.h"
  18. /* Private define ---------------------------------------------------------------*/
  19. #define DEF_ADC_TOUCH_SMPL_TICK 20
  20. #define TOUCH_MQ_LENGTH 64
  21. /* Private Typedef --------------------------------------------------------------*/
  22. struct nu_adc
  23. {
  24. struct rt_adc_device dev;
  25. char *name;
  26. ADC_T *base;
  27. uint32_t bReset;
  28. IRQn_Type irqn;
  29. uint32_t rstidx;
  30. uint32_t modid;
  31. uint32_t chn_mask;
  32. rt_sem_t m_psSem;
  33. #if defined(BSP_USING_ADC_TOUCH)
  34. rt_touch_t psRtTouch;
  35. rt_timer_t psRtTouchMenuTimer;
  36. rt_mq_t m_pmqTouchXYZ;
  37. #endif
  38. nu_adc_cb m_isr[eAdc_ISR_CNT];
  39. nu_adc_cb m_wkisr[eAdc_WKISR_CNT];
  40. };
  41. typedef struct nu_adc *nu_adc_t;
  42. #if defined(BSP_USING_ADC_TOUCH)
  43. struct nu_adc_touch_data
  44. {
  45. uint32_t u32X;
  46. uint32_t u32Y;
  47. uint32_t u32Z0;
  48. uint32_t u32Z1;
  49. };
  50. typedef struct nu_adc_touch_data *nu_adc_touch_data_t;
  51. #endif
  52. /* Private functions ------------------------------------------------------------*/
  53. static rt_err_t nu_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled);
  54. static rt_err_t nu_adc_convert(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value);
  55. static rt_err_t _nu_adc_control(rt_device_t dev, int cmd, void *args);
  56. /* Public functions ------------------------------------------------------------*/
  57. int rt_hw_adc_init(void);
  58. /* Private variables ------------------------------------------------------------*/
  59. static struct nu_adc g_sNuADC =
  60. {
  61. .name = "adc",
  62. .base = ADC0,
  63. .bReset = 1,
  64. .irqn = ADC0_IRQn,
  65. .rstidx = ADC0_RST,
  66. .modid = ADC_MODULE,
  67. .chn_mask = 0
  68. };
  69. static void nu_adc_isr(int vector, void *param)
  70. {
  71. volatile rt_int32_t isr, wkisr;
  72. nu_adc_t psNuAdc = (nu_adc_t)param;
  73. rt_int32_t irqidx;
  74. ADC_T *adc = psNuAdc->base;
  75. //rt_kprintf("[%s %d] CTL: %08x CONF:%08x IER:%08x ISR:%08x\n", __func__, __LINE__, adc->CTL, adc->CONF, adc->IER, adc->ISR);
  76. isr = adc->ISR;
  77. wkisr = adc->WKISR;
  78. adc->ISR = isr;
  79. while ((irqidx = nu_ctz(isr)) < eAdc_ISR_CNT)
  80. {
  81. uint32_t u32IsrBitMask = 1 << irqidx ;
  82. if (psNuAdc->m_isr[irqidx].cbfunc != RT_NULL)
  83. {
  84. // rt_kprintf("[%s] %d %x\n", __func__, irqidx, psNuAdc->m_isr[irqidx].cbfunc);
  85. psNuAdc->m_isr[irqidx].cbfunc(isr, psNuAdc->m_isr[irqidx].private_data);
  86. }
  87. /* Clear sent bit */
  88. isr &= ~(u32IsrBitMask);
  89. } //while
  90. while ((irqidx = nu_ctz(wkisr)) < eAdc_WKISR_CNT)
  91. {
  92. uint32_t u32IsrBitMask = 1 << irqidx ;
  93. if (psNuAdc->m_wkisr[irqidx].cbfunc != RT_NULL)
  94. {
  95. psNuAdc->m_wkisr[irqidx].cbfunc(wkisr, psNuAdc->m_wkisr[irqidx].private_data);
  96. }
  97. wkisr &= ~(u32IsrBitMask);
  98. } //while
  99. }
  100. static rt_err_t _nu_adc_init(rt_device_t dev)
  101. {
  102. nu_adc_t psNuAdc = (nu_adc_t)dev;
  103. /* ADC Engine Clock is set to freq Khz */
  104. CLK_SetModuleClock(psNuAdc->modid, 0, CLK_CLKDIV4_ADC(180)); // Set ADC clock rate to 9MHz
  105. /* Install interrupt service routine */
  106. rt_hw_interrupt_install(psNuAdc->irqn, nu_adc_isr, (void *)psNuAdc, psNuAdc->name);
  107. return RT_EOK;
  108. }
  109. #define ADC_TOUCH_Z0_ACTIVE 20
  110. static int32_t AdcMenuStartCallback(uint32_t status, uint32_t userData)
  111. {
  112. nu_adc_t psNuAdc = (nu_adc_t)userData;
  113. #if defined(BSP_USING_ADC_TOUCH)
  114. ADC_T *adc = psNuAdc->base;
  115. static struct nu_adc_touch_data point;
  116. static rt_bool_t bDrop = RT_FALSE;
  117. static uint32_t u32LastZ0 = 0xffffu;
  118. if (psNuAdc->psRtTouch != RT_NULL)
  119. {
  120. point.u32X = ADC_GET_CONVERSION_XDATA(adc);
  121. point.u32Y = ADC_GET_CONVERSION_YDATA(adc);
  122. point.u32Z0 = ADC_GET_CONVERSION_Z1DATA(adc);
  123. point.u32Z1 = ADC_GET_CONVERSION_Z2DATA(adc);
  124. //rt_kprintf("x=%d y=%d z0=%d z1=%d\n", point.u32X, point.u32Y, point.u32Z0, point.u32Z1);
  125. /* Trigger next or not. */
  126. if (point.u32Z0 < ADC_TOUCH_Z0_ACTIVE)
  127. {
  128. /* Stop sampling procedure. */
  129. rt_timer_stop(g_sNuADC.psRtTouchMenuTimer);
  130. /* Re-start pendown detection */
  131. nu_adc_touch_detect(RT_TRUE);
  132. psNuAdc->bReset = 1;
  133. point.u32Z0 = point.u32Z1 = 0;
  134. bDrop = RT_TRUE;
  135. }
  136. else
  137. {
  138. bDrop = RT_FALSE;
  139. }
  140. /* Notify upper layer. */
  141. if ((!bDrop || (u32LastZ0 > ADC_TOUCH_Z0_ACTIVE)) && rt_mq_send(psNuAdc->m_pmqTouchXYZ, (const void *)&point, sizeof(struct nu_adc_touch_data)) == RT_EOK)
  142. {
  143. rt_hw_touch_isr(psNuAdc->psRtTouch);
  144. }
  145. u32LastZ0 = point.u32Z0;
  146. }
  147. else
  148. #endif
  149. {
  150. rt_err_t result = rt_sem_release(psNuAdc->m_psSem);
  151. RT_ASSERT(result == RT_EOK);
  152. }
  153. return 0;
  154. }
  155. #if defined(BSP_USING_ADC_TOUCH)
  156. static void nu_adc_touch_antiglitch(ADC_T *adc)
  157. {
  158. int count = 10;
  159. do
  160. {
  161. rt_hw_us_delay(1000); // 1ms
  162. ADC_CLR_INT_FLAG(adc, adc->ISR);
  163. if (adc->ISR == 0)
  164. break;
  165. }
  166. while (count-- > 0);
  167. }
  168. void nu_adc_touch_detect(rt_bool_t bStartDetect)
  169. {
  170. nu_adc_t psNuAdc = (nu_adc_t)&g_sNuADC;
  171. ADC_T *adc = psNuAdc->base;
  172. /* Disable interrupt */
  173. rt_hw_interrupt_mask(psNuAdc->irqn);
  174. ADC_POWER_DOWN(adc);
  175. /* Disable interrupt */
  176. ADC_DISABLE_INT(adc, ADC_IER_PEDEIEN_Msk | ADC_IER_MIEN_Msk);
  177. nu_adc_touch_antiglitch(adc);
  178. if (bStartDetect == RT_TRUE)
  179. {
  180. /* Switch to PenDown detection mode */
  181. ADC_DETECT_PD_MODE(adc);
  182. nu_adc_touch_antiglitch(adc);
  183. /* Enable interrupt */
  184. ADC_ENABLE_INT(adc, ADC_IER_PEDEIEN_Msk);
  185. }
  186. else
  187. {
  188. /* Switch to XY coordination converting mode */
  189. ADC_CONVERT_XY_MODE(adc);
  190. nu_adc_touch_antiglitch(adc);
  191. /* Enable interrupt */
  192. ADC_ENABLE_INT(adc, ADC_IER_MIEN_Msk);
  193. }
  194. ADC_POWER_ON(adc);
  195. /* Enable interrupt */
  196. rt_hw_interrupt_umask(psNuAdc->irqn);
  197. }
  198. static int32_t PenDownCallback(uint32_t status, uint32_t userData)
  199. {
  200. nu_adc_t psNuAdc = (nu_adc_t)userData;
  201. return rt_timer_start(psNuAdc->psRtTouchMenuTimer);
  202. }
  203. int32_t nu_adc_touch_read_xyz(uint32_t *bufX, uint32_t *bufY, uint32_t *bufZ0, uint32_t *bufZ1, int32_t dataCnt)
  204. {
  205. int i;
  206. struct nu_adc_touch_data value;
  207. for (i = 0 ; i < dataCnt; i++)
  208. {
  209. if (rt_mq_recv(g_sNuADC.m_pmqTouchXYZ, (void *)&value, sizeof(struct nu_adc_touch_data), 0) == -RT_ETIMEOUT)
  210. break;
  211. bufX[i] = value.u32X;
  212. bufY[i] = value.u32Y;
  213. bufZ0[i] = value.u32Z0;
  214. bufZ1[i] = value.u32Z1;
  215. }
  216. return i;
  217. }
  218. rt_err_t nu_adc_touch_enable(rt_touch_t psRtTouch)
  219. {
  220. nu_adc_t psNuAdc = (nu_adc_t)&g_sNuADC;
  221. nu_adc_cb sNuAdcCb;
  222. ADC_T *adc = psNuAdc->base;
  223. adc->CONF = 0x0;
  224. rt_adc_enable((rt_adc_device_t)psNuAdc, 4); //Channel number 4
  225. rt_adc_enable((rt_adc_device_t)psNuAdc, 5); //Channel number 5
  226. rt_adc_enable((rt_adc_device_t)psNuAdc, 6); //Channel number 6
  227. rt_adc_enable((rt_adc_device_t)psNuAdc, 7); //Channel number 7
  228. /* Register touch device. */
  229. psNuAdc->psRtTouch = psRtTouch;
  230. /* Register PenDown callback. */
  231. sNuAdcCb.cbfunc = PenDownCallback;
  232. sNuAdcCb.private_data = (rt_uint32_t)psNuAdc;
  233. rt_memcpy(&psNuAdc->m_isr[eAdc_PEDEF], &sNuAdcCb, sizeof(nu_adc_cb));
  234. nu_adc_touch_detect(RT_TRUE);
  235. return RT_EOK;
  236. }
  237. rt_err_t nu_adc_touch_disable(void)
  238. {
  239. nu_adc_t psNuAdc = (nu_adc_t)&g_sNuADC;
  240. nu_adc_touch_detect(RT_FALSE);
  241. _nu_adc_control((rt_device_t)psNuAdc, T_OFF, RT_NULL);
  242. _nu_adc_control((rt_device_t)psNuAdc, Z_OFF, RT_NULL);
  243. _nu_adc_control((rt_device_t)psNuAdc, PEDEF_OFF, RT_NULL);
  244. rt_adc_disable((rt_adc_device_t)psNuAdc, 4); //Channel number 4
  245. rt_adc_disable((rt_adc_device_t)psNuAdc, 5); //Channel number 5
  246. rt_adc_disable((rt_adc_device_t)psNuAdc, 6); //Channel number 6
  247. rt_adc_disable((rt_adc_device_t)psNuAdc, 7); //Channel number 7
  248. return RT_EOK;
  249. }
  250. static void nu_adc_touch_smpl(void *p)
  251. {
  252. nu_adc_t psNuAdc = (nu_adc_t)p;
  253. if (psNuAdc->bReset)
  254. {
  255. psNuAdc->bReset = 0;
  256. nu_adc_touch_detect(RT_FALSE);
  257. }
  258. /* Start conversion */
  259. ADC_START_CONV(psNuAdc->base);
  260. }
  261. #endif
  262. static rt_err_t _nu_adc_control(rt_device_t dev, int cmd, void *args)
  263. {
  264. rt_err_t ret = -RT_EINVAL ;
  265. nu_adc_t psNuAdc = (nu_adc_t)dev;
  266. ADC_T *adc = psNuAdc->base;
  267. nu_adc_cb_t psAdcCb = (nu_adc_cb_t)args;
  268. switch (cmd)
  269. {
  270. case START_MST: /* Menu Start Conversion */
  271. {
  272. /* Enable interrupt */
  273. ADC_ENABLE_INT(adc, ADC_IER_MIEN_Msk);
  274. /* Start conversion */
  275. ADC_START_CONV(adc);
  276. /* Wait it done */
  277. ret = rt_sem_take(psNuAdc->m_psSem, RT_WAITING_FOREVER);
  278. RT_ASSERT(ret == RT_EOK);
  279. /* Get data: valid data is 12-bit */
  280. if (args != RT_NULL)
  281. *((uint32_t *)args) = ADC_GET_CONVERSION_DATA(adc, 0);
  282. }
  283. break;
  284. case WKT_ON: /* Enable Touch Wake Up */
  285. {
  286. if (psAdcCb)
  287. {
  288. rt_memcpy(&psNuAdc->m_wkisr[eAdc_WPEDEF], psAdcCb, sizeof(nu_adc_cb));
  289. }
  290. adc->CTL |= ADC_CTL_WKTEN_Msk;
  291. adc->IER |= ADC_IER_WKTIEN_Msk;
  292. //TODO outpw(REG_SYS_WKUPSER, inpw(REG_SYS_WKUPSER) | (1 << 26));
  293. }
  294. break;
  295. case WKT_OFF: /* Disable Touch Wake Up */
  296. {
  297. adc->CTL &= ~ADC_CTL_WKTEN_Msk;
  298. adc->IER &= ~ADC_IER_WKTIEN_Msk;
  299. //TODO outpw(REG_SYS_WKUPSER, inpw(REG_SYS_WKUPSER) & ~(1 << 26));
  300. }
  301. break;
  302. case SWITCH_5WIRE_ON: /* Wire Mode Switch to 5-Wire */
  303. {
  304. adc->CTL |= ADC_CTL_WMSWCH_Msk;
  305. }
  306. break;
  307. case SWITCH_5WIRE_OFF: /* Wire Mode Switch to 4-Wire */
  308. {
  309. adc->CTL &= ~ADC_CTL_WMSWCH_Msk;
  310. }
  311. break;
  312. case T_ON: /* Enable Touch detection function */
  313. {
  314. adc->CONF |= ADC_CONF_TEN_Msk;
  315. }
  316. break;
  317. case T_OFF: /* Disable Touch detection function */
  318. {
  319. adc->CONF &= ~ADC_CONF_TEN_Msk;
  320. }
  321. break;
  322. case TAVG_ON: /* Enable Touch Mean average for X and Y function */
  323. {
  324. adc->CONF |= ADC_CONF_TMAVDIS_Msk;
  325. }
  326. break;
  327. case TAVG_OFF: /* Disable Touch Mean average for X and Y function */
  328. {
  329. adc->CONF &= ~ADC_CONF_TMAVDIS_Msk;
  330. }
  331. break;
  332. case Z_ON: /* Enable Press measure function */
  333. {
  334. adc->CONF |= ADC_CONF_ZEN_Msk;
  335. }
  336. break;
  337. case Z_OFF: /* Disable Press measure function */
  338. {
  339. adc->CONF &= ~ADC_CONF_ZEN_Msk;
  340. #if defined(BSP_USING_ADC_TOUCH)
  341. rt_mq_control(psNuAdc->m_pmqTouchXYZ, RT_IPC_CMD_RESET, RT_NULL);
  342. #endif
  343. }
  344. break;
  345. case TZAVG_ON: /* Enable Pressure Mean average for Z1 and Z2 function */
  346. {
  347. adc->CONF |= ADC_CONF_ZMAVDIS_Msk;
  348. }
  349. break;
  350. case TZAVG_OFF: /* Disable Pressure Mean average for Z1 and Z2 function */
  351. {
  352. adc->CONF &= ~ADC_CONF_ZMAVDIS_Msk;
  353. }
  354. break;
  355. case NAC_ON: /* Enable Normal AD Conversion */
  356. {
  357. adc->CONF |= (ADC_CONF_NACEN_Msk | ADC_CONF_REFSEL_AVDD33);
  358. }
  359. break;
  360. case NAC_OFF: /* Disable Normal AD Conversion */
  361. {
  362. adc->CONF &= ~ADC_CONF_NACEN_Msk;
  363. }
  364. break;
  365. case SWITCH_CH:
  366. {
  367. int chn = (int)args;
  368. if (chn >= ADC_CH_NUM)
  369. {
  370. return -ret;
  371. }
  372. adc->CONF &= ~ADC_CONF_CHSEL_Msk;
  373. adc->CONF |= (chn << ADC_CONF_CHSEL_Pos);
  374. }
  375. break;
  376. default:
  377. return -(ret);
  378. }
  379. return RT_EOK;
  380. }
  381. static rt_err_t _nu_adc_open(rt_device_t dev, rt_uint16_t oflag)
  382. {
  383. nu_adc_t psNuAdc = (nu_adc_t)dev;
  384. ADC_T *adc = psNuAdc->base;
  385. /* Enable ADC engine clock */
  386. CLK_EnableModuleClock(psNuAdc->modid);
  387. /* Reset the ADC IP */
  388. SYS_ResetModule(psNuAdc->modid);
  389. /* Enable ADC Power */
  390. ADC_POWER_ON(adc);
  391. /* Enable ADC to high speed mode */
  392. adc->CONF |= ADC_CONF_SPEED_Msk;
  393. /* Enable interrupt */
  394. rt_hw_interrupt_umask(psNuAdc->irqn);
  395. /* Enable Normal AD Conversion */
  396. _nu_adc_control(dev, NAC_ON, RT_NULL);
  397. return RT_EOK;
  398. }
  399. static rt_err_t _nu_adc_close(rt_device_t dev)
  400. {
  401. nu_adc_t psNuAdc = (nu_adc_t)dev;
  402. ADC_T *adc = psNuAdc->base;
  403. /* Disable Normal AD Conversion */
  404. _nu_adc_control(dev, NAC_OFF, RT_NULL);
  405. /* Disable interrupt */
  406. rt_hw_interrupt_mask(psNuAdc->irqn);
  407. /* Disable ADC Power */
  408. ADC_POWER_DOWN(adc);
  409. /* Disable ADC engine clock */
  410. CLK_DisableModuleClock(psNuAdc->modid);
  411. return RT_EOK;
  412. }
  413. static const struct rt_adc_ops nu_adc_ops =
  414. {
  415. nu_adc_enabled,
  416. nu_adc_convert,
  417. };
  418. /* nu_adc_enabled - Enable ADC clock and wait for ready */
  419. static rt_err_t nu_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
  420. {
  421. nu_adc_t psNuADC = (nu_adc_t)device;
  422. RT_ASSERT(device);
  423. if (channel >= ADC_CH_NUM)
  424. return -(RT_EINVAL);
  425. if (enabled)
  426. {
  427. psNuADC->chn_mask |= (1 << channel);
  428. }
  429. else
  430. {
  431. psNuADC->chn_mask &= ~(1 << channel);
  432. }
  433. if (psNuADC->chn_mask > 0 && ((rt_device_t)device)->ref_count == 0)
  434. {
  435. _nu_adc_open((rt_device_t)device, 0);
  436. ((rt_device_t)device)->ref_count = 1;
  437. }
  438. else if ((psNuADC->chn_mask == 0) && ((rt_device_t)device)->ref_count == 1)
  439. {
  440. _nu_adc_close((rt_device_t)device);
  441. ((rt_device_t)device)->ref_count = 0;
  442. }
  443. return RT_EOK;
  444. }
  445. static rt_err_t nu_adc_convert(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
  446. {
  447. rt_err_t ret = RT_EOK;
  448. RT_ASSERT(device);
  449. RT_ASSERT(value);
  450. if (channel >= ADC_CH_NUM)
  451. {
  452. ret = -RT_EINVAL;
  453. goto exit_nu_adc_convert;
  454. }
  455. else if ((ret = _nu_adc_control((rt_device_t)device, SWITCH_CH, (void *)channel)) != RT_EOK)
  456. {
  457. goto exit_nu_adc_convert;
  458. }
  459. else if ((ret = _nu_adc_control((rt_device_t)device, START_MST, (void *)value)) != RT_EOK)
  460. {
  461. goto exit_nu_adc_convert;
  462. }
  463. exit_nu_adc_convert:
  464. return (-ret) ;
  465. }
  466. int rt_hw_adc_init(void)
  467. {
  468. rt_err_t result = RT_ERROR;
  469. rt_device_t psDev = &g_sNuADC.dev.parent;
  470. result = rt_hw_adc_register(&g_sNuADC.dev, g_sNuADC.name, &nu_adc_ops, &g_sNuADC);
  471. RT_ASSERT(result == RT_EOK);
  472. result = _nu_adc_init(psDev);
  473. RT_ASSERT(result == RT_EOK);
  474. g_sNuADC.m_psSem = rt_sem_create("adc_mst_sem", 0, RT_IPC_FLAG_FIFO);
  475. RT_ASSERT(g_sNuADC.m_psSem);
  476. #if defined(BSP_USING_ADC_TOUCH)
  477. g_sNuADC.m_pmqTouchXYZ = rt_mq_create("ADC_TOUCH_XYZ", sizeof(struct nu_adc_touch_data), TOUCH_MQ_LENGTH, RT_IPC_FLAG_FIFO);
  478. RT_ASSERT(g_sNuADC.m_pmqTouchXYZ);
  479. g_sNuADC.psRtTouchMenuTimer = rt_timer_create("TOUCH_SMPL_TIMER", nu_adc_touch_smpl, (void *)&g_sNuADC, DEF_ADC_TOUCH_SMPL_TICK, RT_TIMER_FLAG_PERIODIC);
  480. RT_ASSERT(g_sNuADC.psRtTouchMenuTimer);
  481. #endif
  482. rt_memset(&g_sNuADC.m_isr, 0, sizeof(g_sNuADC.m_isr));
  483. rt_memset(&g_sNuADC.m_wkisr, 0, sizeof(g_sNuADC.m_wkisr));
  484. g_sNuADC.m_isr[eAdc_MF].cbfunc = AdcMenuStartCallback;
  485. g_sNuADC.m_isr[eAdc_MF].private_data = (uint32_t)&g_sNuADC;
  486. return (int)result;
  487. }
  488. INIT_BOARD_EXPORT(rt_hw_adc_init);
  489. #endif //#if defined(BSP_USING_ADC)