adc.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2013, 2014 Damien P. George
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include "py/runtime.h"
  29. #include "py/binary.h"
  30. #include "py/mphal.h"
  31. #include "adc.h"
  32. #include "pin.h"
  33. #include "timer.h"
  34. #if MICROPY_HW_ENABLE_ADC
  35. /// \moduleref pyb
  36. /// \class ADC - analog to digital conversion: read analog values on a pin
  37. ///
  38. /// Usage:
  39. ///
  40. /// adc = pyb.ADC(pin) # create an analog object from a pin
  41. /// val = adc.read() # read an analog value
  42. ///
  43. /// adc = pyb.ADCAll(resolution) # creale an ADCAll object
  44. /// val = adc.read_channel(channel) # read the given channel
  45. /// val = adc.read_core_temp() # read MCU temperature
  46. /// val = adc.read_core_vbat() # read MCU VBAT
  47. /// val = adc.read_core_vref() # read MCU VREF
  48. /* ADC defintions */
  49. #if defined(STM32H7)
  50. #define ADCx (ADC3)
  51. #else
  52. #define ADCx (ADC1)
  53. #endif
  54. #define ADCx_CLK_ENABLE __HAL_RCC_ADC1_CLK_ENABLE
  55. #define ADC_NUM_CHANNELS (19)
  56. #if defined(STM32F0)
  57. #define ADC_FIRST_GPIO_CHANNEL (0)
  58. #define ADC_LAST_GPIO_CHANNEL (15)
  59. #define ADC_CAL_ADDRESS (0x1ffff7ba)
  60. #define ADC_CAL1 ((uint16_t*)0x1ffff7b8)
  61. #define ADC_CAL2 ((uint16_t*)0x1ffff7c2)
  62. #elif defined(STM32F4)
  63. #define ADC_FIRST_GPIO_CHANNEL (0)
  64. #define ADC_LAST_GPIO_CHANNEL (15)
  65. #define ADC_CAL_ADDRESS (0x1fff7a2a)
  66. #define ADC_CAL1 ((uint16_t*)(ADC_CAL_ADDRESS + 2))
  67. #define ADC_CAL2 ((uint16_t*)(ADC_CAL_ADDRESS + 4))
  68. #elif defined(STM32F7)
  69. #define ADC_FIRST_GPIO_CHANNEL (0)
  70. #define ADC_LAST_GPIO_CHANNEL (15)
  71. #if defined(STM32F722xx) || defined(STM32F723xx) || \
  72. defined(STM32F732xx) || defined(STM32F733xx)
  73. #define ADC_CAL_ADDRESS (0x1ff07a2a)
  74. #else
  75. #define ADC_CAL_ADDRESS (0x1ff0f44a)
  76. #endif
  77. #define ADC_CAL1 ((uint16_t*)(ADC_CAL_ADDRESS + 2))
  78. #define ADC_CAL2 ((uint16_t*)(ADC_CAL_ADDRESS + 4))
  79. #elif defined(STM32H7)
  80. #define ADC_FIRST_GPIO_CHANNEL (0)
  81. #define ADC_LAST_GPIO_CHANNEL (16)
  82. #define ADC_CAL_ADDRESS (0x1FF1E860)
  83. #define ADC_CAL1 ((uint16_t*)(0x1FF1E820))
  84. #define ADC_CAL2 ((uint16_t*)(0x1FF1E840))
  85. #define ADC_CHANNEL_VBAT ADC_CHANNEL_VBAT_DIV4
  86. #elif defined(STM32L4)
  87. #define ADC_FIRST_GPIO_CHANNEL (1)
  88. #define ADC_LAST_GPIO_CHANNEL (16)
  89. #define ADC_CAL_ADDRESS (0x1fff75aa)
  90. #define ADC_CAL1 ((uint16_t*)(ADC_CAL_ADDRESS - 2))
  91. #define ADC_CAL2 ((uint16_t*)(ADC_CAL_ADDRESS + 0x20))
  92. #else
  93. #error Unsupported processor
  94. #endif
  95. #if defined(STM32F091xC)
  96. #define VBAT_DIV (2)
  97. #elif defined(STM32F405xx) || defined(STM32F415xx) || \
  98. defined(STM32F407xx) || defined(STM32F417xx) || \
  99. defined(STM32F401xC) || defined(STM32F401xE) || \
  100. defined(STM32F411xE)
  101. #define VBAT_DIV (2)
  102. #elif defined(STM32F427xx) || defined(STM32F429xx) || \
  103. defined(STM32F437xx) || defined(STM32F439xx) || \
  104. defined(STM32F722xx) || defined(STM32F723xx) || \
  105. defined(STM32F732xx) || defined(STM32F733xx) || \
  106. defined(STM32F746xx) || defined(STM32F767xx) || \
  107. defined(STM32F769xx) || defined(STM32F446xx)
  108. #define VBAT_DIV (4)
  109. #elif defined(STM32H743xx)
  110. #define VBAT_DIV (4)
  111. #elif defined(STM32L475xx) || defined(STM32L476xx) || \
  112. defined(STM32L496xx)
  113. #define VBAT_DIV (3)
  114. #else
  115. #error Unsupported processor
  116. #endif
  117. // Timeout for waiting for end-of-conversion, in ms
  118. #define EOC_TIMEOUT (10)
  119. /* Core temperature sensor definitions */
  120. #define CORE_TEMP_V25 (943) /* (0.76v/3.3v)*(2^ADC resoultion) */
  121. #define CORE_TEMP_AVG_SLOPE (3) /* (2.5mv/3.3v)*(2^ADC resoultion) */
  122. // scale and calibration values for VBAT and VREF
  123. #define ADC_SCALE (3.3f / 4095)
  124. #define VREFIN_CAL ((uint16_t *)ADC_CAL_ADDRESS)
  125. typedef struct _pyb_obj_adc_t {
  126. mp_obj_base_t base;
  127. mp_obj_t pin_name;
  128. int channel;
  129. ADC_HandleTypeDef handle;
  130. } pyb_obj_adc_t;
  131. // convert user-facing channel number into internal channel number
  132. static inline uint32_t adc_get_internal_channel(uint32_t channel) {
  133. #if defined(STM32F4) || defined(STM32F7)
  134. // on F4 and F7 MCUs we want channel 16 to always be the TEMPSENSOR
  135. // (on some MCUs ADC_CHANNEL_TEMPSENSOR=16, on others it doesn't)
  136. if (channel == 16) {
  137. channel = ADC_CHANNEL_TEMPSENSOR;
  138. }
  139. #endif
  140. return channel;
  141. }
  142. STATIC bool is_adcx_channel(int channel) {
  143. #if defined(STM32F411xE)
  144. // The HAL has an incorrect IS_ADC_CHANNEL macro for the F411 so we check for temp
  145. return IS_ADC_CHANNEL(channel) || channel == ADC_CHANNEL_TEMPSENSOR;
  146. #elif defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7)
  147. return IS_ADC_CHANNEL(channel);
  148. #elif defined(STM32L4)
  149. ADC_HandleTypeDef handle;
  150. handle.Instance = ADCx;
  151. return IS_ADC_CHANNEL(&handle, channel);
  152. #else
  153. #error Unsupported processor
  154. #endif
  155. }
  156. STATIC void adc_wait_for_eoc_or_timeout(int32_t timeout) {
  157. uint32_t tickstart = HAL_GetTick();
  158. #if defined(STM32F4) || defined(STM32F7)
  159. while ((ADCx->SR & ADC_FLAG_EOC) != ADC_FLAG_EOC) {
  160. #elif defined(STM32F0) || defined(STM32H7) || defined(STM32L4)
  161. while (READ_BIT(ADCx->ISR, ADC_FLAG_EOC) != ADC_FLAG_EOC) {
  162. #else
  163. #error Unsupported processor
  164. #endif
  165. if (((HAL_GetTick() - tickstart ) > timeout)) {
  166. break; // timeout
  167. }
  168. }
  169. }
  170. STATIC void adcx_clock_enable(void) {
  171. #if defined(STM32F0) || defined(STM32F4) || defined(STM32F7)
  172. ADCx_CLK_ENABLE();
  173. #elif defined(STM32H7)
  174. __HAL_RCC_ADC3_CLK_ENABLE();
  175. __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP);
  176. #elif defined(STM32L4)
  177. __HAL_RCC_ADC_CLK_ENABLE();
  178. #else
  179. #error Unsupported processor
  180. #endif
  181. }
  182. STATIC void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) {
  183. adcx_clock_enable();
  184. adch->Instance = ADCx;
  185. adch->Init.Resolution = resolution;
  186. adch->Init.ContinuousConvMode = DISABLE;
  187. adch->Init.DiscontinuousConvMode = DISABLE;
  188. #if !defined(STM32F0)
  189. adch->Init.NbrOfDiscConversion = 0;
  190. adch->Init.NbrOfConversion = 1;
  191. #endif
  192. adch->Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  193. adch->Init.ExternalTrigConv = ADC_SOFTWARE_START;
  194. adch->Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  195. #if defined(STM32F0) || defined(STM32F4) || defined(STM32F7)
  196. adch->Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  197. adch->Init.ScanConvMode = DISABLE;
  198. adch->Init.DataAlign = ADC_DATAALIGN_RIGHT;
  199. adch->Init.DMAContinuousRequests = DISABLE;
  200. #elif defined(STM32H7)
  201. adch->Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  202. adch->Init.BoostMode = ENABLE;
  203. adch->Init.ScanConvMode = DISABLE;
  204. adch->Init.LowPowerAutoWait = DISABLE;
  205. adch->Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  206. adch->Init.OversamplingMode = DISABLE;
  207. adch->Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  208. adch->Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
  209. #elif defined(STM32L4)
  210. adch->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  211. adch->Init.ScanConvMode = ADC_SCAN_DISABLE;
  212. adch->Init.LowPowerAutoWait = DISABLE;
  213. adch->Init.Overrun = ADC_OVR_DATA_PRESERVED;
  214. adch->Init.OversamplingMode = DISABLE;
  215. adch->Init.DataAlign = ADC_DATAALIGN_RIGHT;
  216. adch->Init.DMAContinuousRequests = DISABLE;
  217. #else
  218. #error Unsupported processor
  219. #endif
  220. HAL_ADC_Init(adch);
  221. #if defined(STM32H7)
  222. HAL_ADCEx_Calibration_Start(adch, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);
  223. #endif
  224. }
  225. STATIC void adc_init_single(pyb_obj_adc_t *adc_obj) {
  226. if (!is_adcx_channel(adc_obj->channel)) {
  227. return;
  228. }
  229. if (ADC_FIRST_GPIO_CHANNEL <= adc_obj->channel && adc_obj->channel <= ADC_LAST_GPIO_CHANNEL) {
  230. // Channels 0-16 correspond to real pins. Configure the GPIO pin in ADC mode.
  231. const pin_obj_t *pin = pin_adc1[adc_obj->channel];
  232. mp_hal_pin_config(pin, MP_HAL_PIN_MODE_ADC, MP_HAL_PIN_PULL_NONE, 0);
  233. }
  234. adcx_init_periph(&adc_obj->handle, ADC_RESOLUTION_12B);
  235. #if defined(STM32L4)
  236. ADC_MultiModeTypeDef multimode;
  237. multimode.Mode = ADC_MODE_INDEPENDENT;
  238. if (HAL_ADCEx_MultiModeConfigChannel(&adc_obj->handle, &multimode) != HAL_OK)
  239. {
  240. nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Can not set multimode on ADC1 channel: %d", adc_obj->channel));
  241. }
  242. #endif
  243. }
  244. STATIC void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel) {
  245. ADC_ChannelConfTypeDef sConfig;
  246. sConfig.Channel = channel;
  247. sConfig.Rank = 1;
  248. #if defined(STM32F0)
  249. sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES_5;
  250. #elif defined(STM32F4) || defined(STM32F7)
  251. sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
  252. #elif defined(STM32H7)
  253. sConfig.SamplingTime = ADC_SAMPLETIME_8CYCLES_5;
  254. sConfig.SingleDiff = ADC_SINGLE_ENDED;
  255. sConfig.OffsetNumber = ADC_OFFSET_NONE;
  256. sConfig.OffsetRightShift = DISABLE;
  257. sConfig.OffsetSignedSaturation = DISABLE;
  258. #elif defined(STM32L4)
  259. sConfig.SamplingTime = ADC_SAMPLETIME_12CYCLES_5;
  260. sConfig.SingleDiff = ADC_SINGLE_ENDED;
  261. sConfig.OffsetNumber = ADC_OFFSET_NONE;
  262. sConfig.Offset = 0;
  263. #else
  264. #error Unsupported processor
  265. #endif
  266. HAL_ADC_ConfigChannel(adc_handle, &sConfig);
  267. }
  268. STATIC uint32_t adc_read_channel(ADC_HandleTypeDef *adcHandle) {
  269. HAL_ADC_Start(adcHandle);
  270. adc_wait_for_eoc_or_timeout(EOC_TIMEOUT);
  271. uint32_t value = ADCx->DR;
  272. HAL_ADC_Stop(adcHandle);
  273. return value;
  274. }
  275. STATIC uint32_t adc_config_and_read_channel(ADC_HandleTypeDef *adcHandle, uint32_t channel) {
  276. adc_config_channel(adcHandle, channel);
  277. return adc_read_channel(adcHandle);
  278. }
  279. /******************************************************************************/
  280. /* MicroPython bindings : adc object (single channel) */
  281. STATIC void adc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
  282. pyb_obj_adc_t *self = MP_OBJ_TO_PTR(self_in);
  283. mp_print_str(print, "<ADC on ");
  284. mp_obj_print_helper(print, self->pin_name, PRINT_STR);
  285. mp_printf(print, " channel=%u>", self->channel);
  286. }
  287. /// \classmethod \constructor(pin)
  288. /// Create an ADC object associated with the given pin.
  289. /// This allows you to then read analog values on that pin.
  290. STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
  291. // check number of arguments
  292. mp_arg_check_num(n_args, n_kw, 1, 1, false);
  293. // 1st argument is the pin name
  294. mp_obj_t pin_obj = args[0];
  295. uint32_t channel;
  296. if (MP_OBJ_IS_INT(pin_obj)) {
  297. channel = adc_get_internal_channel(mp_obj_get_int(pin_obj));
  298. } else {
  299. const pin_obj_t *pin = pin_find(pin_obj);
  300. if ((pin->adc_num & PIN_ADC1) == 0) {
  301. // No ADC1 function on that pin
  302. nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin %q does not have ADC capabilities", pin->name));
  303. }
  304. channel = pin->adc_channel;
  305. }
  306. if (!is_adcx_channel(channel)) {
  307. nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "not a valid ADC Channel: %d", channel));
  308. }
  309. if (ADC_FIRST_GPIO_CHANNEL <= channel && channel <= ADC_LAST_GPIO_CHANNEL) {
  310. // these channels correspond to physical GPIO ports so make sure they exist
  311. if (pin_adc1[channel] == NULL) {
  312. nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
  313. "channel %d not available on this board", channel));
  314. }
  315. }
  316. pyb_obj_adc_t *o = m_new_obj(pyb_obj_adc_t);
  317. memset(o, 0, sizeof(*o));
  318. o->base.type = &pyb_adc_type;
  319. o->pin_name = pin_obj;
  320. o->channel = channel;
  321. adc_init_single(o);
  322. return MP_OBJ_FROM_PTR(o);
  323. }
  324. /// \method read()
  325. /// Read the value on the analog pin and return it. The returned value
  326. /// will be between 0 and 4095.
  327. STATIC mp_obj_t adc_read(mp_obj_t self_in) {
  328. pyb_obj_adc_t *self = MP_OBJ_TO_PTR(self_in);
  329. return mp_obj_new_int(adc_config_and_read_channel(&self->handle, self->channel));
  330. }
  331. STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_read_obj, adc_read);
  332. /// \method read_timed(buf, timer)
  333. ///
  334. /// Read analog values into `buf` at a rate set by the `timer` object.
  335. ///
  336. /// `buf` can be bytearray or array.array for example. The ADC values have
  337. /// 12-bit resolution and are stored directly into `buf` if its element size is
  338. /// 16 bits or greater. If `buf` has only 8-bit elements (eg a bytearray) then
  339. /// the sample resolution will be reduced to 8 bits.
  340. ///
  341. /// `timer` should be a Timer object, and a sample is read each time the timer
  342. /// triggers. The timer must already be initialised and running at the desired
  343. /// sampling frequency.
  344. ///
  345. /// To support previous behaviour of this function, `timer` can also be an
  346. /// integer which specifies the frequency (in Hz) to sample at. In this case
  347. /// Timer(6) will be automatically configured to run at the given frequency.
  348. ///
  349. /// Example using a Timer object (preferred way):
  350. ///
  351. /// adc = pyb.ADC(pyb.Pin.board.X19) # create an ADC on pin X19
  352. /// tim = pyb.Timer(6, freq=10) # create a timer running at 10Hz
  353. /// buf = bytearray(100) # creat a buffer to store the samples
  354. /// adc.read_timed(buf, tim) # sample 100 values, taking 10s
  355. ///
  356. /// Example using an integer for the frequency:
  357. ///
  358. /// adc = pyb.ADC(pyb.Pin.board.X19) # create an ADC on pin X19
  359. /// buf = bytearray(100) # create a buffer of 100 bytes
  360. /// adc.read_timed(buf, 10) # read analog values into buf at 10Hz
  361. /// # this will take 10 seconds to finish
  362. /// for val in buf: # loop over all values
  363. /// print(val) # print the value out
  364. ///
  365. /// This function does not allocate any memory.
  366. STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_in) {
  367. pyb_obj_adc_t *self = MP_OBJ_TO_PTR(self_in);
  368. mp_buffer_info_t bufinfo;
  369. mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE);
  370. size_t typesize = mp_binary_get_size('@', bufinfo.typecode, NULL);
  371. TIM_HandleTypeDef *tim;
  372. #if defined(TIM6)
  373. if (mp_obj_is_integer(freq_in)) {
  374. // freq in Hz given so init TIM6 (legacy behaviour)
  375. tim = timer_tim6_init(mp_obj_get_int(freq_in));
  376. HAL_TIM_Base_Start(tim);
  377. } else
  378. #endif
  379. {
  380. // use the supplied timer object as the sampling time base
  381. tim = pyb_timer_get_handle(freq_in);
  382. }
  383. // configure the ADC channel
  384. adc_config_channel(&self->handle, self->channel);
  385. // This uses the timer in polling mode to do the sampling
  386. // TODO use DMA
  387. uint nelems = bufinfo.len / typesize;
  388. for (uint index = 0; index < nelems; index++) {
  389. // Wait for the timer to trigger so we sample at the correct frequency
  390. while (__HAL_TIM_GET_FLAG(tim, TIM_FLAG_UPDATE) == RESET) {
  391. }
  392. __HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE);
  393. if (index == 0) {
  394. // for the first sample we need to turn the ADC on
  395. HAL_ADC_Start(&self->handle);
  396. } else {
  397. // for subsequent samples we can just set the "start sample" bit
  398. #if defined(STM32F4) || defined(STM32F7)
  399. ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART;
  400. #elif defined(STM32F0) || defined(STM32H7) || defined(STM32L4)
  401. SET_BIT(ADCx->CR, ADC_CR_ADSTART);
  402. #else
  403. #error Unsupported processor
  404. #endif
  405. }
  406. // wait for sample to complete
  407. adc_wait_for_eoc_or_timeout(EOC_TIMEOUT);
  408. // read value
  409. uint value = ADCx->DR;
  410. // store value in buffer
  411. if (typesize == 1) {
  412. value >>= 4;
  413. }
  414. mp_binary_set_val_array_from_int(bufinfo.typecode, bufinfo.buf, index, value);
  415. }
  416. // turn the ADC off
  417. HAL_ADC_Stop(&self->handle);
  418. #if defined(TIM6)
  419. if (mp_obj_is_integer(freq_in)) {
  420. // stop timer if we initialised TIM6 in this function (legacy behaviour)
  421. HAL_TIM_Base_Stop(tim);
  422. }
  423. #endif
  424. return mp_obj_new_int(bufinfo.len);
  425. }
  426. STATIC MP_DEFINE_CONST_FUN_OBJ_3(adc_read_timed_obj, adc_read_timed);
  427. // read_timed_multi((adcx, adcy, ...), (bufx, bufy, ...), timer)
  428. //
  429. // Read analog values from multiple ADC's into buffers at a rate set by the
  430. // timer. The ADC values have 12-bit resolution and are stored directly into
  431. // the corresponding buffer if its element size is 16 bits or greater, otherwise
  432. // the sample resolution will be reduced to 8 bits.
  433. //
  434. // This function should not allocate any heap memory.
  435. STATIC mp_obj_t adc_read_timed_multi(mp_obj_t adc_array_in, mp_obj_t buf_array_in, mp_obj_t tim_in) {
  436. size_t nadcs, nbufs;
  437. mp_obj_t *adc_array, *buf_array;
  438. mp_obj_get_array(adc_array_in, &nadcs, &adc_array);
  439. mp_obj_get_array(buf_array_in, &nbufs, &buf_array);
  440. if (nadcs < 1) {
  441. mp_raise_ValueError("need at least 1 ADC");
  442. }
  443. if (nadcs != nbufs) {
  444. mp_raise_ValueError("length of ADC and buffer lists differ");
  445. }
  446. // Get buf for first ADC, get word size, check other buffers match in type
  447. mp_buffer_info_t bufinfo;
  448. mp_get_buffer_raise(buf_array[0], &bufinfo, MP_BUFFER_WRITE);
  449. size_t typesize = mp_binary_get_size('@', bufinfo.typecode, NULL);
  450. void *bufptrs[nbufs];
  451. for (uint array_index = 0; array_index < nbufs; array_index++) {
  452. mp_buffer_info_t bufinfo_curr;
  453. mp_get_buffer_raise(buf_array[array_index], &bufinfo_curr, MP_BUFFER_WRITE);
  454. if ((bufinfo.len != bufinfo_curr.len) || (bufinfo.typecode != bufinfo_curr.typecode)) {
  455. mp_raise_ValueError("size and type of buffers must match");
  456. }
  457. bufptrs[array_index] = bufinfo_curr.buf;
  458. }
  459. // Use the supplied timer object as the sampling time base
  460. TIM_HandleTypeDef *tim;
  461. tim = pyb_timer_get_handle(tim_in);
  462. // Start adc; this is slow so wait for it to start
  463. pyb_obj_adc_t *adc0 = MP_OBJ_TO_PTR(adc_array[0]);
  464. adc_config_channel(&adc0->handle, adc0->channel);
  465. HAL_ADC_Start(&adc0->handle);
  466. // Wait for sample to complete and discard
  467. adc_wait_for_eoc_or_timeout(EOC_TIMEOUT);
  468. // Read (and discard) value
  469. uint value = ADCx->DR;
  470. // Ensure first sample is on a timer tick
  471. __HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE);
  472. while (__HAL_TIM_GET_FLAG(tim, TIM_FLAG_UPDATE) == RESET) {
  473. }
  474. __HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE);
  475. // Overrun check: assume success
  476. bool success = true;
  477. size_t nelems = bufinfo.len / typesize;
  478. for (size_t elem_index = 0; elem_index < nelems; elem_index++) {
  479. if (__HAL_TIM_GET_FLAG(tim, TIM_FLAG_UPDATE) != RESET) {
  480. // Timer has already triggered
  481. success = false;
  482. } else {
  483. // Wait for the timer to trigger so we sample at the correct frequency
  484. while (__HAL_TIM_GET_FLAG(tim, TIM_FLAG_UPDATE) == RESET) {
  485. }
  486. }
  487. __HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE);
  488. for (size_t array_index = 0; array_index < nadcs; array_index++) {
  489. pyb_obj_adc_t *adc = MP_OBJ_TO_PTR(adc_array[array_index]);
  490. // configure the ADC channel
  491. adc_config_channel(&adc->handle, adc->channel);
  492. // for the first sample we need to turn the ADC on
  493. // ADC is started: set the "start sample" bit
  494. #if defined(STM32F4) || defined(STM32F7)
  495. ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART;
  496. #elif defined(STM32F0) || defined(STM32H7) || defined(STM32L4)
  497. SET_BIT(ADCx->CR, ADC_CR_ADSTART);
  498. #else
  499. #error Unsupported processor
  500. #endif
  501. // wait for sample to complete
  502. adc_wait_for_eoc_or_timeout(EOC_TIMEOUT);
  503. // read value
  504. value = ADCx->DR;
  505. // store values in buffer
  506. if (typesize == 1) {
  507. value >>= 4;
  508. }
  509. mp_binary_set_val_array_from_int(bufinfo.typecode, bufptrs[array_index], elem_index, value);
  510. }
  511. }
  512. // Turn the ADC off
  513. adc0 = MP_OBJ_TO_PTR(adc_array[0]);
  514. HAL_ADC_Stop(&adc0->handle);
  515. return mp_obj_new_bool(success);
  516. }
  517. STATIC MP_DEFINE_CONST_FUN_OBJ_3(adc_read_timed_multi_fun_obj, adc_read_timed_multi);
  518. STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(adc_read_timed_multi_obj, MP_ROM_PTR(&adc_read_timed_multi_fun_obj));
  519. STATIC const mp_rom_map_elem_t adc_locals_dict_table[] = {
  520. { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&adc_read_obj) },
  521. { MP_ROM_QSTR(MP_QSTR_read_timed), MP_ROM_PTR(&adc_read_timed_obj) },
  522. { MP_ROM_QSTR(MP_QSTR_read_timed_multi), MP_ROM_PTR(&adc_read_timed_multi_obj) },
  523. };
  524. STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table);
  525. const mp_obj_type_t pyb_adc_type = {
  526. { &mp_type_type },
  527. .name = MP_QSTR_ADC,
  528. .print = adc_print,
  529. .make_new = adc_make_new,
  530. .locals_dict = (mp_obj_dict_t*)&adc_locals_dict,
  531. };
  532. /******************************************************************************/
  533. /* adc all object */
  534. typedef struct _pyb_adc_all_obj_t {
  535. mp_obj_base_t base;
  536. ADC_HandleTypeDef handle;
  537. } pyb_adc_all_obj_t;
  538. void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution, uint32_t en_mask) {
  539. switch (resolution) {
  540. #if !defined(STM32H7)
  541. case 6: resolution = ADC_RESOLUTION_6B; break;
  542. #endif
  543. case 8: resolution = ADC_RESOLUTION_8B; break;
  544. case 10: resolution = ADC_RESOLUTION_10B; break;
  545. case 12: resolution = ADC_RESOLUTION_12B; break;
  546. default:
  547. nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
  548. "resolution %d not supported", resolution));
  549. }
  550. for (uint32_t channel = ADC_FIRST_GPIO_CHANNEL; channel <= ADC_LAST_GPIO_CHANNEL; ++channel) {
  551. // only initialise those channels that are selected with the en_mask
  552. if (en_mask & (1 << channel)) {
  553. // Channels 0-16 correspond to real pins. Configure the GPIO pin in
  554. // ADC mode.
  555. const pin_obj_t *pin = pin_adc1[channel];
  556. if (pin) {
  557. mp_hal_pin_config(pin, MP_HAL_PIN_MODE_ADC, MP_HAL_PIN_PULL_NONE, 0);
  558. }
  559. }
  560. }
  561. adcx_init_periph(&adc_all->handle, resolution);
  562. }
  563. int adc_get_resolution(ADC_HandleTypeDef *adcHandle) {
  564. uint32_t res_reg = ADC_GET_RESOLUTION(adcHandle);
  565. switch (res_reg) {
  566. #if !defined(STM32H7)
  567. case ADC_RESOLUTION_6B: return 6;
  568. #endif
  569. case ADC_RESOLUTION_8B: return 8;
  570. case ADC_RESOLUTION_10B: return 10;
  571. }
  572. return 12;
  573. }
  574. int adc_read_core_temp(ADC_HandleTypeDef *adcHandle) {
  575. int32_t raw_value = adc_config_and_read_channel(adcHandle, ADC_CHANNEL_TEMPSENSOR);
  576. // Note: constants assume 12-bit resolution, so we scale the raw value to
  577. // be 12-bits.
  578. raw_value <<= (12 - adc_get_resolution(adcHandle));
  579. return ((raw_value - CORE_TEMP_V25) / CORE_TEMP_AVG_SLOPE) + 25;
  580. }
  581. #if MICROPY_PY_BUILTINS_FLOAT
  582. // correction factor for reference value
  583. STATIC volatile float adc_refcor = 1.0f;
  584. float adc_read_core_temp_float(ADC_HandleTypeDef *adcHandle) {
  585. int32_t raw_value = adc_config_and_read_channel(adcHandle, ADC_CHANNEL_TEMPSENSOR);
  586. // constants assume 12-bit resolution so we scale the raw value to 12-bits
  587. raw_value <<= (12 - adc_get_resolution(adcHandle));
  588. float core_temp_avg_slope = (*ADC_CAL2 - *ADC_CAL1) / 80.0;
  589. return (((float)raw_value * adc_refcor - *ADC_CAL1) / core_temp_avg_slope) + 30.0f;
  590. }
  591. float adc_read_core_vbat(ADC_HandleTypeDef *adcHandle) {
  592. uint32_t raw_value = adc_config_and_read_channel(adcHandle, ADC_CHANNEL_VBAT);
  593. // Note: constants assume 12-bit resolution, so we scale the raw value to
  594. // be 12-bits.
  595. raw_value <<= (12 - adc_get_resolution(adcHandle));
  596. #if defined(STM32F4) || defined(STM32F7)
  597. // ST docs say that (at least on STM32F42x and STM32F43x), VBATE must
  598. // be disabled when TSVREFE is enabled for TEMPSENSOR and VREFINT
  599. // conversions to work. VBATE is enabled by the above call to read
  600. // the channel, and here we disable VBATE so a subsequent call for
  601. // TEMPSENSOR or VREFINT works correctly.
  602. ADC->CCR &= ~ADC_CCR_VBATE;
  603. #endif
  604. return raw_value * VBAT_DIV * ADC_SCALE * adc_refcor;
  605. }
  606. float adc_read_core_vref(ADC_HandleTypeDef *adcHandle) {
  607. uint32_t raw_value = adc_config_and_read_channel(adcHandle, ADC_CHANNEL_VREFINT);
  608. // Note: constants assume 12-bit resolution, so we scale the raw value to
  609. // be 12-bits.
  610. raw_value <<= (12 - adc_get_resolution(adcHandle));
  611. // update the reference correction factor
  612. adc_refcor = ((float)(*VREFIN_CAL)) / ((float)raw_value);
  613. return (*VREFIN_CAL) * ADC_SCALE;
  614. }
  615. #endif
  616. /******************************************************************************/
  617. /* MicroPython bindings : adc_all object */
  618. STATIC mp_obj_t adc_all_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
  619. // check number of arguments
  620. mp_arg_check_num(n_args, n_kw, 1, 2, false);
  621. // make ADCAll object
  622. pyb_adc_all_obj_t *o = m_new_obj(pyb_adc_all_obj_t);
  623. o->base.type = &pyb_adc_all_type;
  624. mp_int_t res = mp_obj_get_int(args[0]);
  625. uint32_t en_mask = 0xffffffff;
  626. if (n_args > 1) {
  627. en_mask = mp_obj_get_int(args[1]);
  628. }
  629. adc_init_all(o, res, en_mask);
  630. return MP_OBJ_FROM_PTR(o);
  631. }
  632. STATIC mp_obj_t adc_all_read_channel(mp_obj_t self_in, mp_obj_t channel) {
  633. pyb_adc_all_obj_t *self = MP_OBJ_TO_PTR(self_in);
  634. uint32_t chan = adc_get_internal_channel(mp_obj_get_int(channel));
  635. uint32_t data = adc_config_and_read_channel(&self->handle, chan);
  636. return mp_obj_new_int(data);
  637. }
  638. STATIC MP_DEFINE_CONST_FUN_OBJ_2(adc_all_read_channel_obj, adc_all_read_channel);
  639. STATIC mp_obj_t adc_all_read_core_temp(mp_obj_t self_in) {
  640. pyb_adc_all_obj_t *self = MP_OBJ_TO_PTR(self_in);
  641. #if MICROPY_PY_BUILTINS_FLOAT
  642. float data = adc_read_core_temp_float(&self->handle);
  643. return mp_obj_new_float(data);
  644. #else
  645. int data = adc_read_core_temp(&self->handle);
  646. return mp_obj_new_int(data);
  647. #endif
  648. }
  649. STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_core_temp_obj, adc_all_read_core_temp);
  650. #if MICROPY_PY_BUILTINS_FLOAT
  651. STATIC mp_obj_t adc_all_read_core_vbat(mp_obj_t self_in) {
  652. pyb_adc_all_obj_t *self = MP_OBJ_TO_PTR(self_in);
  653. float data = adc_read_core_vbat(&self->handle);
  654. return mp_obj_new_float(data);
  655. }
  656. STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_core_vbat_obj, adc_all_read_core_vbat);
  657. STATIC mp_obj_t adc_all_read_core_vref(mp_obj_t self_in) {
  658. pyb_adc_all_obj_t *self = MP_OBJ_TO_PTR(self_in);
  659. float data = adc_read_core_vref(&self->handle);
  660. return mp_obj_new_float(data);
  661. }
  662. STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_core_vref_obj, adc_all_read_core_vref);
  663. STATIC mp_obj_t adc_all_read_vref(mp_obj_t self_in) {
  664. pyb_adc_all_obj_t *self = MP_OBJ_TO_PTR(self_in);
  665. adc_read_core_vref(&self->handle);
  666. return mp_obj_new_float(3.3 * adc_refcor);
  667. }
  668. STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_vref_obj, adc_all_read_vref);
  669. #endif
  670. STATIC const mp_rom_map_elem_t adc_all_locals_dict_table[] = {
  671. { MP_ROM_QSTR(MP_QSTR_read_channel), MP_ROM_PTR(&adc_all_read_channel_obj) },
  672. { MP_ROM_QSTR(MP_QSTR_read_core_temp), MP_ROM_PTR(&adc_all_read_core_temp_obj) },
  673. #if MICROPY_PY_BUILTINS_FLOAT
  674. { MP_ROM_QSTR(MP_QSTR_read_core_vbat), MP_ROM_PTR(&adc_all_read_core_vbat_obj) },
  675. { MP_ROM_QSTR(MP_QSTR_read_core_vref), MP_ROM_PTR(&adc_all_read_core_vref_obj) },
  676. { MP_ROM_QSTR(MP_QSTR_read_vref), MP_ROM_PTR(&adc_all_read_vref_obj) },
  677. #endif
  678. };
  679. STATIC MP_DEFINE_CONST_DICT(adc_all_locals_dict, adc_all_locals_dict_table);
  680. const mp_obj_type_t pyb_adc_all_type = {
  681. { &mp_type_type },
  682. .name = MP_QSTR_ADCAll,
  683. .make_new = adc_all_make_new,
  684. .locals_dict = (mp_obj_dict_t*)&adc_all_locals_dict,
  685. };
  686. #endif // MICROPY_HW_ENABLE_ADC