adc.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #include "libs/task.h"
  2. #include "hal/adc.h"
  3. static ADC_HandleTypeDef hadc1;
  4. void HAL_ADC1_Init(void){
  5. ADC_InjectionConfTypeDef sConfigInjected = {0};
  6. ADC_ChannelConfTypeDef sConfig = {0};
  7. hadc1.Instance = ADC1;
  8. hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
  9. hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  10. hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  11. hadc1.Init.ContinuousConvMode = DISABLE;
  12. hadc1.Init.DiscontinuousConvMode = DISABLE;
  13. hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  14. hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  15. hadc1.Init.DataAlign = ADC_DATAALIGN_LEFT;
  16. hadc1.Init.NbrOfConversion = 2;
  17. hadc1.Init.DMAContinuousRequests = DISABLE;
  18. hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  19. hadc1.Init.LowPowerAutoWait = DISABLE;
  20. hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  21. if (HAL_ADC_Init(&hadc1) != HAL_OK)
  22. {
  23. Error_Handler();
  24. }
  25. /** Configure Injected Channel
  26. */
  27. sConfigInjected.InjectedChannel = ADC_CHANNEL_1;
  28. sConfigInjected.InjectedRank = ADC_INJECTED_RANK_1;
  29. sConfigInjected.InjectedSingleDiff = ADC_SINGLE_ENDED;
  30. sConfigInjected.InjectedNbrOfConversion = 3;
  31. sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_7CYCLES_5;
  32. sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONV_EDGE_RISING;
  33. sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T1_TRGO;
  34. sConfigInjected.AutoInjectedConv = DISABLE;
  35. sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
  36. sConfigInjected.QueueInjectedContext = ENABLE;
  37. sConfigInjected.InjectedOffset = 0;
  38. sConfigInjected.InjectedOffsetNumber = ADC_OFFSET_NONE;
  39. if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK)
  40. {
  41. Error_Handler();
  42. }
  43. /** Configure Injected Channel
  44. */
  45. sConfigInjected.InjectedChannel = ADC_CHANNEL_7;
  46. sConfigInjected.InjectedRank = ADC_INJECTED_RANK_2;
  47. if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK)
  48. {
  49. Error_Handler();
  50. }
  51. /** Configure Injected Channel
  52. */
  53. sConfigInjected.InjectedChannel = ADC_CHANNEL_6;
  54. sConfigInjected.InjectedRank = ADC_INJECTED_RANK_3;
  55. if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK)
  56. {
  57. Error_Handler();
  58. }
  59. /** Configure Regular Channel
  60. */
  61. sConfig.Channel = ADC_CHANNEL_2;
  62. sConfig.Rank = ADC_REGULAR_RANK_1;
  63. sConfig.SingleDiff = ADC_SINGLE_ENDED;
  64. sConfig.SamplingTime = ADC_SAMPLETIME_61CYCLES_5;
  65. sConfig.OffsetNumber = ADC_OFFSET_NONE;
  66. sConfig.Offset = 0;
  67. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  68. {
  69. Error_Handler();
  70. }
  71. /** Configure Regular Channel
  72. */
  73. sConfig.Channel = ADC_CHANNEL_8;
  74. sConfig.Rank = ADC_REGULAR_RANK_2;
  75. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  76. {
  77. Error_Handler();
  78. }
  79. }
  80. void HAL_ADC1_Enable(void) {
  81. ADC_TypeDef * ADCx = hadc1.Instance;
  82. /* disable IT and flags in case of LL driver usage
  83. * workaround for unwanted interrupt enabling done by LL driver */
  84. LL_ADC_DisableIT_EOC( ADCx );
  85. LL_ADC_ClearFlag_EOC( ADCx );
  86. LL_ADC_DisableIT_JEOC( ADCx );
  87. LL_ADC_ClearFlag_JEOC( ADCx );
  88. if (LL_ADC_IsEnabled (ADCx) == 0)
  89. {
  90. if ( LL_ADC_IsInternalRegulatorEnabled(ADCx) == 0u)
  91. {
  92. /* Enable ADC internal voltage regulator */
  93. LL_ADC_EnableInternalRegulator(ADCx);
  94. /* Wait for Regulator Startup time */
  95. /* Note: Variable divided by 2 to compensate partially */
  96. /* CPU processing cycles, scaling in us split to not */
  97. /* exceed 32 bits register capacity and handle low frequency. */
  98. volatile uint32_t wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US / 10UL) * (SystemCoreClock / (100000UL * 2UL)));
  99. while(wait_loop_index != 0UL)
  100. {
  101. wait_loop_index--;
  102. }
  103. }
  104. LL_ADC_StartCalibration( ADCx, LL_ADC_SINGLE_ENDED );
  105. while ( LL_ADC_IsCalibrationOnGoing( ADCx) == 1u)
  106. {}
  107. /* ADC Enable (must be done after calibration) */
  108. /* ADC5-140924: Enabling the ADC by setting ADEN bit soon after polling ADCAL=0
  109. * following a calibration phase, could have no effect on ADC
  110. * within certain AHB/ADC clock ratio.
  111. */
  112. while ( LL_ADC_IsActiveFlag_ADRDY( ADCx ) == 0u)
  113. {
  114. LL_ADC_Enable( ADCx );
  115. }
  116. /* Clear JSQR from CubeMX setting to avoid not wanting conversion*/
  117. //LL_ADC_INJ_StartConversion( ADCx );
  118. //LL_ADC_INJ_StopConversion(ADCx);
  119. /* TODO: check if not already done by MX */
  120. LL_ADC_INJ_SetQueueMode( ADCx, LL_ADC_INJ_QUEUE_2CONTEXTS_END_EMPTY );
  121. /* Only the Interrupt of the first ADC is enabled.
  122. * As Both ADCs are fired by HW at the same moment
  123. * It is safe to consider that both conversion are ready at the same time*/
  124. LL_ADC_ClearFlag_JEOS( ADCx );
  125. LL_ADC_EnableIT_JEOS( ADCx );
  126. }
  127. HAL_NVIC_EnableIRQ(ADC1_IRQn);
  128. //LL_ADC_INJ_StartConversion( ADCx );
  129. }
  130. void HAL_ADC1_InJ_StartConvert(void) {
  131. ADC_TypeDef * ADCx = hadc1.Instance;
  132. while(LL_ADC_INJ_IsConversionOngoing( ADCx ) == 0) {
  133. LL_ADC_INJ_StartConversion( ADCx );
  134. }
  135. }
  136. void HAL_ADC1_ChanConfig(u32 channel) {
  137. if (LL_ADC_IsEnabled(hadc1.Instance) == 0 )
  138. {
  139. LL_ADC_DisableIT_EOC(hadc1.Instance);
  140. LL_ADC_ClearFlag_EOC(hadc1.Instance);
  141. LL_ADC_DisableIT_JEOC(hadc1.Instance);
  142. LL_ADC_ClearFlag_JEOC(hadc1.Instance);
  143. LL_ADC_StartCalibration( hadc1.Instance, LL_ADC_SINGLE_ENDED );
  144. while ( LL_ADC_IsCalibrationOnGoing( hadc1.Instance ) )
  145. { }
  146. LL_ADC_Enable( hadc1.Instance );
  147. }
  148. /* reset regular conversion sequencer length set by cubeMX */
  149. LL_ADC_REG_SetSequencerLength( hadc1.Instance, LL_ADC_REG_SEQ_SCAN_DISABLE );
  150. /* configure the sampling time (should already be configured by for non user conversions)*/
  151. LL_ADC_SetChannelSamplingTime ( hadc1.Instance, __LL_ADC_DECIMAL_NB_TO_CHANNEL(channel) ,ADC_SAMPLETIME_61CYCLES_5);
  152. }
  153. u16 HAL_ADC1_ReadValue(u32 channel)
  154. {
  155. u16 retVal;
  156. LL_ADC_REG_SetSequencerRanks( hadc1.Instance,
  157. LL_ADC_REG_RANK_1,
  158. __LL_ADC_DECIMAL_NB_TO_CHANNEL( channel ) );
  159. LL_ADC_REG_ReadConversionData12(hadc1.Instance);
  160. LL_ADC_REG_StartConversion(hadc1.Instance);
  161. /* Wait until end of regular conversion */
  162. u64 StartTime = get_mseconds();
  163. while ( LL_ADC_IsActiveFlag_EOC(hadc1.Instance) == 0u ) {
  164. if (get_mseconds() - StartTime >= 1) {
  165. LL_ADC_REG_StartConversion(hadc1.Instance);
  166. StartTime = get_mseconds();
  167. }
  168. }
  169. retVal = LL_ADC_REG_ReadConversionData12(hadc1.Instance);
  170. return retVal;
  171. }