bsp_adc.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*********************************************************************
  2. * INCLUDES
  3. */
  4. #include "bsp_adc.h"
  5. #include "system.h"
  6. #include "exception.h"
  7. /*********************************************************************
  8. * DEFINITIONS
  9. */
  10. #define CHANNEL_MAX 8
  11. #define PIN_NOT_USED 0xFF
  12. #define CHANNEL_NOT_USED 0xFF
  13. #define WAIT_TIME_VALUE 10000 // 等待超时最大值
  14. /*********************************************************************
  15. * STRUCTION
  16. */
  17. typedef struct {
  18. uint32_t pin;
  19. uint32_t channel;
  20. }adc_config_t;
  21. typedef enum{
  22. ChargeADC_IDIE=0,
  23. ChargeADC_SET,
  24. ChargeADC_IRQ,
  25. }_ChargeADC_STATE;
  26. /*********************************************************************
  27. * LOCAL VARIABLES
  28. */
  29. static adc_config_t m_adc_config[CHANNEL_MAX] = {{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED}};
  30. static nrf_saadc_channel_config_t channelConfig[CHANNEL_MAX];
  31. static nrf_saadc_value_t s_bufferPool[CHANNEL_MAX] = {0};
  32. static volatile bool adc_SampleOk = true; // adc采集完成标志
  33. static volatile _ChargeADC_STATE Chargeadc_state = ChargeADC_IDIE; // 充电引脚adc采集完成标志
  34. //定义SAADC采样数据缓存
  35. //定义SAADC采样缓存数组大小
  36. //只有采样结果存满该缓存之后,才会产生SAADC采样完成事件
  37. static uint32_t sample_in_buffer = 0;
  38. static bsp_adc_read_cb m_cb = NULL;
  39. static uint32_t m_cb_channel = CHANNEL_NOT_USED;
  40. static uint32_t m_cb_count = 0;
  41. /*********************************************************************
  42. * LOCAL FUNCTIONS
  43. */
  44. uint8_t bsp_Get_ChargePinADC(int16_t *adc){
  45. uint8_t i =0;
  46. uint8_t adc_sort[CHANNEL_MAX] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
  47. uint8_t sort_index = 0;
  48. if(ChargeADC_IRQ != Chargeadc_state )return 0;
  49. else{
  50. for(i=0;i<CHANNEL_MAX;i++)
  51. {
  52. if(channelConfig[i].pin_p != NRF_SAADC_INPUT_DISABLED){
  53. adc_sort[sort_index] = i;
  54. sort_index++;
  55. }
  56. }
  57. //获取数据
  58. for(i=0;i<sample_in_buffer;i++)
  59. {
  60. if(adc_sort[i] == PIN_CHARGING_CHANNEL)
  61. {
  62. *adc = s_bufferPool[i];
  63. }
  64. }
  65. DEBUG_LOG(" >> ChargeADC_IDIE\r\n");
  66. Chargeadc_state = ChargeADC_IDIE;
  67. return 1;
  68. }
  69. }
  70. /**
  71. @brief ADC中断处理回调函数
  72. @param 无
  73. @return 无
  74. */
  75. static void adcCallbackFunc(nrf_drv_saadc_evt_t const *pEvent)
  76. {
  77. int i;
  78. ret_code_t err_code;
  79. uint8_t adc_sort[CHANNEL_MAX] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
  80. uint8_t sort_index = 0;
  81. if(pEvent->type == NRF_DRV_SAADC_EVT_DONE) // 采样完成,采集时填充顺序为,通道编号小的先填充。
  82. {
  83. //设置好缓存,为下一次采样做准备
  84. err_code=nrf_drv_saadc_buffer_convert(pEvent->data.done.p_buffer,sample_in_buffer);
  85. if(err_code == NRF_SUCCESS)
  86. {
  87. adc_SampleOk = true;
  88. if(ChargeADC_SET == Chargeadc_state){
  89. Chargeadc_state= ChargeADC_IRQ;
  90. DEBUG_LOG(" >> ChargeADC_IRQ\r\n");
  91. }
  92. //读取回调
  93. if(m_cb != NULL && m_cb_count != 0)
  94. {
  95. //预先排序,采集时填充顺序为,通道编号小的先填充。
  96. for(i=0;i<CHANNEL_MAX;i++)
  97. {
  98. if(channelConfig[i].pin_p != NRF_SAADC_INPUT_DISABLED){
  99. adc_sort[sort_index] = i;
  100. sort_index++;
  101. }
  102. }
  103. //获取数据
  104. for(i=0;i<sample_in_buffer;i++)
  105. {
  106. if(adc_sort[i] == m_cb_channel)
  107. {
  108. m_cb(s_bufferPool[i]);
  109. }
  110. }
  111. m_cb_count--;
  112. }
  113. }
  114. }
  115. }
  116. static void bsp_adc_init_process(void)
  117. {
  118. if(Except_TxError(EXCEPT_ADC_INIT,"bsp_adc_init_error\r\n") == 0)
  119. {
  120. Process_Stop(bsp_adc_init_process);
  121. }
  122. }
  123. /**
  124. @brief 初始化ADC
  125. @param 无
  126. @return 无
  127. */
  128. static void ADC_Init(void)
  129. {
  130. int ret = 0;
  131. ret_code_t errCode;
  132. nrf_drv_saadc_config_t p_config = NRFX_SAADC_DEFAULT_CONFIG;
  133. p_config.interrupt_priority = ADC_IRQ_PRIORITY;
  134. // ADC初始化
  135. errCode = nrf_drv_saadc_init(&p_config, adcCallbackFunc);//优先级设置为3,比定时器中断要高,不然回调会在定时器中断结束后触发。
  136. if(errCode != NRF_SUCCESS)ret = -1;
  137. // ADC通道配置
  138. for(int i=0;i<CHANNEL_MAX;i++)
  139. {
  140. if(m_adc_config[i].pin != PIN_NOT_USED && m_adc_config[i].channel != CHANNEL_NOT_USED)
  141. {
  142. // ADC通道初始化
  143. errCode = nrf_drv_saadc_channel_init(m_adc_config[i].channel, &channelConfig[m_adc_config[i].channel]);
  144. if(errCode != NRF_SUCCESS)ret = -1;
  145. }
  146. }
  147. //若是中断读取,则要配置,否则不用。
  148. if(sample_in_buffer > 0)
  149. {
  150. // 缓冲配置
  151. errCode = nrf_drv_saadc_buffer_convert(s_bufferPool, sample_in_buffer);
  152. if(errCode != NRF_SUCCESS)ret = -1;
  153. }
  154. if(ret == -1)
  155. {
  156. Process_Start(0,"bsp_adc_init",bsp_adc_init_process);
  157. }
  158. }
  159. static void cb_adcWakeup(uint32_t t)
  160. {
  161. ADC_Enable();
  162. }
  163. static void cb_adcSleep(uint32_t t)
  164. {
  165. ADC_Disable();
  166. }
  167. /*********************************************************************
  168. * PUBLIC FUNCTIONS
  169. */
  170. /**
  171. @brief 初始化ADC引脚和通道
  172. @param pin -[in] 需要初始化的adc引脚
  173. @param channel -[in] 需要初始化的adc通道
  174. @return 错误代码
  175. */
  176. uint32_t ADC_SetPinChannel(uint32_t pin, uint32_t channel,nrf_gpio_pin_pull_t pin_pull)
  177. {
  178. ret_code_t errCode;
  179. //清除已存在的引脚和通道
  180. ADC_RemovePinChannel(pin, channel);
  181. for(int i=0;i<CHANNEL_MAX;i++)
  182. {
  183. if(m_adc_config[i].pin == PIN_NOT_USED && m_adc_config[i].channel == CHANNEL_NOT_USED && PIN_NOT_USED != pin)
  184. {
  185. m_adc_config[i].pin = pin;
  186. m_adc_config[i].channel = channel;
  187. //设置ADC引脚为浮空
  188. nrf_gpio_cfg_input(m_adc_config[i].pin,pin_pull);
  189. // 单端输入
  190. channelConfig[m_adc_config[i].channel].resistor_p = NRF_SAADC_RESISTOR_DISABLED;
  191. channelConfig[m_adc_config[i].channel].resistor_n = NRF_SAADC_RESISTOR_DISABLED;
  192. channelConfig[m_adc_config[i].channel].gain = NRF_SAADC_GAIN1_6;
  193. channelConfig[m_adc_config[i].channel].reference = NRF_SAADC_REFERENCE_INTERNAL;
  194. channelConfig[m_adc_config[i].channel].acq_time = NRF_SAADC_ACQTIME_10US;
  195. channelConfig[m_adc_config[i].channel].mode = NRF_SAADC_MODE_SINGLE_ENDED;
  196. channelConfig[m_adc_config[i].channel].burst = NRF_SAADC_BURST_DISABLED;
  197. channelConfig[m_adc_config[i].channel].pin_p = (nrf_saadc_input_t)(m_adc_config[i].channel + 1);
  198. channelConfig[m_adc_config[i].channel].pin_n = NRF_SAADC_INPUT_DISABLED;
  199. // ADC通道初始化
  200. errCode = nrf_drv_saadc_channel_init(m_adc_config[i].channel, &channelConfig[m_adc_config[i].channel]);
  201. if(errCode != NRF_SUCCESS)return ADC_ERR_INIT_CONGESTION;
  202. sample_in_buffer++;
  203. DEBUG_LOG("add channel ( %d ):\n", channel);
  204. return ADC_OP_SUCCESS;
  205. }
  206. }
  207. return ADC_ERR_INIT_CONGESTION;
  208. }
  209. /**
  210. @brief 移除已初始化ADC引脚和通道
  211. @param pin -[in] 需要移除的adc引脚
  212. @param channel -[in] 需要移除的adc通道
  213. @return 错误代码
  214. */
  215. uint32_t ADC_RemovePinChannel(uint32_t pin, uint32_t channel)
  216. {
  217. for(int i=0;i<CHANNEL_MAX;i++)
  218. {
  219. if(m_adc_config[i].pin == pin && m_adc_config[i].channel == channel)
  220. {
  221. nrf_drv_saadc_channel_uninit(m_adc_config[i].channel);
  222. m_adc_config[i].pin = PIN_NOT_USED;
  223. m_adc_config[i].channel = CHANNEL_NOT_USED;
  224. if(sample_in_buffer != 0)sample_in_buffer--;
  225. DEBUG_LOG("del channel ( %d ):\n", channel);
  226. return ADC_OP_SUCCESS;
  227. }
  228. }
  229. return ADC_ERR_REMOVE_PIN_CHANNEL;
  230. }
  231. /**
  232. @brief ADC初始化
  233. @param 无
  234. @return 无
  235. */
  236. void ADC_Initialize(void)
  237. {
  238. ADC_SetPinChannel(PIN_ADC_CHARGMEASURE, PIN_ADC_CHARGMEASURE_CHANNEL,NRF_GPIO_PIN_NOPULL);
  239. ADC_SetPinChannel(PIN_ADC_BAT_IN, PIN_ADC_BAT_CHANNEL,NRF_GPIO_PIN_NOPULL);
  240. ADC_Init();
  241. Wakeup_Regist(cb_adcWakeup);
  242. Sleep_Regist(cb_adcSleep);
  243. Chargeadc_state = ChargeADC_IDIE;
  244. }
  245. uint32_t ADC_ReadChargePin(uint32_t channel)
  246. {
  247. uint32_t errCode;
  248. if(Chargeadc_state != ChargeADC_IDIE)
  249. {
  250. return ADC_ERR_READ_BUSY;
  251. }
  252. //没有配置通道返回失败
  253. if(sample_in_buffer == 0)return ADC_ERR_READ_NO_CHANNEL;
  254. nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
  255. errCode = nrf_drv_saadc_sample();
  256. if(errCode != NRF_SUCCESS)return ADC_ERR_READ_FAIL;
  257. DEBUG_LOG(" >> ChargeADC_SET\r\n");
  258. Chargeadc_state =ChargeADC_SET;
  259. return ADC_OP_SUCCESS;
  260. }
  261. /**
  262. @brief ADC读取
  263. @param channel -[in] 需要读取的通道
  264. @param p_adc_value -[out] 返回读取的通道值
  265. @return 错误代码
  266. */
  267. uint32_t ADC_Read(uint32_t channel, int16_t *p_adc_value)
  268. {
  269. uint32_t errCode;
  270. uint32_t wait_time_out = WAIT_TIME_VALUE;
  271. uint8_t adc_sort[CHANNEL_MAX] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
  272. uint8_t sort_index = 0;
  273. int i;
  274. adc_SampleOk = false;
  275. if(Chargeadc_state != ChargeADC_IDIE)return ADC_ERR_READ_BUSY;
  276. //没有配置通道返回失败
  277. if(sample_in_buffer == 0)return ADC_ERR_READ_NO_CHANNEL;
  278. errCode = nrf_drv_saadc_sample();
  279. if(errCode != NRF_SUCCESS)return ADC_ERR_READ_FAIL;
  280. //等待采集
  281. while(!adc_SampleOk)
  282. {
  283. if(wait_time_out--){
  284. // nrf_pwr_mgmt_run();
  285. }
  286. else{
  287. return ADC_ERR_READ_TIMEOUT;
  288. }
  289. }
  290. //预先排序,采集时填充顺序为,通道编号小的先填充。
  291. for(i=0;i<CHANNEL_MAX;i++)
  292. {
  293. if(channelConfig[i].pin_p != NRF_SAADC_INPUT_DISABLED){
  294. adc_sort[sort_index] = i;
  295. sort_index++;
  296. }
  297. }
  298. //获取数据
  299. for(i=0;i<sample_in_buffer;i++)
  300. {
  301. if(adc_sort[i] == channel)
  302. {
  303. *p_adc_value = s_bufferPool[i];
  304. }
  305. }
  306. return ADC_OP_SUCCESS;
  307. }
  308. uint32_t ADC_Read_CallBack_Once(uint32_t channel, bsp_adc_read_cb cb)
  309. {
  310. uint32_t errCode;
  311. for(int i=0;i<CHANNEL_MAX;i++)
  312. {
  313. if(m_adc_config[i].channel == channel)
  314. {
  315. if(cb != NULL)
  316. {
  317. m_cb = cb;
  318. m_cb_channel = channel;
  319. m_cb_count = 1;
  320. }
  321. //没有配置通道返回失败
  322. if(sample_in_buffer == 0)return ADC_ERR_READ_NO_CHANNEL;
  323. errCode = nrf_drv_saadc_sample();
  324. if(errCode != NRF_SUCCESS)return ADC_ERR_READ_FAIL;
  325. return ADC_OP_SUCCESS;
  326. }
  327. }
  328. return ADC_ERR_READ_NO_CHANNEL;
  329. }
  330. /**
  331. @brief 开启ADC,与初始化没有区别,为了与Disable成对出现
  332. @param 无
  333. @return 无
  334. */
  335. void ADC_Enable(void)
  336. {
  337. ADC_Init();
  338. }
  339. /**
  340. @brief 禁用ADC
  341. @param 无
  342. @return 无
  343. */
  344. void ADC_Disable(void)
  345. {
  346. nrf_drv_saadc_uninit();
  347. }