cmem7_adc.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /**
  2. *****************************************************************************
  3. * @file cmem7_adc.c
  4. *
  5. * @brief CMEM7 ADC source file
  6. *
  7. *
  8. * @version V1.0
  9. * @date 3. September 2013
  10. *
  11. * @note
  12. *
  13. *****************************************************************************
  14. * @attention
  15. *
  16. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  17. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  18. * TIME. AS A RESULT, CAPITAL-MICRO SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
  19. * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  20. * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  21. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  22. *
  23. * <h2><center>&copy; COPYRIGHT 2013 Capital-micro </center></h2>
  24. *****************************************************************************
  25. */
  26. #include "cmem7_adc.h"
  27. #include "cmem7.h"
  28. #define ADC_SYSTEM_MODE_IDLE 0
  29. static BOOL adc_IsMultiChannel(uint32_t channel) {
  30. uint32_t i = 0;
  31. for (i = 0; channel != 0; i++) {
  32. channel &= (channel - 1);
  33. }
  34. return ((i > 1) ? TRUE : FALSE);
  35. }
  36. static uint8_t adc_GetChannel(uint32_t channel) {
  37. uint32_t i = 0;
  38. for (i = 0; channel > 1; i++) {
  39. channel >>= 1;
  40. }
  41. return i;
  42. }
  43. static void adc_Reset(uint8_t adc, BOOL enable) {
  44. if (adc == ADC_PERIPH_1) {
  45. ADC->POWERDOWN_RESET_b.POWERDOWN_ADC1 = TRUE;
  46. ADC->POWERDOWN_RESET_b.RESET_ADC1 = TRUE;
  47. udelay(8000);
  48. if (enable) {
  49. ADC->POWERDOWN_RESET_b.POWERDOWN_ADC1 = FALSE;
  50. ADC->POWERDOWN_RESET_b.RESET_ADC1 = FALSE;
  51. udelay(8000);
  52. }
  53. } else {
  54. ADC->POWERDOWN_RESET_b.POWERDOWN_ADC2 = TRUE;
  55. ADC->POWERDOWN_RESET_b.RESET_ADC2 = TRUE;
  56. udelay(8000);
  57. if (enable) {
  58. ADC->POWERDOWN_RESET_b.POWERDOWN_ADC2 = FALSE;
  59. ADC->POWERDOWN_RESET_b.RESET_ADC2 = FALSE;
  60. udelay(8000);
  61. }
  62. }
  63. }
  64. void ADC_Init(ADC_InitTypeDef* init) {
  65. assert_param(init);
  66. assert_param(IS_ADC_PHASE_CTRL(init->ADC_PhaseCtrl));
  67. assert_param(IS_ADC_VSEN(init->ADC_VsenSelection));
  68. SOFT_RESET->SOFTRST_b.ADC_n = 0;
  69. SOFT_RESET->SOFTRST_b.ADC_n = 1;
  70. ADC->CFG0_b.PHASE_CTRL = init->ADC_PhaseCtrl;
  71. ADC->CFG0_b.VSEN = init->ADC_VsenSelection;
  72. }
  73. void ADC_Enable(uint8_t adc, BOOL enable) {
  74. assert_param(IS_ADC_ALL_PERIPH(adc));
  75. adc_Reset(adc, enable);
  76. }
  77. void ADC_EnableInt(uint32_t Int, BOOL enable) {
  78. assert_param(IS_ADC_INT(Int));
  79. if (enable) {
  80. ADC->INT_MASK &= ~Int;
  81. } else {
  82. ADC->INT_MASK |= Int;
  83. }
  84. }
  85. BOOL ADC_GetIntStatus(uint32_t Int) {
  86. assert_param(IS_ADC_INT(Int));
  87. if (0 != (ADC->INT_STATUS & Int)) {
  88. return TRUE;
  89. }
  90. return FALSE;
  91. }
  92. void ADC_ClearInt(uint32_t Int) {
  93. assert_param(IS_ADC_INT(Int));
  94. ADC->INT_STATUS = Int;
  95. }
  96. BOOL ADC_StartConversion(uint8_t adc, uint8_t convMode, uint32_t channel) {
  97. assert_param(IS_ADC_ALL_PERIPH(adc));
  98. assert_param(IS_ADC_CONVERSION(convMode));
  99. if (adc == ADC_PERIPH_1) {
  100. assert_param(IS_ADC1_CHANNEL(channel));
  101. if (ADC->BUSY_b.ADC1_BUSY) {
  102. return FALSE;
  103. }
  104. if (adc_IsMultiChannel(channel)) {
  105. ADC->CFG_ADC1_b.SYSTEM_MODE = ADC_SYSTEM_MODE_SINGLE_CONV;
  106. ADC->CFG_ADC1_b.MULTI_CHANNEL_BIT = channel;
  107. ADC->CFG_ADC1_b.MULTI_CHANNEL_CONTINUE_SCAN =
  108. (convMode == ADC_SYSTEM_MODE_CONTINUOUS_CONV) ? 1 : 0;
  109. } else {
  110. ADC->CFG_ADC1_b.SYSTEM_MODE = convMode;
  111. if (convMode == ADC_SYSTEM_MODE_CONTINUOUS_CONV) {
  112. ADC->CFG_ADC1_b.CHANNEL_SEL = adc_GetChannel(channel);
  113. } else {
  114. ADC->CFG_ADC1_b.MULTI_CHANNEL_BIT = channel;
  115. ADC->CFG_ADC1_b.MULTI_CHANNEL_CONTINUE_SCAN = 0;
  116. }
  117. }
  118. ADC->ADC1_START_b.EN = TRUE;
  119. } else {
  120. assert_param(IS_ADC2_CHANNEL(channel));
  121. if (ADC->BUSY_b.ADC2_BUSY) {
  122. return FALSE;
  123. }
  124. if (adc_IsMultiChannel(channel)) {
  125. ADC->CFG_ADC2_b.SYSTEM_MODE = ADC_SYSTEM_MODE_SINGLE_CONV;
  126. ADC->CFG_ADC2_b.MULTI_CHANNEL_BIT = channel;
  127. ADC->CFG_ADC2_b.MULTI_CHANNEL_CONTINUE_SCAN =
  128. (convMode == ADC_SYSTEM_MODE_CONTINUOUS_CONV) ? 1 : 0;
  129. } else {
  130. ADC->CFG_ADC2_b.SYSTEM_MODE = convMode;
  131. if (convMode == ADC_SYSTEM_MODE_CONTINUOUS_CONV) {
  132. ADC->CFG_ADC2_b.CHANNEL_SEL = adc_GetChannel(channel);
  133. } else {
  134. ADC->CFG_ADC2_b.MULTI_CHANNEL_BIT = channel;
  135. ADC->CFG_ADC2_b.MULTI_CHANNEL_CONTINUE_SCAN = 0;
  136. }
  137. }
  138. ADC->ADC2_START_b.EN = TRUE;
  139. }
  140. return TRUE;
  141. }
  142. BOOL ADC_StartCalibration(uint8_t adc, uint8_t calibration) {
  143. assert_param(IS_ADC_ALL_PERIPH(adc));
  144. assert_param(IS_ADC_CALIBRATION(calibration));
  145. if (adc == ADC_PERIPH_1) {
  146. if (ADC->BUSY_b.ADC1_BUSY) {
  147. return FALSE;
  148. }
  149. ADC->CFG_ADC1_b.SYSTEM_MODE = calibration;
  150. ADC->ADC1_START_b.EN = TRUE;
  151. } else {
  152. if (ADC->BUSY_b.ADC2_BUSY) {
  153. return FALSE;
  154. }
  155. ADC->CFG_ADC2_b.SYSTEM_MODE = calibration;
  156. ADC->ADC2_START_b.EN = TRUE;
  157. }
  158. return TRUE;
  159. }
  160. void ADC_Stop(uint8_t adc) {
  161. assert_param(IS_ADC_ALL_PERIPH(adc));
  162. if (adc == ADC_PERIPH_1) {
  163. if (IS_ADC_CONVERSION(ADC->CFG_ADC1_b.SYSTEM_MODE)) {
  164. ADC->ADC1_STOP_b.EN = TRUE;
  165. }
  166. while (ADC->BUSY_b.ADC1_BUSY) ;
  167. ADC->ADC1_FIFO_CLEAR_b.CLEAR = TRUE;
  168. //udelay(1000);
  169. ADC->ADC1_FIFO_CLEAR_b.CLEAR = FALSE;
  170. } else {
  171. if (IS_ADC_CONVERSION(ADC->CFG_ADC2_b.SYSTEM_MODE)) {
  172. ADC->ADC2_STOP_b.EN = TRUE;
  173. }
  174. while (ADC->BUSY_b.ADC2_BUSY) ;
  175. ADC->ADC2_FIFO_CLEAR_b.CLEAR = TRUE;
  176. //udelay(1000);
  177. ADC->ADC2_FIFO_CLEAR_b.CLEAR = FALSE;
  178. }
  179. }
  180. BOOL ADC_IsBusy(uint8_t adc) {
  181. assert_param(IS_ADC_ALL_PERIPH(adc));
  182. if (adc == ADC_PERIPH_1) {
  183. if (ADC->BUSY_b.ADC1_BUSY) {
  184. return TRUE;
  185. }
  186. } else {
  187. if (ADC->BUSY_b.ADC2_BUSY) {
  188. return TRUE;
  189. }
  190. }
  191. return FALSE;
  192. }
  193. /* return value is actual read data size */
  194. uint8_t ADC_Read(uint8_t adc, uint8_t size, ADC_Data* data) {
  195. uint8_t count = 0;
  196. uint8_t sysMode;
  197. uint32_t tmp = 0;
  198. assert_param(IS_ADC_ALL_PERIPH(adc));
  199. assert_param(data);
  200. if (adc == ADC_PERIPH_1) {
  201. sysMode = ADC->CFG_ADC1_b.SYSTEM_MODE;
  202. } else {
  203. sysMode = ADC->CFG_ADC2_b.SYSTEM_MODE;
  204. }
  205. if ((sysMode == ADC_SYSTEM_MODE_SINGLE_CONV) ||
  206. (sysMode == ADC_SYSTEM_MODE_CONTINUOUS_CONV)) {
  207. while (count < size) {
  208. if (adc == ADC_PERIPH_1) {
  209. if (ADC->STATUS_b.ADC1_READ_EMPTY) {
  210. break;
  211. }
  212. tmp = ADC->ADC1_FIFO_READ;
  213. (data + count)->channel = 1 << ((tmp&0xf000) >> 12);
  214. (data + count++)->data = (tmp & 0xfff);
  215. } else {
  216. if (ADC->STATUS_b.ADC2_READ_EMPTY) {
  217. break;
  218. }
  219. tmp = ADC->ADC2_FIFO_READ;
  220. (data + count)->channel = 1 << ((tmp&0xf000) >> 12);
  221. (data + count++)->data = (tmp & 0xfff);
  222. }
  223. }
  224. } else if (sysMode == ADC_CALIBRATION_OFFSET) {
  225. if (adc == ADC_PERIPH_1) {
  226. if (!ADC->BUSY_b.ADC1_BUSY) {
  227. (data + count)->channel = ADC_CHANNEL_CALIBRATION;
  228. (data + count++)->data = ADC->ADC1_OUT_OFFSET_CALIBRATION;
  229. }
  230. } else {
  231. if (!ADC->BUSY_b.ADC2_BUSY) {
  232. (data + count)->channel = ADC_CHANNEL_CALIBRATION;
  233. (data + count++)->data = ADC->ADC2_OUT_OFFSET_CALIBRATION;
  234. }
  235. }
  236. } else if (sysMode == ADC_CALIBRATION_NEGTIVE_GAIN) {
  237. if (adc == ADC_PERIPH_1) {
  238. if (!ADC->BUSY_b.ADC1_BUSY) {
  239. (data + count)->channel = ADC_CHANNEL_CALIBRATION;
  240. (data + count++)->data = ADC->ADC1_OUT_NEGTIVE_GAIN_CALIBRATION;
  241. }
  242. } else {
  243. if (!ADC->BUSY_b.ADC2_BUSY) {
  244. (data + count)->channel = ADC_CHANNEL_CALIBRATION;
  245. (data + count++)->data = ADC->ADC2_OUT_NEGTIVE_GAIN_CALIBRATION;
  246. }
  247. }
  248. } else {
  249. if (adc == ADC_PERIPH_1) {
  250. if (!ADC->BUSY_b.ADC1_BUSY) {
  251. (data + count)->channel = ADC_CHANNEL_CALIBRATION;
  252. (data + count++)->data = ADC->ADC1_OUT_POSITIVE_GAIN_CALIBRATION;
  253. }
  254. } else {
  255. if (!ADC->BUSY_b.ADC2_BUSY) {
  256. (data + count)->channel = ADC_CHANNEL_CALIBRATION;
  257. (data + count++)->data = ADC->ADC2_OUT_POSITIVE_GAIN_CALIBRATION;
  258. }
  259. }
  260. }
  261. return count;
  262. }