gd32f30x_adc.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. /*!
  2. \file gd32f30x_adc.c
  3. \brief ADC driver
  4. \version 2017-02-10, V1.0.0, firmware for GD32F30x
  5. \version 2018-10-10, V1.1.0, firmware for GD32F30x
  6. \version 2018-12-25, V2.0.0, firmware for GD32F30x
  7. \version 2020-09-30, V2.1.0, firmware for GD32F30x
  8. */
  9. /*
  10. Copyright (c) 2020, GigaDevice Semiconductor Inc.
  11. Redistribution and use in source and binary forms, with or without modification,
  12. are permitted provided that the following conditions are met:
  13. 1. Redistributions of source code must retain the above copyright notice, this
  14. list of conditions and the following disclaimer.
  15. 2. Redistributions in binary form must reproduce the above copyright notice,
  16. this list of conditions and the following disclaimer in the documentation
  17. and/or other materials provided with the distribution.
  18. 3. Neither the name of the copyright holder nor the names of its contributors
  19. may be used to endorse or promote products derived from this software without
  20. specific prior written permission.
  21. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  22. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  24. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  25. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  26. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  27. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  28. WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  30. OF SUCH DAMAGE.
  31. */
  32. #include "gd32f30x_adc.h"
  33. /*!
  34. \brief reset ADC
  35. \param[in] adc_periph: ADCx,x=0,1,2
  36. only one among these parameters can be selected
  37. \param[out] none
  38. \retval none
  39. */
  40. void adc_deinit(uint32_t adc_periph)
  41. {
  42. switch(adc_periph){
  43. case ADC0:
  44. rcu_periph_reset_enable(RCU_ADC0RST);
  45. rcu_periph_reset_disable(RCU_ADC0RST);
  46. break;
  47. case ADC1:
  48. rcu_periph_reset_enable(RCU_ADC1RST);
  49. rcu_periph_reset_disable(RCU_ADC1RST);
  50. break;
  51. #if (defined(GD32F30X_HD) || defined(GD32F30X_XD))
  52. case ADC2:
  53. rcu_periph_reset_enable(RCU_ADC2RST);
  54. rcu_periph_reset_disable(RCU_ADC2RST);
  55. break;
  56. #endif
  57. default:
  58. break;
  59. }
  60. }
  61. /*!
  62. \brief enable ADC interface
  63. \param[in] adc_periph: ADCx,x=0,1,2
  64. only one among these parameters can be selected
  65. \param[out] none
  66. \retval none
  67. */
  68. void adc_enable(uint32_t adc_periph)
  69. {
  70. if(RESET == (ADC_CTL1(adc_periph) & ADC_CTL1_ADCON)){
  71. ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_ADCON;
  72. }
  73. }
  74. /*!
  75. \brief disable ADC interface
  76. \param[in] adc_periph: ADCx,x=0,1,2
  77. only one among these parameters can be selected
  78. \param[out] none
  79. \retval none
  80. */
  81. void adc_disable(uint32_t adc_periph)
  82. {
  83. ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ADCON);
  84. }
  85. /*!
  86. \brief ADC calibration and reset calibration
  87. \param[in] adc_periph: ADCx,x=0,1,2
  88. only one among these parameters can be selected
  89. \param[out] none
  90. \retval none
  91. */
  92. void adc_calibration_enable(uint32_t adc_periph)
  93. {
  94. /* reset the selected ADC calibration registers */
  95. ADC_CTL1(adc_periph) |= (uint32_t) ADC_CTL1_RSTCLB;
  96. /* check the RSTCLB bit state */
  97. while((ADC_CTL1(adc_periph) & ADC_CTL1_RSTCLB)){
  98. }
  99. /* enable ADC calibration process */
  100. ADC_CTL1(adc_periph) |= ADC_CTL1_CLB;
  101. /* check the CLB bit state */
  102. while((ADC_CTL1(adc_periph) & ADC_CTL1_CLB)){
  103. }
  104. }
  105. /*!
  106. \brief enable DMA request
  107. \param[in] adc_periph: ADCx,x=0,1,2
  108. only one among these parameters can be selected
  109. \param[out] none
  110. \retval none
  111. */
  112. void adc_dma_mode_enable(uint32_t adc_periph)
  113. {
  114. ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DMA);
  115. }
  116. /*!
  117. \brief disable DMA request
  118. \param[in] adc_periph: ADCx,x=0,1,2
  119. only one among these parameters can be selected
  120. \param[out] none
  121. \retval none
  122. */
  123. void adc_dma_mode_disable(uint32_t adc_periph)
  124. {
  125. ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DMA);
  126. }
  127. /*!
  128. \brief enable the temperature sensor and Vrefint channel
  129. \param[in] none
  130. \param[out] none
  131. \retval none
  132. */
  133. void adc_tempsensor_vrefint_enable(void)
  134. {
  135. /* enable the temperature sensor and Vrefint channel */
  136. ADC_CTL1(ADC0) |= ADC_CTL1_TSVREN;
  137. }
  138. /*!
  139. \brief disable the temperature sensor and Vrefint channel
  140. \param[in] none
  141. \param[out] none
  142. \retval none
  143. */
  144. void adc_tempsensor_vrefint_disable(void)
  145. {
  146. /* disable the temperature sensor and Vrefint channel */
  147. ADC_CTL1(ADC0) &= ~ADC_CTL1_TSVREN;
  148. }
  149. /*!
  150. \brief configure ADC resolution
  151. \param[in] adc_periph: ADCx,x=0,1,2
  152. only one among these parameters can be selected
  153. \param[in] resolution: ADC resolution
  154. only one among these parameters can be selected
  155. \arg ADC_RESOLUTION_12B: 12-bit ADC resolution
  156. \arg ADC_RESOLUTION_10B: 10-bit ADC resolution
  157. \arg ADC_RESOLUTION_8B: 8-bit ADC resolution
  158. \arg ADC_RESOLUTION_6B: 6-bit ADC resolution
  159. \param[out] none
  160. \retval none
  161. */
  162. void adc_resolution_config(uint32_t adc_periph , uint32_t resolution)
  163. {
  164. ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_DRES);
  165. ADC_OVSAMPCTL(adc_periph) |= (uint32_t)resolution;
  166. }
  167. /*!
  168. \brief configure ADC discontinuous mode
  169. \param[in] adc_periph: ADCx,x=0,1,2
  170. only one among these parameters can be selected
  171. \param[in] adc_channel_group: select the channel group
  172. only one among these parameters can be selected
  173. \arg ADC_REGULAR_CHANNEL: regular channel group
  174. \arg ADC_INSERTED_CHANNEL: inserted channel group
  175. \arg ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of regular & inserted channel
  176. \param[in] length: number of conversions in discontinuous mode,the number can be 1..8
  177. for regular channel ,the number has no effect for inserted channel
  178. \param[out] none
  179. \retval none
  180. */
  181. void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_channel_group, uint8_t length)
  182. {
  183. ADC_CTL0(adc_periph) &= ~((uint32_t)( ADC_CTL0_DISRC | ADC_CTL0_DISIC ));
  184. switch(adc_channel_group){
  185. case ADC_REGULAR_CHANNEL:
  186. /* config the number of conversions in discontinuous mode */
  187. ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DISNUM);
  188. ADC_CTL0(adc_periph) |= CTL0_DISNUM(((uint32_t)length - 1U));
  189. ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISRC;
  190. break;
  191. case ADC_INSERTED_CHANNEL:
  192. ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISIC;
  193. break;
  194. case ADC_CHANNEL_DISCON_DISABLE:
  195. default:
  196. break;
  197. }
  198. }
  199. /*!
  200. \brief configure the ADC sync mode
  201. \param[in] mode: ADC mode
  202. only one among these parameters can be selected
  203. \arg ADC_MODE_FREE: all the ADCs work independently
  204. \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL: ADC0 and ADC1 work in combined regular parallel + inserted parallel mode
  205. \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION: ADC0 and ADC1 work in combined regular parallel + trigger rotation mode
  206. \arg ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_FAST: ADC0 and ADC1 work in combined inserted parallel + follow-up fast mode
  207. \arg ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_SLOW: ADC0 and ADC1 work in combined inserted parallel + follow-up slow mode
  208. \arg ADC_DAUL_INSERTED_PARALLEL: ADC0 and ADC1 work in inserted parallel mode only
  209. \arg ADC_DAUL_REGULAL_PARALLEL: ADC0 and ADC1 work in regular parallel mode only
  210. \arg ADC_DAUL_REGULAL_FOLLOWUP_FAST: ADC0 and ADC1 work in follow-up fast mode only
  211. \arg ADC_DAUL_REGULAL_FOLLOWUP_SLOW: ADC0 and ADC1 work in follow-up slow mode only
  212. \arg ADC_DAUL_INSERTED_TRRIGGER_ROTATION: ADC0 and ADC1 work in trigger rotation mode only
  213. \param[out] none
  214. \retval none
  215. */
  216. void adc_mode_config(uint32_t mode)
  217. {
  218. ADC_CTL0(ADC0) &= ~(ADC_CTL0_SYNCM);
  219. ADC_CTL0(ADC0) |= mode;
  220. }
  221. /*!
  222. \brief enable or disable ADC special function
  223. \param[in] adc_periph: ADCx,x=0,1,2
  224. only one among these parameters can be selected
  225. \param[in] function: the function to config
  226. one or more parameters can be selected below
  227. \arg ADC_SCAN_MODE: scan mode select
  228. \arg ADC_INSERTED_CHANNEL_AUTO: inserted channel group convert automatically
  229. \arg ADC_CONTINUOUS_MODE: continuous mode select
  230. \param[in] newvalue: ENABLE or DISABLE
  231. \param[out] none
  232. \retval none
  233. */
  234. void adc_special_function_config(uint32_t adc_periph , uint32_t function , ControlStatus newvalue)
  235. {
  236. if(newvalue){
  237. if(0U != (function & ADC_SCAN_MODE)){
  238. ADC_CTL0(adc_periph) |= ADC_SCAN_MODE;
  239. }
  240. if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)){
  241. ADC_CTL0(adc_periph) |= ADC_INSERTED_CHANNEL_AUTO;
  242. }
  243. if(0U != (function & ADC_CONTINUOUS_MODE)){
  244. ADC_CTL1(adc_periph) |= ADC_CONTINUOUS_MODE;
  245. }
  246. }else{
  247. if(0U != (function & ADC_SCAN_MODE)){
  248. ADC_CTL0(adc_periph) &= ~ADC_SCAN_MODE;
  249. }
  250. if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)){
  251. ADC_CTL0(adc_periph) &= ~ADC_INSERTED_CHANNEL_AUTO;
  252. }
  253. if(0U != (function & ADC_CONTINUOUS_MODE)){
  254. ADC_CTL1(adc_periph) &= ~ADC_CONTINUOUS_MODE;
  255. }
  256. }
  257. }
  258. /*!
  259. \brief configure ADC data alignment
  260. \param[in] adc_periph: ADCx,x=0,1,2
  261. only one among these parameters can be selected
  262. \param[in] data_alignment: data alignment select
  263. only one parameter can be selected
  264. \arg ADC_DATAALIGN_RIGHT: LSB alignment
  265. \arg ADC_DATAALIGN_LEFT: MSB alignment
  266. \param[out] none
  267. \retval none
  268. */
  269. void adc_data_alignment_config(uint32_t adc_periph , uint32_t data_alignment)
  270. {
  271. if(ADC_DATAALIGN_RIGHT != data_alignment){
  272. ADC_CTL1(adc_periph) |= ADC_CTL1_DAL;
  273. }else{
  274. ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DAL);
  275. }
  276. }
  277. /*!
  278. \brief configure the length of regular channel group or inserted channel group
  279. \param[in] adc_periph: ADCx,x=0,1,2
  280. only one among these parameters can be selected
  281. \param[in] adc_channel_group: select the channel group
  282. only one parameter can be selected
  283. \arg ADC_REGULAR_CHANNEL: regular channel group
  284. \arg ADC_INSERTED_CHANNEL: inserted channel group
  285. \param[in] length: the length of the channel
  286. regular channel 1-16
  287. inserted channel 1-4
  288. \param[out] none
  289. \retval none
  290. */
  291. void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t length)
  292. {
  293. switch(adc_channel_group){
  294. case ADC_REGULAR_CHANNEL:
  295. ADC_RSQ0(adc_periph) &= ~((uint32_t)ADC_RSQ0_RL);
  296. ADC_RSQ0(adc_periph) |= RSQ0_RL((uint32_t)(length-1U));
  297. break;
  298. case ADC_INSERTED_CHANNEL:
  299. ADC_ISQ(adc_periph) &= ~((uint32_t)ADC_ISQ_IL);
  300. ADC_ISQ(adc_periph) |= ISQ_IL((uint32_t)(length-1U));
  301. break;
  302. default:
  303. break;
  304. }
  305. }
  306. /*!
  307. \brief configure ADC regular channel
  308. \param[in] adc_periph: ADCx,x=0,1,2
  309. only one among these parameters can be selected
  310. \param[in] rank: the regular group sequence rank,this parameter must be between 0 to 15
  311. \param[in] adc_channel: the selected ADC channel
  312. only one among these parameters can be selected
  313. \arg ADC_CHANNEL_x(x=0..17)(x=16 and x=17 are only for ADC0): ADC Channelx
  314. \param[in] sample_time: the sample time value
  315. only one parameter can be selected
  316. \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles
  317. \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles
  318. \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles
  319. \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles
  320. \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles
  321. \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles
  322. \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles
  323. \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles
  324. \param[out] none
  325. \retval none
  326. */
  327. void adc_regular_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time)
  328. {
  329. uint32_t rsq,sampt;
  330. /* ADC regular sequence config */
  331. if(rank < 6U){
  332. rsq = ADC_RSQ2(adc_periph);
  333. rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*rank)));
  334. rsq |= ((uint32_t)adc_channel << (5U*rank));
  335. ADC_RSQ2(adc_periph) = rsq;
  336. }else if(rank < 12U){
  337. rsq = ADC_RSQ1(adc_periph);
  338. rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-6U))));
  339. rsq |= ((uint32_t)adc_channel << (5U*(rank-6U)));
  340. ADC_RSQ1(adc_periph) = rsq;
  341. }else if(rank < 16U){
  342. rsq = ADC_RSQ0(adc_periph);
  343. rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-12U))));
  344. rsq |= ((uint32_t)adc_channel << (5U*(rank-12U)));
  345. ADC_RSQ0(adc_periph) = rsq;
  346. }else{
  347. }
  348. /* ADC sampling time config */
  349. if(adc_channel < 10U){
  350. sampt = ADC_SAMPT1(adc_periph);
  351. sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*adc_channel)));
  352. sampt |= (uint32_t)(sample_time << (3U*adc_channel));
  353. ADC_SAMPT1(adc_periph) = sampt;
  354. }else if(adc_channel < 18U){
  355. sampt = ADC_SAMPT0(adc_periph);
  356. sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(adc_channel-10U))));
  357. sampt |= (uint32_t)(sample_time << (3U*(adc_channel-10U)));
  358. ADC_SAMPT0(adc_periph) = sampt;
  359. }else{
  360. }
  361. }
  362. /*!
  363. \brief configure ADC inserted channel
  364. \param[in] adc_periph: ADCx,x=0,1,2
  365. only one among these parameters can be selected
  366. \param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3
  367. \param[in] adc_channel: the selected ADC channel
  368. only one among these parameters can be selected
  369. \arg ADC_CHANNEL_x(x=0..17)(x=16 and x=17 are only for ADC0): ADC Channelx
  370. \param[in] sample_time: The sample time value
  371. only one parameter can be selected
  372. \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles
  373. \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles
  374. \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles
  375. \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles
  376. \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles
  377. \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles
  378. \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles
  379. \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles
  380. \param[out] none
  381. \retval none
  382. */
  383. void adc_inserted_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time)
  384. {
  385. uint8_t inserted_length;
  386. uint32_t isq,sampt;
  387. inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph) , 20U , 21U);
  388. isq = ADC_ISQ(adc_periph);
  389. isq &= ~((uint32_t)(ADC_ISQ_ISQN << (5U * ((3 + rank) - inserted_length))));
  390. isq |= ((uint32_t)adc_channel << (5U * ((3 + rank) - inserted_length)));
  391. ADC_ISQ(adc_periph) = isq;
  392. /* ADC sampling time config */
  393. if(adc_channel < 10U){
  394. sampt = ADC_SAMPT1(adc_periph);
  395. sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*adc_channel)));
  396. sampt |= (uint32_t) sample_time << (3U*adc_channel);
  397. ADC_SAMPT1(adc_periph) = sampt;
  398. }else if(adc_channel < 18U){
  399. sampt = ADC_SAMPT0(adc_periph);
  400. sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(adc_channel-10U))));
  401. sampt |= ((uint32_t)sample_time << (3U*(adc_channel-10U)));
  402. ADC_SAMPT0(adc_periph) = sampt;
  403. }else{
  404. }
  405. }
  406. /*!
  407. \brief configure ADC inserted channel offset
  408. \param[in] adc_periph: ADCx,x=0,1,2
  409. only one among these parameters can be selected
  410. \param[in] inserted_channel : insert channel select
  411. only one parameter can be selected
  412. \arg ADC_INSERTED_CHANNEL_0: inserted channel0
  413. \arg ADC_INSERTED_CHANNEL_1: inserted channel1
  414. \arg ADC_INSERTED_CHANNEL_2: inserted channel2
  415. \arg ADC_INSERTED_CHANNEL_3: inserted channel3
  416. \param[in] offset : the offset data
  417. \param[out] none
  418. \retval none
  419. */
  420. void adc_inserted_channel_offset_config(uint32_t adc_periph , uint8_t inserted_channel , uint16_t offset)
  421. {
  422. uint8_t inserted_length;
  423. uint32_t num = 0U;
  424. inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph) , 20U , 21U);
  425. num = 3U - (inserted_length - inserted_channel);
  426. if(num <= 3U){
  427. /* calculate the offset of the register */
  428. num = num * 4U;
  429. /* config the offset of the selected channels */
  430. REG32((adc_periph) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset);
  431. }
  432. }
  433. /*!
  434. \brief enable ADC external trigger
  435. \param[in] adc_periph: ADCx,x=0,1,2
  436. only one among these parameters can be selected
  437. \param[in] adc_channel_group: select the channel group
  438. one or more parameters can be selected
  439. \arg ADC_REGULAR_CHANNEL: regular channel group
  440. \arg ADC_INSERTED_CHANNEL: inserted channel group
  441. \param[in] newvalue: ENABLE or DISABLE
  442. \param[out] none
  443. \retval none
  444. */
  445. void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_channel_group, ControlStatus newvalue)
  446. {
  447. if(newvalue){
  448. if(0U != (adc_channel_group & ADC_REGULAR_CHANNEL)){
  449. ADC_CTL1(adc_periph) |= ADC_CTL1_ETERC;
  450. }
  451. if(0U != (adc_channel_group & ADC_INSERTED_CHANNEL)){
  452. ADC_CTL1(adc_periph) |= ADC_CTL1_ETEIC;
  453. }
  454. }else{
  455. if(0U != (adc_channel_group & ADC_REGULAR_CHANNEL)){
  456. ADC_CTL1(adc_periph) &= ~ADC_CTL1_ETERC;
  457. }
  458. if(0U != (adc_channel_group & ADC_INSERTED_CHANNEL)){
  459. ADC_CTL1(adc_periph) &= ~ADC_CTL1_ETEIC;
  460. }
  461. }
  462. }
  463. /*!
  464. \brief configure ADC external trigger source
  465. \param[in] adc_periph: ADCx,x=0,1,2
  466. only one among these parameters can be selected
  467. \param[in] adc_channel_group: select the channel group
  468. only one parameter can be selected
  469. \arg ADC_REGULAR_CHANNEL: regular channel group
  470. \arg ADC_INSERTED_CHANNEL: inserted channel group
  471. \param[in] external_trigger_source: regular or inserted group trigger source
  472. only one parameter can be selected
  473. for regular channel:
  474. \arg ADC0_1_EXTTRIG_REGULAR_T0_CH0: timer 0 CC0 event select
  475. \arg ADC0_1_EXTTRIG_REGULAR_T0_CH1: timer 0 CC1 event select
  476. \arg ADC0_1_EXTTRIG_REGULAR_T0_CH2: timer 0 CC2 event select
  477. \arg ADC0_1_EXTTRIG_REGULAR_T1_CH1: timer 1 CC1 event select
  478. \arg ADC0_1_EXTTRIG_REGULAR_T2_TRGO: timer 2 TRGO event select
  479. \arg ADC0_1_EXTTRIG_REGULAR_T3_CH3: timer 3 CC3 event select
  480. \arg ADC0_1_EXTTRIG_REGULAR_T7_TRGO: timer 7 TRGO event select
  481. \arg ADC0_1_EXTTRIG_REGULAR_EXTI_11 : external interrupt line 11
  482. \arg ADC2_EXTTRIG_REGULAR_T2_CH0: timer 2 CC0 event select
  483. \arg ADC2_EXTTRIG_REGULAR_T1_CH2: timer 1 CC2 event select
  484. \arg ADC2_EXTTRIG_REGULAR_T0_CH2: timer 0 CC2 event select
  485. \arg ADC2_EXTTRIG_REGULAR_T7_CH0: timer 7 CC0 event select
  486. \arg ADC2_EXTTRIG_REGULAR_T7_TRGO: timer 7 TRGO event select
  487. \arg ADC2_EXTTRIG_REGULAR_T4_CH0: timer 4 CC0 event select
  488. \arg ADC2_EXTTRIG_REGULAR_T4_CH2: timer 4 CC2 event select
  489. \arg ADC0_1_2_EXTTRIG_REGULAR_NONE: software trigger
  490. for inserted channel:
  491. \arg ADC0_1_EXTTRIG_INSERTED_T0_TRGO: timer 0 TRGO event select
  492. \arg ADC0_1_EXTTRIG_INSERTED_T0_CH3: timer 0 CC3 event select
  493. \arg ADC0_1_EXTTRIG_INSERTED_T1_TRGO: timer 1 TRGO event select
  494. \arg ADC0_1_EXTTRIG_INSERTED_T1_CH0: timer 1 CC0 event select
  495. \arg ADC0_1_EXTTRIG_INSERTED_T2_CH3: timer 2 CC3 event select
  496. \arg ADC0_1_EXTTRIG_INSERTED_T3_TRGO: timer 3 TRGO event select
  497. \arg ADC0_1_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15
  498. \arg ADC0_1_EXTTRIG_INSERTED_T7_CH3: timer 7 CC3 event select
  499. \arg ADC2_EXTTRIG_INSERTED_T0_TRGO: timer 0 TRGO event select
  500. \arg ADC2_EXTTRIG_INSERTED_T0_CH3: timer 0 CC3 event select
  501. \arg ADC2_EXTTRIG_INSERTED_T3_CH2: timer 3 CC2 event select
  502. \arg ADC2_EXTTRIG_INSERTED_T7_CH1: timer 7 CC1 event select
  503. \arg ADC2_EXTTRIG_INSERTED_T7_CH3: timer 7 CC3 event select
  504. \arg ADC2_EXTTRIG_INSERTED_T4_TRGO: timer 4 TRGO event select
  505. \arg ADC2_EXTTRIG_INSERTED_T4_CH3: timer 4 CC3 event select
  506. \arg ADC0_1_2_EXTTRIG_INSERTED_NONE: software trigger
  507. \param[out] none
  508. \retval none
  509. */
  510. void adc_external_trigger_source_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t external_trigger_source)
  511. {
  512. switch(adc_channel_group){
  513. case ADC_REGULAR_CHANNEL:
  514. ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSRC);
  515. ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source;
  516. break;
  517. case ADC_INSERTED_CHANNEL:
  518. ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSIC);
  519. ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source;
  520. break;
  521. default:
  522. break;
  523. }
  524. }
  525. /*!
  526. \brief enable ADC software trigger
  527. \param[in] adc_periph: ADCx,x=0,1,2
  528. only one among these parameters can be selected
  529. \param[in] adc_channel_group: select the channel group
  530. one or more parameters can be selected
  531. \arg ADC_REGULAR_CHANNEL: regular channel group
  532. \arg ADC_INSERTED_CHANNEL: inserted channel group
  533. \param[out] none
  534. \retval none
  535. */
  536. void adc_software_trigger_enable(uint32_t adc_periph , uint8_t adc_channel_group)
  537. {
  538. if(0U != (adc_channel_group & ADC_REGULAR_CHANNEL)){
  539. ADC_CTL1(adc_periph) |= ADC_CTL1_SWRCST;
  540. }
  541. if(0U != (adc_channel_group & ADC_INSERTED_CHANNEL)){
  542. ADC_CTL1(adc_periph) |= ADC_CTL1_SWICST;
  543. }
  544. }
  545. /*!
  546. \brief read ADC regular group data register
  547. \param[in] adc_periph: ADCx,x=0,1,2
  548. only one among these parameters can be selected
  549. \param[in] none
  550. \param[out] none
  551. \retval the conversion value
  552. */
  553. uint16_t adc_regular_data_read(uint32_t adc_periph)
  554. {
  555. return (uint16_t)(ADC_RDATA(adc_periph));
  556. }
  557. /*!
  558. \brief read ADC inserted group data register
  559. \param[in] adc_periph: ADCx,x=0,1,2
  560. only one among these parameters can be selected
  561. \param[in] inserted_channel : insert channel select
  562. only one parameter can be selected
  563. \arg ADC_INSERTED_CHANNEL_0: inserted Channel0
  564. \arg ADC_INSERTED_CHANNEL_1: inserted channel1
  565. \arg ADC_INSERTED_CHANNEL_2: inserted Channel2
  566. \arg ADC_INSERTED_CHANNEL_3: inserted Channel3
  567. \param[out] none
  568. \retval the conversion value
  569. */
  570. uint16_t adc_inserted_data_read(uint32_t adc_periph , uint8_t inserted_channel)
  571. {
  572. uint32_t idata;
  573. /* read the data of the selected channel */
  574. switch(inserted_channel){
  575. case ADC_INSERTED_CHANNEL_0:
  576. idata = ADC_IDATA0(adc_periph);
  577. break;
  578. case ADC_INSERTED_CHANNEL_1:
  579. idata = ADC_IDATA1(adc_periph);
  580. break;
  581. case ADC_INSERTED_CHANNEL_2:
  582. idata = ADC_IDATA2(adc_periph);
  583. break;
  584. case ADC_INSERTED_CHANNEL_3:
  585. idata = ADC_IDATA3(adc_periph);
  586. break;
  587. default:
  588. idata = 0U;
  589. break;
  590. }
  591. return (uint16_t)idata;
  592. }
  593. /*!
  594. \brief read the last ADC0 and ADC1 conversion result data in sync mode
  595. \param[in] none
  596. \param[out] none
  597. \retval the conversion value
  598. */
  599. uint32_t adc_sync_mode_convert_value_read(void)
  600. {
  601. /* return conversion value */
  602. return ADC_RDATA(ADC0);
  603. }
  604. /*!
  605. \brief get the ADC flag bits
  606. \param[in] adc_periph: ADCx,x=0,1,2
  607. only one among these parameters can be selected
  608. \param[in] adc_flag: the adc flag bits
  609. only one parameter can be selected
  610. \arg ADC_FLAG_WDE: analog watchdog event flag
  611. \arg ADC_FLAG_EOC: end of group conversion flag
  612. \arg ADC_FLAG_EOIC: end of inserted group conversion flag
  613. \arg ADC_FLAG_STIC: start flag of inserted channel group
  614. \arg ADC_FLAG_STRC: start flag of regular channel group
  615. \param[out] none
  616. \retval FlagStatus: SET or RESET
  617. */
  618. FlagStatus adc_flag_get(uint32_t adc_periph , uint32_t adc_flag)
  619. {
  620. FlagStatus reval = RESET;
  621. if(ADC_STAT(adc_periph) & adc_flag){
  622. reval = SET;
  623. }
  624. return reval;
  625. }
  626. /*!
  627. \brief clear the ADC flag bits
  628. \param[in] adc_periph: ADCx,x=0,1,2
  629. only one among these parameters can be selected
  630. \param[in] adc_flag: the adc flag bits
  631. one or more parameters can be selected
  632. \arg ADC_FLAG_WDE: analog watchdog event flag
  633. \arg ADC_FLAG_EOC: end of group conversion flag
  634. \arg ADC_FLAG_EOIC: end of inserted group conversion flag
  635. \arg ADC_FLAG_STIC: start flag of inserted channel group
  636. \arg ADC_FLAG_STRC: start flag of regular channel group
  637. \param[out] none
  638. \retval none
  639. */
  640. void adc_flag_clear(uint32_t adc_periph , uint32_t adc_flag)
  641. {
  642. ADC_STAT(adc_periph) = ~((uint32_t)adc_flag);
  643. }
  644. /*!
  645. \brief get the ADC interrupt bits
  646. \param[in] adc_periph: ADCx,x=0,1,2
  647. only one among these parameters can be selected
  648. \param[in] adc_interrupt: the adc interrupt bits
  649. only oneparameter can be selected
  650. \arg ADC_INT_FLAG_WDE: analog watchdog interrupt
  651. \arg ADC_INT_FLAG_EOC: end of group conversion interrupt
  652. \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt
  653. \param[out] none
  654. \retval FlagStatus: SET or RESET
  655. */
  656. FlagStatus adc_interrupt_flag_get(uint32_t adc_periph , uint32_t adc_interrupt)
  657. {
  658. FlagStatus interrupt_flag = RESET;
  659. uint32_t state;
  660. /* check the interrupt bits */
  661. switch(adc_interrupt){
  662. case ADC_INT_FLAG_WDE:
  663. state = ADC_STAT(adc_periph) & ADC_STAT_WDE;
  664. if((ADC_CTL0(adc_periph) & ADC_CTL0_WDEIE) && state){
  665. interrupt_flag = SET;
  666. }
  667. break;
  668. case ADC_INT_FLAG_EOC:
  669. state = ADC_STAT(adc_periph) & ADC_STAT_EOC;
  670. if((ADC_CTL0(adc_periph) & ADC_CTL0_EOCIE) && state){
  671. interrupt_flag = SET;
  672. }
  673. break;
  674. case ADC_INT_FLAG_EOIC:
  675. state = ADC_STAT(adc_periph) & ADC_STAT_EOIC;
  676. if((ADC_CTL0(adc_periph) & ADC_CTL0_EOICIE) && state){
  677. interrupt_flag = SET;
  678. }
  679. break;
  680. default:
  681. break;
  682. }
  683. return interrupt_flag;
  684. }
  685. /*!
  686. \brief clear the ADC flag
  687. \param[in] adc_periph: ADCx,x=0,1,2
  688. only one among these parameters can be selected
  689. \param[in] adc_interrupt: the adc status flag
  690. one or more parameters can be selected
  691. \arg ADC_INT_FLAG_WDE: analog watchdog interrupt
  692. \arg ADC_INT_FLAG_EOC: end of group conversion interrupt
  693. \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt
  694. \param[out] none
  695. \retval none
  696. */
  697. void adc_interrupt_flag_clear(uint32_t adc_periph , uint32_t adc_interrupt)
  698. {
  699. ADC_STAT(adc_periph) = ~((uint32_t)adc_interrupt);
  700. }
  701. /*!
  702. \brief enable ADC interrupt
  703. \param[in] adc_periph: ADCx,x=0,1,2
  704. only one among these parameters can be selected
  705. \param[in] adc_interrupt: the adc interrupt
  706. one or more parameters can be selected
  707. \arg ADC_INT_WDE: analog watchdog interrupt flag
  708. \arg ADC_INT_EOC: end of group conversion interrupt flag
  709. \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag
  710. \param[out] none
  711. \retval none
  712. */
  713. void adc_interrupt_enable(uint32_t adc_periph , uint32_t adc_interrupt)
  714. {
  715. if(0U != (adc_interrupt & ADC_INT_WDE)){
  716. ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_WDEIE;
  717. }
  718. if(0U != (adc_interrupt & ADC_INT_EOC)){
  719. ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOCIE;
  720. }
  721. if(0U != (adc_interrupt & ADC_INT_EOIC)){
  722. ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOICIE;
  723. }
  724. }
  725. /*!
  726. \brief disable ADC interrupt
  727. \param[in] adc_periph: ADCx,x=0,1,2
  728. only one among these parameters can be selected
  729. \param[in] adc_interrupt: the adc interrupt flag
  730. one or more parameters can be selected
  731. \arg ADC_INT_WDE: analog watchdog interrupt flag
  732. \arg ADC_INT_EOC: end of group conversion interrupt flag
  733. \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag
  734. \param[out] none
  735. \retval none
  736. */
  737. void adc_interrupt_disable(uint32_t adc_periph, uint32_t adc_interrupt)
  738. {
  739. if(0U != (adc_interrupt & ADC_INT_WDE)){
  740. ADC_CTL0(adc_periph) &= ~(uint32_t) ADC_CTL0_WDEIE;
  741. }
  742. if(0U != (adc_interrupt & ADC_INT_EOC)){
  743. ADC_CTL0(adc_periph) &= ~(uint32_t) ADC_CTL0_EOCIE;
  744. }
  745. if(0U != (adc_interrupt & ADC_INT_EOIC)){
  746. ADC_CTL0(adc_periph) &= ~(uint32_t) ADC_CTL0_EOICIE;
  747. }
  748. }
  749. /*!
  750. \brief configure ADC analog watchdog single channel
  751. \param[in] adc_periph: ADCx,x=0,1,2
  752. only one among these parameters can be selected
  753. \param[in] adc_channel: the selected ADC channel
  754. only one among these parameters can be selected
  755. \arg ADC_CHANNEL_x: ADC Channelx(x=0..17)(x=16 and x=17 are only for ADC0)
  756. \param[out] none
  757. \retval none
  758. */
  759. void adc_watchdog_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel)
  760. {
  761. ADC_CTL0(adc_periph) &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL);
  762. ADC_CTL0(adc_periph) |= (uint32_t)adc_channel;
  763. ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC);
  764. }
  765. /*!
  766. \brief configure ADC analog watchdog group channel
  767. \param[in] adc_periph: ADCx,x=0,1,2
  768. only one among these parameters can be selected
  769. \param[in] adc_channel_group: the channel group use analog watchdog
  770. only one parameter can be selected
  771. \arg ADC_REGULAR_CHANNEL: regular channel group
  772. \arg ADC_INSERTED_CHANNEL: inserted channel group
  773. \arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group
  774. \param[out] none
  775. \retval none
  776. */
  777. void adc_watchdog_group_channel_enable(uint32_t adc_periph, uint8_t adc_channel_group)
  778. {
  779. ADC_CTL0(adc_periph) &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC);
  780. /* select the group */
  781. switch(adc_channel_group){
  782. case ADC_REGULAR_CHANNEL:
  783. ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_RWDEN;
  784. break;
  785. case ADC_INSERTED_CHANNEL:
  786. ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_IWDEN;
  787. break;
  788. case ADC_REGULAR_INSERTED_CHANNEL:
  789. ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN);
  790. break;
  791. default:
  792. break;
  793. }
  794. }
  795. /*!
  796. \brief disable ADC analog watchdog
  797. \param[in] adc_periph: ADCx,x=0,1,2
  798. only one among these parameters can be selected
  799. \param[out] none
  800. \retval none
  801. */
  802. void adc_watchdog_disable(uint32_t adc_periph)
  803. {
  804. ADC_CTL0(adc_periph) &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL);
  805. }
  806. /*!
  807. \brief configure ADC analog watchdog threshold
  808. \param[in] adc_periph: ADCx,x=0,1,2
  809. only one among these parameters can be selected
  810. \param[in] low_threshold: analog watchdog low threshold,0..4095
  811. \param[in] high_threshold: analog watchdog high threshold,0..4095
  812. \param[out] none
  813. \retval none
  814. */
  815. void adc_watchdog_threshold_config(uint32_t adc_periph , uint16_t low_threshold , uint16_t high_threshold)
  816. {
  817. ADC_WDLT(adc_periph) = (uint32_t)WDLT_WDLT(low_threshold);
  818. ADC_WDHT(adc_periph) = (uint32_t)WDHT_WDHT(high_threshold);
  819. }
  820. /*!
  821. \brief configure ADC oversample mode
  822. \param[in] adc_periph: ADCx,x=0,1,2
  823. only one among these parameters can be selected
  824. \param[in] mode: ADC oversampling mode
  825. only oneparameter can be selected
  826. \arg ADC_OVERSAMPLING_ALL_CONVERT: all oversampled conversions for a channel are done consecutively after a trigger
  827. \arg ADC_OVERSAMPLING_ONE_CONVERT: each oversampled conversion for a channel needs a trigger
  828. \param[in] shift: ADC oversampling shift
  829. only oneparameter can be selected
  830. \arg ADC_OVERSAMPLING_SHIFT_NONE: no oversampling shift
  831. \arg ADC_OVERSAMPLING_SHIFT_1B: 1-bit oversampling shift
  832. \arg ADC_OVERSAMPLING_SHIFT_2B: 2-bit oversampling shift
  833. \arg ADC_OVERSAMPLING_SHIFT_3B: 3-bit oversampling shift
  834. \arg ADC_OVERSAMPLING_SHIFT_4B: 3-bit oversampling shift
  835. \arg ADC_OVERSAMPLING_SHIFT_5B: 5-bit oversampling shift
  836. \arg ADC_OVERSAMPLING_SHIFT_6B: 6-bit oversampling shift
  837. \arg ADC_OVERSAMPLING_SHIFT_7B: 7-bit oversampling shift
  838. \arg ADC_OVERSAMPLING_SHIFT_8B: 8-bit oversampling shift
  839. \param[in] ratio: ADC oversampling ratio
  840. only oneparameter can be selected
  841. \arg ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio multiple 2
  842. \arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio multiple 4
  843. \arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio multiple 8
  844. \arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio multiple 16
  845. \arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio multiple 32
  846. \arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio multiple 64
  847. \arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio multiple 128
  848. \arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio multiple 256
  849. \param[out] none
  850. \retval none
  851. */
  852. void adc_oversample_mode_config(uint32_t adc_periph, uint32_t mode, uint16_t shift, uint8_t ratio)
  853. {
  854. if(ADC_OVERSAMPLING_ONE_CONVERT == mode){
  855. ADC_OVSAMPCTL(adc_periph) |= (uint32_t)ADC_OVSAMPCTL_TOVS;
  856. }else{
  857. ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_TOVS);
  858. }
  859. /* config the shift and ratio */
  860. ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)(ADC_OVSAMPCTL_OVSR | ADC_OVSAMPCTL_OVSS));
  861. ADC_OVSAMPCTL(adc_periph) |= ((uint32_t)shift | (uint32_t)ratio);
  862. }
  863. /*!
  864. \brief enable ADC oversample mode
  865. \param[in] adc_periph: ADCx,x=0,1,2
  866. only one among these parameters can be selected
  867. \param[out] none
  868. \retval none
  869. */
  870. void adc_oversample_mode_enable(uint32_t adc_periph)
  871. {
  872. ADC_OVSAMPCTL(adc_periph) |= ADC_OVSAMPCTL_OVSEN;
  873. }
  874. /*!
  875. \brief disable ADC oversample mode
  876. \param[in] adc_periph: ADCx,x=0,1,2
  877. only one among these parameters can be selected
  878. \param[out] none
  879. \retval none
  880. */
  881. void adc_oversample_mode_disable(uint32_t adc_periph)
  882. {
  883. ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN);
  884. }