summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--stmhal/adc.c32
-rw-r--r--stmhal/dac.c42
-rw-r--r--stmhal/qstrdefsport.h1
-rw-r--r--stmhal/timer.c27
-rw-r--r--stmhal/timer.h2
5 files changed, 82 insertions, 22 deletions
diff --git a/stmhal/adc.c b/stmhal/adc.c
index 8a1c23c4f6..dafa3f7bce 100644
--- a/stmhal/adc.c
+++ b/stmhal/adc.c
@@ -11,6 +11,7 @@
#include "adc.h"
#include "pin.h"
#include "build/pins.h"
+#include "timer.h"
// Usage Model:
//
@@ -162,8 +163,39 @@ STATIC mp_obj_t adc_read(mp_obj_t self_in) {
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_read_obj, adc_read);
+STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_in) {
+ pyb_obj_adc_t *self = self_in;
+
+ buffer_info_t bufinfo;
+ mp_get_buffer_raise(buf_in, &bufinfo);
+
+ // Init TIM6 at the required frequency (in Hz)
+ timer_tim6_init(mp_obj_get_int(freq_in));
+
+ // Start timer
+ HAL_TIM_Base_Start(&TIM6_Handle);
+
+ // This uses the timer in polling mode to do the sampling
+ // TODO use DMA
+ for (uint i = 0; i < bufinfo.len; i++) {
+ // Wait for the timer to trigger
+ while (__HAL_TIM_GET_FLAG(&TIM6_Handle, TIM_FLAG_UPDATE) == RESET) {
+ }
+ __HAL_TIM_CLEAR_FLAG(&TIM6_Handle, TIM_FLAG_UPDATE);
+ ((byte*)bufinfo.buf)[i] = adc_read_channel(&self->handle) >> 4;
+ }
+
+ // Stop timer
+ HAL_TIM_Base_Stop(&TIM6_Handle);
+
+ return mp_obj_new_int(bufinfo.len);
+}
+
+STATIC MP_DEFINE_CONST_FUN_OBJ_3(adc_read_timed_obj, adc_read_timed);
+
STATIC const mp_map_elem_t adc_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&adc_read_obj},
+ { MP_OBJ_NEW_QSTR(MP_QSTR_read_timed), (mp_obj_t)&adc_read_timed_obj},
};
STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table);
diff --git a/stmhal/dac.c b/stmhal/dac.c
index 5e809412e9..c018a4046a 100644
--- a/stmhal/dac.c
+++ b/stmhal/dac.c
@@ -10,9 +10,9 @@
#include "parse.h"
#include "obj.h"
#include "runtime.h"
+#include "timer.h"
#include "dac.h"
-TIM_HandleTypeDef TIM6_Handle;
STATIC DAC_HandleTypeDef DAC_Handle;
void dac_init(void) {
@@ -22,19 +22,8 @@ void dac_init(void) {
}
STATIC void TIM6_Config(uint freq) {
- // TIM6 clock enable
- __TIM6_CLK_ENABLE();
-
- // Compute the prescaler value so TIM6 triggers at freq-Hz
- uint16_t period = (uint16_t) ((SystemCoreClock / 2) / freq) - 1;
-
- // time base clock configuration
- TIM6_Handle.Instance = TIM6;
- TIM6_Handle.Init.Period = period;
- TIM6_Handle.Init.Prescaler = 0; // timer runs at SystemCoreClock / 2
- TIM6_Handle.Init.ClockDivision = 0; // unused for TIM6
- TIM6_Handle.Init.CounterMode = TIM_COUNTERMODE_UP; // unused for TIM6
- HAL_TIM_Base_Init(&TIM6_Handle);
+ // Init TIM6 at the required frequency (in Hz)
+ timer_tim6_init(freq);
// TIM6 TRGO selection
TIM_MasterConfigTypeDef config;
@@ -203,17 +192,14 @@ mp_obj_t pyb_dac_dma(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
DAC_Init(self->dac_channel, &DAC_InitStructure);
*/
- if (self->state != 3) {
- DAC_ChannelConfTypeDef config;
- config.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
- config.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
- HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel);
- self->state = 3;
- }
-
// DMA1_Stream[67] channel7 configuration
DMA_HandleTypeDef DMA_Handle;
DMA_Handle.Instance = self->dma_stream;
+
+ // Need to deinit DMA first
+ DMA_Handle.State = HAL_DMA_STATE_READY;
+ HAL_DMA_DeInit(&DMA_Handle);
+
DMA_Handle.Init.Channel = DMA_CHANNEL_7;
DMA_Handle.Init.Direction = DMA_MEMORY_TO_PERIPH;
DMA_Handle.Init.PeriphInc = DMA_PINC_DISABLE;
@@ -231,6 +217,18 @@ mp_obj_t pyb_dac_dma(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
__HAL_LINKDMA(&DAC_Handle, DMA_Handle1, DMA_Handle);
+ DAC_Handle.Instance = DAC;
+ DAC_Handle.State = HAL_DAC_STATE_RESET;
+ HAL_DAC_Init(&DAC_Handle);
+
+ if (self->state != 3) {
+ DAC_ChannelConfTypeDef config;
+ config.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
+ config.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
+ HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel);
+ self->state = 3;
+ }
+
HAL_DAC_Start_DMA(&DAC_Handle, self->dac_channel, (uint32_t*)bufinfo.buf, bufinfo.len, DAC_ALIGN_8B_R);
/*
diff --git a/stmhal/qstrdefsport.h b/stmhal/qstrdefsport.h
index ab59699d7d..68b91c3d8d 100644
--- a/stmhal/qstrdefsport.h
+++ b/stmhal/qstrdefsport.h
@@ -97,6 +97,7 @@ Q(filtered_xyz)
// for ADC object
Q(ADC)
Q(ADC_all)
+Q(read_timed)
Q(read_channel)
Q(read_core_temp)
Q(read_core_vbat)
diff --git a/stmhal/timer.c b/stmhal/timer.c
index 1e77f0fea3..5ea605039d 100644
--- a/stmhal/timer.c
+++ b/stmhal/timer.c
@@ -27,6 +27,7 @@
TIM_HandleTypeDef TIM3_Handle;
TIM_HandleTypeDef TIM5_Handle;
+TIM_HandleTypeDef TIM6_Handle;
// TIM3 is set-up for the USB CDC interface
void timer_tim3_init(void) {
@@ -57,6 +58,7 @@ void timer_tim3_deinit(void) {
*/
// TIM5 is set-up for the servo controller
+// This function inits but does not start the timer
void timer_tim5_init(void) {
// TIM5 clock enable
__TIM5_CLK_ENABLE();
@@ -74,6 +76,31 @@ void timer_tim5_init(void) {
HAL_TIM_PWM_Init(&TIM5_Handle);
}
+// Init TIM6 with a counter-overflow at the given frequency (given in Hz)
+// TIM6 is used by the DAC and ADC for auto sampling at a given frequency
+// This function inits but does not start the timer
+void timer_tim6_init(uint freq) {
+ // TIM6 clock enable
+ __TIM6_CLK_ENABLE();
+
+ // Timer runs at SystemCoreClock / 2
+ // Compute the prescaler value so TIM6 triggers at freq-Hz
+ uint32_t period = (SystemCoreClock / 2) / freq;
+ uint32_t prescaler = 1;
+ while (period > 0xffff) {
+ period >>= 1;
+ prescaler <<= 1;
+ }
+
+ // Time base clock configuration
+ TIM6_Handle.Instance = TIM6;
+ TIM6_Handle.Init.Period = period - 1;
+ TIM6_Handle.Init.Prescaler = prescaler - 1;
+ TIM6_Handle.Init.ClockDivision = 0; // unused for TIM6
+ TIM6_Handle.Init.CounterMode = TIM_COUNTERMODE_UP; // unused for TIM6
+ HAL_TIM_Base_Init(&TIM6_Handle);
+}
+
// Interrupt dispatch
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim == &TIM3_Handle) {
diff --git a/stmhal/timer.h b/stmhal/timer.h
index 317b39b3f7..06e19bcc8b 100644
--- a/stmhal/timer.h
+++ b/stmhal/timer.h
@@ -5,6 +5,8 @@
extern TIM_HandleTypeDef TIM3_Handle;
extern TIM_HandleTypeDef TIM5_Handle;
+extern TIM_HandleTypeDef TIM6_Handle;
void timer_tim3_init(void);
void timer_tim5_init(void);
+void timer_tim6_init(uint freq);