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