adc.c 8.4 KB

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