adc.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /* Copyright 2023 Dual Tachyon
  2. * https://github.com/DualTachyon
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "ARMCM0.h"
  17. #include "adc.h"
  18. #include "bsp/dp32g030/irq.h"
  19. #include "bsp/dp32g030/saradc.h"
  20. #include "bsp/dp32g030/syscon.h"
  21. uint8_t ADC_GetChannelNumber(ADC_CH_MASK Mask)
  22. {
  23. if (Mask & ADC_CH15) return 15U;
  24. if (Mask & ADC_CH14) return 14U;
  25. if (Mask & ADC_CH13) return 13U;
  26. if (Mask & ADC_CH12) return 12U;
  27. if (Mask & ADC_CH11) return 11U;
  28. if (Mask & ADC_CH10) return 10U;
  29. if (Mask & ADC_CH9) return 9U;
  30. if (Mask & ADC_CH8) return 8U;
  31. if (Mask & ADC_CH7) return 7U;
  32. if (Mask & ADC_CH6) return 6U;
  33. if (Mask & ADC_CH5) return 5U;
  34. if (Mask & ADC_CH4) return 4U;
  35. if (Mask & ADC_CH3) return 3U;
  36. if (Mask & ADC_CH2) return 2U;
  37. if (Mask & ADC_CH1) return 1U;
  38. if (Mask & ADC_CH0) return 0U;
  39. return 0U;
  40. }
  41. void ADC_Disable(void)
  42. {
  43. SARADC_CFG = (SARADC_CFG & ~SARADC_CFG_ADC_EN_MASK) | SARADC_CFG_ADC_EN_BITS_DISABLE;
  44. }
  45. void ADC_Enable(void)
  46. {
  47. SARADC_CFG = (SARADC_CFG & ~SARADC_CFG_ADC_EN_MASK) | SARADC_CFG_ADC_EN_BITS_ENABLE;
  48. }
  49. void ADC_SoftReset(void)
  50. {
  51. SARADC_START = (SARADC_START & ~SARADC_START_SOFT_RESET_MASK) | SARADC_START_SOFT_RESET_BITS_ASSERT;
  52. SARADC_START = (SARADC_START & ~SARADC_START_SOFT_RESET_MASK) | SARADC_START_SOFT_RESET_BITS_DEASSERT;
  53. }
  54. // The firmware thinks W_SARADC_SMPL_CLK_SEL is at [8:7] but the TRM says it's at [10:9]
  55. #define FW_R_SARADC_SMPL_SHIFT 7
  56. #define FW_R_SARADC_SMPL_MASK (3U << FW_R_SARADC_SMPL_SHIFT)
  57. uint32_t ADC_GetClockConfig(void)
  58. {
  59. uint32_t Value;
  60. Value = SYSCON_CLK_SEL;
  61. Value = 0
  62. | (Value & ~(SYSCON_CLK_SEL_R_PLL_MASK | FW_R_SARADC_SMPL_MASK))
  63. | (((Value & SYSCON_CLK_SEL_R_PLL_MASK) >> SYSCON_CLK_SEL_R_PLL_SHIFT) << SYSCON_CLK_SEL_W_PLL_SHIFT)
  64. | (((Value & FW_R_SARADC_SMPL_MASK) >> FW_R_SARADC_SMPL_SHIFT) << SYSCON_CLK_SEL_W_SARADC_SMPL_SHIFT)
  65. ;
  66. return Value;
  67. }
  68. void ADC_Configure(ADC_Config_t *pAdc)
  69. {
  70. SYSCON_DEV_CLK_GATE = (SYSCON_DEV_CLK_GATE & ~SYSCON_DEV_CLK_GATE_SARADC_MASK) | SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE;
  71. ADC_Disable();
  72. SYSCON_CLK_SEL = (ADC_GetClockConfig() & ~SYSCON_CLK_SEL_W_SARADC_SMPL_MASK) | ((pAdc->CLK_SEL << SYSCON_CLK_SEL_W_SARADC_SMPL_SHIFT) & SYSCON_CLK_SEL_W_SARADC_SMPL_MASK);
  73. SARADC_CFG = 0
  74. | (SARADC_CFG & ~(0
  75. | SARADC_CFG_CH_SEL_MASK
  76. | SARADC_CFG_AVG_MASK
  77. | SARADC_CFG_CONT_MASK
  78. | SARADC_CFG_SMPL_SETUP_MASK
  79. | SARADC_CFG_MEM_MODE_MASK
  80. | SARADC_CFG_SMPL_CLK_MASK
  81. | SARADC_CFG_SMPL_WIN_MASK
  82. | SARADC_CFG_ADC_TRIG_MASK
  83. | SARADC_CFG_DMA_EN_MASK
  84. ))
  85. | ((pAdc->CH_SEL << SARADC_CFG_CH_SEL_SHIFT) & SARADC_CFG_CH_SEL_MASK)
  86. | ((pAdc->AVG << SARADC_CFG_AVG_SHIFT) & SARADC_CFG_AVG_MASK)
  87. | ((pAdc->CONT << SARADC_CFG_CONT_SHIFT) & SARADC_CFG_CONT_MASK)
  88. | ((pAdc->SMPL_SETUP << SARADC_CFG_SMPL_SETUP_SHIFT) & SARADC_CFG_SMPL_SETUP_MASK)
  89. | ((pAdc->MEM_MODE << SARADC_CFG_MEM_MODE_SHIFT) & SARADC_CFG_MEM_MODE_MASK)
  90. | ((pAdc->SMPL_CLK << SARADC_CFG_SMPL_CLK_SHIFT) & SARADC_CFG_SMPL_CLK_MASK)
  91. | ((pAdc->SMPL_WIN << SARADC_CFG_SMPL_WIN_SHIFT) & SARADC_CFG_SMPL_WIN_MASK)
  92. | ((pAdc->ADC_TRIG << SARADC_CFG_ADC_TRIG_SHIFT) & SARADC_CFG_ADC_TRIG_MASK)
  93. | ((pAdc->DMA_EN << SARADC_CFG_DMA_EN_SHIFT) & SARADC_CFG_DMA_EN_MASK)
  94. ;
  95. SARADC_EXTTRIG_SEL = pAdc->EXTTRIG_SEL;
  96. if (pAdc->CALIB_OFFSET_VALID) {
  97. SARADC_CALIB_OFFSET = (SARADC_CALIB_OFFSET & ~SARADC_CALIB_OFFSET_VALID_MASK) | SARADC_CALIB_OFFSET_VALID_BITS_YES;
  98. } else {
  99. SARADC_CALIB_OFFSET = (SARADC_CALIB_OFFSET & ~SARADC_CALIB_OFFSET_VALID_MASK) | SARADC_CALIB_OFFSET_VALID_BITS_NO;
  100. }
  101. if (pAdc->CALIB_KD_VALID) {
  102. SARADC_CALIB_KD = (SARADC_CALIB_KD & ~SARADC_CALIB_KD_VALID_MASK) | SARADC_CALIB_KD_VALID_BITS_YES;
  103. } else {
  104. SARADC_CALIB_KD = (SARADC_CALIB_KD & ~SARADC_CALIB_KD_VALID_MASK) | SARADC_CALIB_KD_VALID_BITS_NO;
  105. }
  106. SARADC_IF = 0xFFFFFFFF;
  107. SARADC_IE = 0
  108. | (SARADC_IE & ~(0
  109. | SARADC_IE_CHx_EOC_MASK
  110. | SARADC_IE_FIFO_FULL_MASK
  111. | SARADC_IE_FIFO_HFULL_MASK
  112. ))
  113. | ((pAdc->IE_CHx_EOC << SARADC_IE_CHx_EOC_SHIFT) & SARADC_IE_CHx_EOC_MASK)
  114. | ((pAdc->IE_FIFO_FULL << SARADC_IE_FIFO_FULL_SHIFT) & SARADC_IE_FIFO_FULL_MASK)
  115. | ((pAdc->IE_FIFO_HFULL << SARADC_IE_FIFO_HFULL_SHIFT) & SARADC_IE_FIFO_HFULL_MASK)
  116. ;
  117. if (SARADC_IE == 0) {
  118. NVIC_DisableIRQ((IRQn_Type)DP32_SARADC_IRQn);
  119. } else {
  120. NVIC_EnableIRQ((IRQn_Type)DP32_SARADC_IRQn);
  121. }
  122. }
  123. void ADC_Start(void)
  124. {
  125. SARADC_START = (SARADC_START & ~SARADC_START_START_MASK) | SARADC_START_START_BITS_ENABLE;
  126. }
  127. bool ADC_CheckEndOfConversion(ADC_CH_MASK Mask)
  128. {
  129. volatile ADC_Channel_t *pChannels = (volatile ADC_Channel_t *)&SARADC_CH0;
  130. uint8_t Channel = ADC_GetChannelNumber(Mask);
  131. return (pChannels[Channel].STAT & ADC_CHx_STAT_EOC_MASK) >> ADC_CHx_STAT_EOC_SHIFT;
  132. }
  133. uint16_t ADC_GetValue(ADC_CH_MASK Mask)
  134. {
  135. volatile ADC_Channel_t *pChannels = (volatile ADC_Channel_t *)&SARADC_CH0;
  136. uint8_t Channel = ADC_GetChannelNumber(Mask);
  137. SARADC_IF = 1 << Channel; // TODO: Or just use 'Mask'
  138. return (pChannels[Channel].DATA & ADC_CHx_DATA_DATA_MASK) >> ADC_CHx_DATA_DATA_SHIFT;
  139. }