/stm32/cores/arduino/adc.c

https://github.com/avikde/koduino · C · 207 lines · 92 code · 38 blank · 77 comment · 14 complexity · 6a78c7f188353dae4d4f835051d494e1 MD5 · raw file

  1. /**
  2. * @authors Avik De <avikde@gmail.com>
  3. This file is part of koduino <https://github.com/avikde/koduino>
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation, either
  7. version 3 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with this library; if not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include "adc.h"
  18. #include "pins.h"
  19. ////////////////////////////////////////////////////////////////////////////////////
  20. #if defined(SERIES_STM32F37x) || defined(SERIES_STM32F10x)
  21. uint8_t ADC_SAMPLE_TIME = ADC_SampleTime_13Cycles5;
  22. #elif defined(SERIES_STM32F4xx)
  23. uint8_t ADC_SAMPLE_TIME = ADC_SampleTime_15Cycles;
  24. #elif defined(SERIES_STM32F30x)
  25. uint8_t ADC_SAMPLE_TIME = ADC_SampleTime_19Cycles5;
  26. #endif
  27. #define ADC_TIMEOUT 50
  28. void analogReadSampleTime(uint8_t sampleTime) {
  29. ADC_SAMPLE_TIME = sampleTime;
  30. }
  31. void adcCommonInit() {
  32. #if defined(SERIES_STM32F4xx)
  33. ADC_CommonInitTypeDef ADC_CommonInitStructure;
  34. ADC_DeInit();
  35. ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  36. ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
  37. ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
  38. ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
  39. ADC_CommonInit(&ADC_CommonInitStructure);
  40. #elif defined(SERIES_STM32F30x)
  41. ADC_CommonInitTypeDef ADC_CommonInitStructure;
  42. ADC_CommonStructInit(&ADC_CommonInitStructure);
  43. ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  44. ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
  45. ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0x0;
  46. ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
  47. #if defined(STM32F303xC)
  48. ADC_CommonInit(ADC2, &ADC_CommonInitStructure);
  49. #endif
  50. #endif
  51. }
  52. void adcInit(ADC_TypeDef *ADCx) {
  53. #if defined(SERIES_STM32F37x) || defined(SERIES_STM32F30x)
  54. // was causing problems if initing multiple ADCs
  55. // ADC_DeInit(ADCx);
  56. #endif
  57. ADC_InitTypeDef ADC_InitStructure;
  58. ADC_StructInit(&ADC_InitStructure);
  59. // Common
  60. ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
  61. // Data align right
  62. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  63. // Continuous conv
  64. #if defined(SERIES_STM32F37x) || defined(SERIES_STM32F10x) || defined(SERIES_STM32F4xx)
  65. ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  66. #endif
  67. // Resolution
  68. #if defined(SERIES_STM32F30x)
  69. ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  70. #endif
  71. // Configure for 1 channel
  72. #if defined(SERIES_STM32F37x) || defined(SERIES_STM32F10x)
  73. ADC_InitStructure.ADC_NbrOfChannel = 1;
  74. #elif defined(SERIES_STM32F30x)
  75. ADC_InitStructure.ADC_NbrOfRegChannel = 1;
  76. #else
  77. ADC_InitStructure.ADC_NbrOfConversion = 1;
  78. #endif
  79. // No external trigger
  80. #if defined(SERIES_STM32F37x) || defined(SERIES_STM32F10x)
  81. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  82. #elif defined(SERIES_STM32F30x)
  83. ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
  84. // Immaterial
  85. ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;
  86. #endif
  87. // Independent
  88. // #if defined(SERIES_STM32F37x)
  89. // ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  90. // #endif
  91. // other options
  92. #if defined(SERIES_STM32F30x)
  93. ADC_InitStructure.ADC_OverrunMode = DISABLE;
  94. ADC_InitStructure.ADC_AutoInjMode = DISABLE;
  95. #endif
  96. ADC_Init(ADCx, &ADC_InitStructure);
  97. ADC_Cmd(ADCx, ENABLE);
  98. #if defined(SERIES_STM32F37x)
  99. ADC_ResetCalibration(ADCx);
  100. while(ADC_GetResetCalibrationStatus(ADCx));
  101. ADC_StartCalibration(ADCx);
  102. while(ADC_GetCalibrationStatus(ADCx));
  103. #endif
  104. }
  105. uint16_t analogRead(uint8_t pin) {
  106. // Check ioConfig and set?
  107. // pinMode(pin, INPUT_ANALOG);
  108. // which ADC? mostly use ADC1
  109. ADC_TypeDef *ADCx = ADC1;
  110. // special cases:
  111. #if defined(STM32F303xC)
  112. // PC4 and PC5 on ADC2
  113. if ((PIN_MAP[pin].port==GPIOC && PIN_MAP[pin].pin==4) || (PIN_MAP[pin].port==GPIOC && PIN_MAP[pin].pin==5))
  114. ADCx = ADC2;
  115. #endif
  116. ADC_RegularChannelConfig(ADCx, PIN_MAP[pin].adcChannel, 1, ADC_SAMPLE_TIME);
  117. // Start the conversion
  118. #if defined(SERIES_STM32F10x)
  119. ADC_SoftwareStartConvCmd(ADCx, ENABLE);
  120. #elif defined(SERIES_STM32F30x)
  121. ADC_StartConversion(ADCx);
  122. #else
  123. ADC_SoftwareStartConv(ADCx);
  124. #endif
  125. // Wait until conversion completion
  126. while(ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) == RESET);
  127. // Get the conversion value
  128. return ADC_GetConversionValue(ADCx);
  129. }
  130. // #if defined(SERIES_STM32F4xx)
  131. // #define MAX_ADCS 3
  132. // uint16_t syncReadBuffer[MAX_ADCS];
  133. // const uint16_t *analogSyncRead(uint8_t pin1, uint8_t pin2, uint8_t pin3) {
  134. // ADC_RegularChannelConfig(ADC1, PIN_MAP[pin1].adcChannel, 1, ADC_SAMPLE_TIME);
  135. // ADC_RegularChannelConfig(ADC2, PIN_MAP[pin2].adcChannel, 1, ADC_SAMPLE_TIME);
  136. // ADC_RegularChannelConfig(ADC3, PIN_MAP[pin3].adcChannel, 1, ADC_SAMPLE_TIME);
  137. // ADC_SoftwareStartConv(ADC1);
  138. // ADC_SoftwareStartConv(ADC2);
  139. // ADC_SoftwareStartConv(ADC3);
  140. // while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
  141. // while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET);
  142. // while(ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC) == RESET);
  143. // // Get the conversion value
  144. // syncReadBuffer[0] = ADC_GetConversionValue(ADC1);
  145. // syncReadBuffer[1] = ADC_GetConversionValue(ADC2);
  146. // syncReadBuffer[2] = ADC_GetConversionValue(ADC3);
  147. // return (const uint16_t *)&syncReadBuffer;
  148. // }
  149. // const uint16_t *analogSyncRead2(uint8_t pin1, uint8_t pin2) {
  150. // static int timeout;
  151. // ADC_RegularChannelConfig(ADC1, PIN_MAP[pin1].adcChannel, 1, ADC_SAMPLE_TIME);
  152. // ADC_RegularChannelConfig(ADC2, PIN_MAP[pin2].adcChannel, 1, ADC_SAMPLE_TIME);
  153. // ADC_SoftwareStartConv(ADC1);
  154. // ADC_SoftwareStartConv(ADC2);
  155. // // Need a timeout
  156. // timeout = ADC_TIMEOUT;
  157. // while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET && ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET)
  158. // // return previous values
  159. // if ((timeout--) == 0) return (const uint16_t *)&syncReadBuffer;
  160. // // Didn't time out; get the conversion value
  161. // syncReadBuffer[0] = ADC_GetConversionValue(ADC1);
  162. // syncReadBuffer[1] = ADC_GetConversionValue(ADC2);
  163. // return (const uint16_t *)&syncReadBuffer;
  164. // }
  165. // #endif