adc.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. #include "FreeRTOS.h"
  2. #include "board.h"
  3. #include "chip.h"
  4. #define ADC_CTR 0x00
  5. #define ADC_CFG 0x04
  6. #define ADC_IMR 0x08
  7. #define ADC_STA 0x0C
  8. #define ADC_AUX0 0x14
  9. #define ADC_AUX1 0x18
  10. #define ADC_AUX2 0x1C
  11. #define ADC_AUX3 0x20
  12. #define ADC_AUX4 0x38
  13. #define ADC_AUX5 0x3c
  14. #define ADC_AUX6 0x40
  15. #define ADC_AUX7 0x44
  16. #define ADC_DBNCNT 0x2C
  17. #define ADC_DETINTER 0x30
  18. #define ADC_SCTR 0x34
  19. #define ADC_CLK_FREQ 1000000
  20. #define ADC_DEBOUNCE_CNT 0x10000
  21. #define ADC_TRANS_INTERVAL_MS 1
  22. #define ADC_GPIO_DDR_ADDR (REGS_GPIO_BASE + 0x80 * 3 + 0x4)
  23. typedef struct adc_private_data {
  24. eAdcID id;
  25. uint32_t base;
  26. uint32_t irq;
  27. uint32_t clk_id;
  28. adc_int_cb ch_cb[ADC_CH_MAX];
  29. void *ch_cb_priv[ADC_CH_MAX];
  30. } adc_pdata_t;
  31. static adc_pdata_t g_adc[ADC_ID_MAX] = {
  32. [0] = {
  33. .id = 0,
  34. .base = REGS_ADC_BASE,
  35. .irq = ADC_IRQn,
  36. .clk_id = CLK_ADC,
  37. },
  38. [1] = {
  39. .id = 1,
  40. .base = REGS_ADC1_BASE,
  41. .irq = ADC1_IRQn,
  42. .clk_id = CLK_ADC1,
  43. },
  44. [2] = {
  45. .id = 2,
  46. .base = REGS_ADC2_BASE,
  47. .irq = ADC2_IRQn,
  48. .clk_id = CLK_ADC2,
  49. }
  50. };
  51. static uint32_t adc_get_int_bitoff(eAdcChannel ch)
  52. {
  53. uint32_t bitoff = 0;
  54. switch (ch) {
  55. case ADC_CH_AUX0:
  56. bitoff = 0;
  57. break;
  58. case ADC_CH_AUX1:
  59. bitoff = 3;
  60. break;
  61. case ADC_CH_AUX2:
  62. bitoff = 6;
  63. break;
  64. case ADC_CH_AUX3:
  65. bitoff = 9;
  66. break;
  67. case ADC_CH_AUX4:
  68. bitoff = 16;
  69. break;
  70. case ADC_CH_AUX5:
  71. bitoff = 19;
  72. break;
  73. case ADC_CH_AUX6:
  74. bitoff = 22;
  75. break;
  76. case ADC_CH_AUX7:
  77. bitoff = 25;
  78. break;
  79. }
  80. return bitoff;
  81. }
  82. static void adc_clear_int_status(adc_pdata_t *adc, eAdcChannel ch, uint32_t int_flg)
  83. {
  84. uint32_t val, bitoff;
  85. bitoff = adc_get_int_bitoff(ch);
  86. val = readl(adc->base + ADC_STA);
  87. val &= ~((int_flg & ADC_INT_MASK) << bitoff);
  88. writel(val, adc->base + ADC_STA);
  89. }
  90. static uint32_t adc_get_int_status(adc_pdata_t *adc, eAdcChannel ch)
  91. {
  92. uint32_t bitoff = 0;
  93. bitoff = adc_get_int_bitoff(ch);
  94. return (readl(adc->base + ADC_STA) >> bitoff) & ADC_INT_MASK;
  95. }
  96. static uint32_t adc_get_value(adc_pdata_t *adc, eAdcChannel ch)
  97. {
  98. uint32_t regoff;
  99. switch (ch) {
  100. case ADC_CH_AUX0:
  101. regoff = ADC_AUX0;
  102. break;
  103. case ADC_CH_AUX1:
  104. regoff = ADC_AUX1;
  105. break;
  106. case ADC_CH_AUX2:
  107. regoff = ADC_AUX2;
  108. break;
  109. case ADC_CH_AUX3:
  110. regoff = ADC_AUX3;
  111. break;
  112. case ADC_CH_AUX4:
  113. regoff = ADC_AUX4;
  114. break;
  115. case ADC_CH_AUX5:
  116. regoff = ADC_AUX5;
  117. break;
  118. case ADC_CH_AUX6:
  119. regoff = ADC_AUX6;
  120. break;
  121. case ADC_CH_AUX7:
  122. regoff = ADC_AUX7;
  123. break;
  124. }
  125. return readl(adc->base + regoff);
  126. }
  127. /*
  128. * clk unit = 1/pclk
  129. */
  130. static void adc_set_debounce_cnt(adc_pdata_t *adc, uint32_t debounce_cnt)
  131. {
  132. writel(debounce_cnt & 0xffffff, adc->base + ADC_DBNCNT);
  133. }
  134. /*
  135. * clk unit = 1/(adc_clk/2)
  136. */
  137. static void adc_set_transform_interval(adc_pdata_t *adc, uint32_t interval)
  138. {
  139. writel(interval & 0xffff, adc->base + ADC_DETINTER);
  140. }
  141. static void adc_reset(adc_pdata_t *adc)
  142. {
  143. uint32_t val;
  144. val = readl(adc->base + ADC_CTR);
  145. val |= (1 << 0);
  146. writel(val, adc->base + ADC_CTR);
  147. }
  148. static void adc_set_deinter(adc_pdata_t *adc, uint32_t count)
  149. {
  150. int mincnt, clkid;
  151. switch (adc->id) {
  152. case ADC0:
  153. clkid = CLK_ADC;
  154. break;
  155. case ADC1:
  156. clkid = CLK_ADC1;
  157. break;
  158. case ADC2:
  159. clkid = CLK_ADC2;
  160. break;
  161. default:
  162. return;
  163. }
  164. mincnt = ADC_DEBOUNCE_CNT * (ulClkGetRate(clkid) / 1000) / 2 / (ulClkGetRate(CLK_APB) / 1000);
  165. adc_set_transform_interval(adc, configMAX(mincnt, count));
  166. }
  167. static void adc_set_deinter_ms(adc_pdata_t *adc, uint32_t ms)
  168. {
  169. uint32_t count;
  170. count = (ms * ADC_CLK_FREQ)/1000;
  171. count /= 2;
  172. if(count < 0xffff)
  173. adc_set_deinter(adc, count);
  174. }
  175. static void adc_int_handler(void *para)
  176. {
  177. adc_pdata_t *adc = (adc_pdata_t *)para;
  178. adc_int_cb cb;
  179. uint32_t channel;
  180. uint32_t status;
  181. uint32_t imr;
  182. uint32_t int_en;
  183. imr = readl(adc->base + ADC_IMR);
  184. for (channel = ADC_CH_AUX0; channel < ADC_CH_MAX; channel++) {
  185. int_en = ~((imr >> adc_get_int_bitoff((eAdcChannel)channel)) & ADC_INT_MASK);
  186. status = adc_get_int_status(adc, (eAdcChannel)channel);
  187. if (status) {
  188. cb = adc->ch_cb[channel];
  189. if (cb && (status & int_en)) {
  190. cb((uint32_t)adc->id, status & int_en, adc_get_value(adc, (eAdcChannel)channel), adc->ch_cb_priv[channel]);
  191. }
  192. adc_clear_int_status(adc, (eAdcChannel)channel, status);
  193. }
  194. }
  195. }
  196. int adc_int_threshold_sel(eAdcID adc_id, int high)
  197. {
  198. uint32_t bitoff;
  199. bitoff = adc_id - ADC0 + 11;
  200. if (high)
  201. vSysctlConfigure(SYS_ANA_CFG, bitoff, 1, 1);
  202. else
  203. vSysctlConfigure(SYS_ANA_CFG, bitoff, 1, 0);
  204. return 0;
  205. }
  206. int adc_interrupt_enable(eAdcID id, eAdcChannel ch, uint32_t int_flg, int enable)
  207. {
  208. adc_pdata_t *adc;
  209. uint32_t bitoff;
  210. uint32_t val;
  211. if (id >= ADC_ID_MAX) {
  212. printf("%s, Invalid id:%d\n", __func__, id);
  213. return -1;
  214. }
  215. adc = &g_adc[id];
  216. bitoff = adc_get_int_bitoff(ch);
  217. val = readl(adc->base + ADC_IMR);
  218. if (enable)
  219. val &= ~((int_flg & ADC_INT_MASK) << bitoff);
  220. else
  221. val |= ((int_flg & ADC_INT_MASK) << bitoff);
  222. writel(val, adc->base + ADC_IMR);
  223. return 0;
  224. }
  225. int adc_force_conv_enable(eAdcID id, eAdcChannel ch, int enable)
  226. {
  227. adc_pdata_t *adc;
  228. uint32_t bitoff;
  229. uint32_t val;
  230. if (id >= ADC_ID_MAX) {
  231. printf("%s, Invalid id:%d\n", __func__, id);
  232. return -1;
  233. }
  234. adc = &g_adc[id];
  235. val = readl(adc->base + ADC_CTR);
  236. if (ch < ADC_CH_AUX4)
  237. bitoff = ch - ADC_CH_AUX0 + 13;
  238. else
  239. bitoff = ch - ADC_CH_AUX4 + 28;
  240. if (enable)
  241. val |= (1 << bitoff);
  242. else
  243. val &= ~(1 << bitoff);
  244. writel(val, adc->base + ADC_CTR);
  245. return 0;
  246. }
  247. /*
  248. * enable = 1,ADC值大于阈值时,触发中断。
  249. * enable = 0,ADC值小于阈值时,触发中断。
  250. */
  251. int adc_det_high_valid_enable(eAdcID id, eAdcChannel ch, int enable)
  252. {
  253. adc_pdata_t *adc;
  254. uint32_t bitoff;
  255. uint32_t val;
  256. if (id >= ADC_ID_MAX) {
  257. printf("%s, Invalid id:%d\n", __func__, id);
  258. return -1;
  259. }
  260. adc = &g_adc[id];
  261. val = readl(adc->base + ADC_CTR);
  262. if (ch < ADC_CH_AUX4)
  263. bitoff = ch - ADC_CH_AUX0 + 8;
  264. else
  265. bitoff = ch - ADC_CH_AUX4 + 24;
  266. if (enable)
  267. val |= (1 << bitoff);
  268. else
  269. val &= ~(1 << bitoff);
  270. writel(val, adc->base + ADC_CTR);
  271. return 0;
  272. }
  273. uint32_t adc_get_chn_val_force(eAdcID id, eAdcChannel ch)
  274. {
  275. int i;
  276. uint32_t adc_v;
  277. configASSERT(ch >= ADC_CH_AUX0 && ch <= ADC_CH_AUX7);
  278. for (i = ADC_CH_AUX0; i <= ADC_CH_AUX7; i++) {
  279. if (ch == i) {
  280. adc_enable(id, (eAdcChannel)i, 1);
  281. adc_force_conv_enable(id, (eAdcChannel)i, 1);
  282. adc_clear_int_status(&g_adc[id], (eAdcChannel)i, ADC_INT_MASK);
  283. } else {
  284. adc_enable(id, (eAdcChannel)i, 0);
  285. adc_force_conv_enable(id, (eAdcChannel)i, 0);
  286. }
  287. }
  288. while(!(adc_get_int_status(&g_adc[id], ch) & ADC_VALUE_INT)) {
  289. vTaskDelay(1);
  290. }
  291. return adc_get_value(&g_adc[id], ch);
  292. }
  293. int adc_register_int_cb(eAdcID id, eAdcChannel ch, adc_int_cb cb, void *user_param)
  294. {
  295. adc_pdata_t *adc;
  296. if (id >= ADC_ID_MAX) {
  297. printf("%s, Invalid id:%d\n", __func__, id);
  298. return -1;
  299. }
  300. adc = &g_adc[id];
  301. adc->ch_cb[ch] = cb;
  302. adc->ch_cb_priv[ch] = user_param;
  303. return 0;
  304. }
  305. int adc_enable(eAdcID id, eAdcChannel ch, int enable)
  306. {
  307. adc_pdata_t *adc;
  308. uint32_t bitoff;
  309. uint32_t val;
  310. if (id >= ADC_ID_MAX) {
  311. printf("%s, Invalid id:%d\n", __func__, id);
  312. return -1;
  313. }
  314. adc = &g_adc[id];
  315. val = readl(adc->base + ADC_CTR);
  316. if (ch < ADC_CH_AUX4)
  317. bitoff = ch - ADC_CH_AUX0 + 3;
  318. else
  319. bitoff = ch - ADC_CH_AUX4 + 20;
  320. if (enable) {
  321. val |= (1 << bitoff);
  322. } else {
  323. val &= ~(1 << bitoff);
  324. }
  325. writel(val, adc->base + ADC_CTR);
  326. return 0;
  327. }
  328. void adc_hardware_init(void)
  329. {
  330. /* ADC 管脚需要将其设置为gpio输入 */
  331. u32 val;
  332. #ifdef ADC0_SUPPORT
  333. adc_int_threshold_sel(ADC0, ADC0_THR_SEL);
  334. val = readl(ADC_GPIO_DDR_ADDR);
  335. val &= ~(0xff << 15);
  336. if (GetChipHWVeriosn() != CHIP_HVER_0)
  337. val |= (0x85 << 15);
  338. else
  339. val |= (0xff << 15);
  340. writel(val, ADC_GPIO_DDR_ADDR);
  341. #endif /*_ADC0 */
  342. #ifdef ADC1_SUPPORT
  343. adc_int_threshold_sel(ADC1, ADC1_THR_SEL);
  344. val = readl(ADC_GPIO_DDR_ADDR);
  345. val &= ~(0xff << 23);
  346. if (GetChipHWVeriosn() != CHIP_HVER_0)
  347. val |= (0xa4 << 23);
  348. else
  349. val |= (0xff << 23);
  350. writel(val, ADC_GPIO_DDR_ADDR);
  351. #endif /*_ADC1 */
  352. #ifdef ADC2_SUPPORT
  353. adc_int_threshold_sel(ADC2, ADC2_THR_SEL);
  354. // 注:ADC2的AUX0~7的gpio功能由mcu控制,请在mcu上将对应gpio设置为输入。
  355. #endif /*_ADC2 */
  356. }
  357. int adc_init(void)
  358. {
  359. adc_pdata_t *adc;
  360. eAdcChannel channel;
  361. int id;
  362. adc_hardware_init();
  363. for (id = 0; id < ADC_ID_MAX; id++) {
  364. #ifndef ADC0_SUPPORT
  365. if (id == ADC0)
  366. continue;
  367. #endif
  368. #ifndef ADC1_SUPPORT
  369. if (id == ADC1)
  370. continue;
  371. #endif
  372. #ifndef ADC2_SUPPORT
  373. if (id == ADC2)
  374. continue;
  375. #endif
  376. adc = &g_adc[id];
  377. vClkSetRate(adc->clk_id, ADC_CLK_FREQ);
  378. adc_reset(adc);
  379. for (channel = 0; channel < ADC_CH_MAX; channel++) {
  380. adc->ch_cb[channel] = NULL;
  381. adc->ch_cb_priv[channel] = NULL;
  382. /* disable all adc channel */
  383. adc_enable(id, channel, 0);
  384. /* disable and clear irq */
  385. adc_interrupt_enable(id, channel, ADC_INT_MASK, 0);
  386. adc_clear_int_status(adc, channel, ADC_INT_MASK);
  387. }
  388. /* set debounce count */
  389. adc_set_debounce_cnt(adc, ADC_DEBOUNCE_CNT);
  390. adc_set_deinter_ms(adc, ADC_TRANS_INTERVAL_MS);
  391. request_irq(adc->irq, 0, adc_int_handler, (void *)adc);
  392. }
  393. return 0;
  394. }