diff options
-rw-r--r-- | ports/stm32/Makefile | 2 | ||||
-rw-r--r-- | ports/stm32/dac.c | 296 | ||||
-rw-r--r-- | ports/stm32/dac.h | 2 | ||||
-rw-r--r-- | ports/stm32/dma.c | 100 | ||||
-rw-r--r-- | ports/stm32/dma.h | 4 | ||||
-rw-r--r-- | ports/stm32/main.c | 4 |
6 files changed, 226 insertions, 182 deletions
diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 242ced38c..d90a7c2e4 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -296,8 +296,6 @@ SRC_HAL = $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\ hal_adc.c \ hal_adc_ex.c \ hal_cortex.c \ - hal_dac.c \ - hal_dac_ex.c \ hal_dma.c \ hal_flash.c \ hal_flash_ex.c \ diff --git a/ports/stm32/dac.c b/ports/stm32/dac.c index 3a92258ff..cb9157c3d 100644 --- a/ports/stm32/dac.c +++ b/ports/stm32/dac.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013-2019 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -70,15 +70,6 @@ #define DAC DAC1 #endif -STATIC DAC_HandleTypeDef DAC_Handle; - -void dac_init(void) { - memset(&DAC_Handle, 0, sizeof DAC_Handle); - DAC_Handle.Instance = DAC; - DAC_Handle.State = HAL_DAC_STATE_RESET; - HAL_DAC_Init(&DAC_Handle); -} - #if defined(TIM6) STATIC void TIM6_Config(uint freq) { // Init TIM6 at the required frequency (in Hz) @@ -131,27 +122,97 @@ STATIC uint32_t TIMx_Config(mp_obj_t timer) { } } +STATIC void dac_deinit(uint32_t dac_channel) { + DAC->CR &= ~(DAC_CR_EN1 << dac_channel); + #if defined(STM32H7) || defined(STM32L4) + DAC->MCR = (DAC->MCR & ~(DAC_MCR_MODE1_Msk << dac_channel)) | (DAC_OUTPUTBUFFER_DISABLE << dac_channel); + #else + DAC->CR |= DAC_CR_BOFF1 << dac_channel; + #endif +} + +STATIC void dac_config_channel(uint32_t dac_channel, uint32_t trig, uint32_t outbuf) { + DAC->CR &= ~(DAC_CR_EN1 << dac_channel); + uint32_t cr_off = DAC_CR_DMAEN1 | DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1; + uint32_t cr_on = trig; + #if defined(STM32H7) || defined(STM32L4) + DAC->MCR = (DAC->MCR & ~(DAC_MCR_MODE1_Msk << dac_channel)) | (outbuf << dac_channel); + #else + cr_off |= DAC_CR_BOFF1; + cr_on |= outbuf; + #endif + DAC->CR = (DAC->CR & ~(cr_off << dac_channel)) | (cr_on << dac_channel); +} + +STATIC void dac_set_value(uint32_t dac_channel, uint32_t align, uint32_t value) { + uint32_t base; + if (dac_channel == DAC_CHANNEL_1) { + base = (uint32_t)&DAC->DHR12R1; + } else { + base = (uint32_t)&DAC->DHR12R2; + } + *(volatile uint32_t*)(base + align) = value; +} + +STATIC void dac_start(uint32_t dac_channel) { + DAC->CR |= DAC_CR_EN1 << dac_channel; +} + +STATIC void dac_start_dma(uint32_t dac_channel, const dma_descr_t *dma_descr, uint32_t dma_mode, uint32_t bit_size, uint32_t dac_align, size_t len, void *buf) { + uint32_t dma_align; + if (bit_size == 8) { + dma_align = DMA_MDATAALIGN_BYTE | DMA_PDATAALIGN_BYTE; + } else { + dma_align = DMA_MDATAALIGN_HALFWORD | DMA_PDATAALIGN_HALFWORD; + } + + uint32_t base; + if (dac_channel == DAC_CHANNEL_1) { + base = (uint32_t)&DAC->DHR12R1; + } else { + base = (uint32_t)&DAC->DHR12R2; + } + + dma_nohal_deinit(dma_descr); + dma_nohal_init(dma_descr, DMA_MEMORY_TO_PERIPH | dma_mode | dma_align); + dma_nohal_start(dma_descr, (uint32_t)buf, base + dac_align, len); + + DAC->CR |= DAC_CR_EN1 << dac_channel; +} + /******************************************************************************/ // MicroPython bindings -typedef enum { - DAC_STATE_RESET, - DAC_STATE_WRITE_SINGLE, - DAC_STATE_BUILTIN_WAVEFORM, - DAC_STATE_DMA_WAVEFORM, // should be last enum since we use space beyond it -} pyb_dac_state_t; - typedef struct _pyb_dac_obj_t { mp_obj_base_t base; - uint32_t dac_channel; // DAC_CHANNEL_1 or DAC_CHANNEL_2 - const dma_descr_t *tx_dma_descr; - mp_hal_pin_obj_t pin; // pin_A4 or pin_A5 + uint8_t dac_channel; // DAC_CHANNEL_1 or DAC_CHANNEL_2 uint8_t bits; // 8 or 12 - uint8_t state; uint8_t outbuf_single; uint8_t outbuf_waveform; } pyb_dac_obj_t; +STATIC pyb_dac_obj_t pyb_dac_obj[2]; + +STATIC void pyb_dac_reconfigure(pyb_dac_obj_t *self, uint32_t cr, uint32_t outbuf, uint32_t value) { + bool restart = false; + const uint32_t cr_mask = DAC_CR_DMAEN1 | DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1 | DAC_CR_EN1; + if (((DAC->CR >> self->dac_channel) & cr_mask) != (cr | DAC_CR_EN1)) { + const dma_descr_t *tx_dma_descr; + if (self->dac_channel == DAC_CHANNEL_1) { + tx_dma_descr = &dma_DAC_1_TX; + } else { + tx_dma_descr = &dma_DAC_2_TX; + } + dma_nohal_deinit(tx_dma_descr); + dac_config_channel(self->dac_channel, cr, outbuf); + restart = true; + } + dac_set_value(self->dac_channel, DAC_ALIGN_12B_R, value); + if (restart) { + dac_start(self->dac_channel); + } +} + STATIC void pyb_dac_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_dac_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "DAC(%u, bits=%u)", @@ -170,7 +231,13 @@ STATIC mp_obj_t pyb_dac_init_helper(pyb_dac_obj_t *self, size_t n_args, const mp mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); // GPIO configuration - mp_hal_pin_config(self->pin, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_obj_t pin; + if (self->dac_channel == DAC_CHANNEL_1) { + pin = pin_A4; + } else { + pin = pin_A5; + } + mp_hal_pin_config(pin, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); // DAC peripheral clock #if defined(STM32F4) || defined(STM32F7) @@ -183,20 +250,8 @@ STATIC mp_obj_t pyb_dac_init_helper(pyb_dac_obj_t *self, size_t n_args, const mp #error Unsupported Processor #endif - // stop anything already going on - __HAL_RCC_DMA1_CLK_ENABLE(); - DMA_HandleTypeDef DMA_Handle; - /* Get currently configured dma */ - dma_init_handle(&DMA_Handle, self->tx_dma_descr, DMA_MEMORY_TO_PERIPH, (void*)NULL); - // Need to deinit DMA first - DMA_Handle.State = HAL_DMA_STATE_READY; - HAL_DMA_DeInit(&DMA_Handle); - - HAL_DAC_Stop(&DAC_Handle, self->dac_channel); - if ((self->dac_channel == DAC_CHANNEL_1 && DAC_Handle.DMA_Handle1 != NULL) - || (self->dac_channel == DAC_CHANNEL_2 && DAC_Handle.DMA_Handle2 != NULL)) { - HAL_DAC_Stop_DMA(&DAC_Handle, self->dac_channel); - } + // Stop the DAC in case it was already running + DAC->CR &= ~(DAC_CR_EN1 << self->dac_channel); // set bit resolution if (args[0].u_int == 8 || args[0].u_int == 12) { @@ -218,9 +273,6 @@ STATIC mp_obj_t pyb_dac_init_helper(pyb_dac_obj_t *self, size_t n_args, const mp self->outbuf_waveform = DAC_OUTPUTBUFFER_DISABLE; } - // reset state of DAC - self->state = DAC_STATE_RESET; - return mp_const_none; } @@ -251,25 +303,25 @@ STATIC mp_obj_t pyb_dac_make_new(const mp_obj_type_t *type, size_t n_args, size_ } } - pyb_dac_obj_t *dac = m_new_obj(pyb_dac_obj_t); - dac->base.type = &pyb_dac_type; - + uint32_t dac_channel; if (dac_id == 1) { - dac->pin = pin_A4; - dac->dac_channel = DAC_CHANNEL_1; - dac->tx_dma_descr = &dma_DAC_1_TX; + dac_channel = DAC_CHANNEL_1; } else if (dac_id == 2) { - dac->pin = pin_A5; - dac->dac_channel = DAC_CHANNEL_2; - dac->tx_dma_descr = &dma_DAC_2_TX; + dac_channel = DAC_CHANNEL_2; } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "DAC(%d) doesn't exist", dac_id)); } - // configure the peripheral - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - pyb_dac_init_helper(dac, n_args - 1, args + 1, &kw_args); + pyb_dac_obj_t *dac = &pyb_dac_obj[dac_id - 1]; + dac->base.type = &pyb_dac_type; + dac->dac_channel = dac_channel; + + if (dac->bits == 0 || n_args > 1 || n_kw > 0) { + // configure the peripheral + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + pyb_dac_init_helper(dac, n_args - 1, args + 1, &kw_args); + } // return object return MP_OBJ_FROM_PTR(dac); @@ -284,21 +336,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_dac_init_obj, 1, pyb_dac_init); /// Turn off the DAC, enable other use of pin. STATIC mp_obj_t pyb_dac_deinit(mp_obj_t self_in) { pyb_dac_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (self->dac_channel == DAC_CHANNEL_1) { - DAC_Handle.Instance->CR &= ~DAC_CR_EN1; - #if defined(STM32H7) || defined(STM32L4) - DAC->MCR = (DAC->MCR & ~(7 << DAC_MCR_MODE1_Pos)) | 2 << DAC_MCR_MODE1_Pos; - #else - DAC_Handle.Instance->CR |= DAC_CR_BOFF1; - #endif - } else { - DAC_Handle.Instance->CR &= ~DAC_CR_EN2; - #if defined(STM32H7) || defined(STM32L4) - DAC->MCR = (DAC->MCR & ~(7 << DAC_MCR_MODE2_Pos)) | 2 << DAC_MCR_MODE2_Pos; - #else - DAC_Handle.Instance->CR |= DAC_CR_BOFF2; - #endif - } + dac_deinit(self->dac_channel); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_dac_deinit_obj, pyb_dac_deinit); @@ -313,19 +351,9 @@ STATIC mp_obj_t pyb_dac_noise(mp_obj_t self_in, mp_obj_t freq) { // set TIM6 to trigger the DAC at the given frequency TIM6_Config(mp_obj_get_int(freq)); - if (self->state != DAC_STATE_BUILTIN_WAVEFORM) { - // configure DAC to trigger via TIM6 - DAC_ChannelConfTypeDef config; - config.DAC_Trigger = DAC_TRIGGER_T6_TRGO; - config.DAC_OutputBuffer = self->outbuf_waveform; - HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel); - self->state = DAC_STATE_BUILTIN_WAVEFORM; - } - - // set noise wave generation - HAL_DACEx_NoiseWaveGenerate(&DAC_Handle, self->dac_channel, DAC_LFSRUNMASK_BITS10_0); - HAL_DAC_SetValue(&DAC_Handle, self->dac_channel, DAC_ALIGN_12B_L, 0x7ff0); - HAL_DAC_Start(&DAC_Handle, self->dac_channel); + // Configure DAC in noise mode with trigger via TIM6 + uint32_t cr = DAC_LFSRUNMASK_BITS11_0 | DAC_CR_WAVE1_0 | DAC_TRIGGER_T6_TRGO; + pyb_dac_reconfigure(self, cr, self->outbuf_waveform, 0); return mp_const_none; } @@ -343,19 +371,9 @@ STATIC mp_obj_t pyb_dac_triangle(mp_obj_t self_in, mp_obj_t freq) { // set TIM6 to trigger the DAC at the given frequency TIM6_Config(mp_obj_get_int(freq)); - if (self->state != DAC_STATE_BUILTIN_WAVEFORM) { - // configure DAC to trigger via TIM6 - DAC_ChannelConfTypeDef config; - config.DAC_Trigger = DAC_TRIGGER_T6_TRGO; - config.DAC_OutputBuffer = self->outbuf_waveform; - HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel); - self->state = DAC_STATE_BUILTIN_WAVEFORM; - } - - // set triangle wave generation - HAL_DACEx_TriangleWaveGenerate(&DAC_Handle, self->dac_channel, DAC_TRIANGLEAMPLITUDE_1023); - HAL_DAC_SetValue(&DAC_Handle, self->dac_channel, DAC_ALIGN_12B_R, 0x100); - HAL_DAC_Start(&DAC_Handle, self->dac_channel); + // Configure DAC in triangle mode with trigger via TIM6 + uint32_t cr = DAC_TRIANGLEAMPLITUDE_4095 | DAC_CR_WAVE1_1 | DAC_TRIGGER_T6_TRGO; + pyb_dac_reconfigure(self, cr, self->outbuf_waveform, 0); return mp_const_none; } @@ -367,20 +385,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_dac_triangle_obj, pyb_dac_triangle); STATIC mp_obj_t pyb_dac_write(mp_obj_t self_in, mp_obj_t val) { pyb_dac_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (self->state != DAC_STATE_WRITE_SINGLE) { - DAC_ChannelConfTypeDef config; - config.DAC_Trigger = DAC_TRIGGER_NONE; - config.DAC_OutputBuffer = self->outbuf_single; - HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel); - self->state = DAC_STATE_WRITE_SINGLE; - } - // DAC output is always 12-bit at the hardware level, and we provide support // for multiple bit "resolutions" simply by shifting the input value. - HAL_DAC_SetValue(&DAC_Handle, self->dac_channel, DAC_ALIGN_12B_R, - mp_obj_get_int(val) << (12 - self->bits)); - - HAL_DAC_Start(&DAC_Handle, self->dac_channel); + uint32_t cr = DAC_TRIGGER_NONE; + uint32_t value = mp_obj_get_int(val) << (12 - self->bits); + pyb_dac_reconfigure(self, cr, self->outbuf_single, value); return mp_const_none; } @@ -432,83 +441,24 @@ mp_obj_t pyb_dac_write_timed(size_t n_args, const mp_obj_t *pos_args, mp_map_t * dac_trigger = TIMx_Config(args[1].u_obj); } - __HAL_RCC_DMA1_CLK_ENABLE(); - - DMA_HandleTypeDef DMA_Handle; - /* Get currently configured dma */ - dma_init_handle(&DMA_Handle, self->tx_dma_descr, DMA_MEMORY_TO_PERIPH, (void*)NULL); - /* - DMA_Cmd(DMA_Handle->Instance, DISABLE); - while (DMA_GetCmdStatus(DMA_Handle->Instance) != DISABLE) { - } - - DAC_Cmd(self->dac_channel, DISABLE); - */ - - /* - // DAC channel configuration - DAC_InitTypeDef DAC_InitStructure; - DAC_InitStructure.DAC_Trigger = DAC_Trigger_T7_TRGO; - DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; - DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_1; // unused, but need to set it to a valid value - DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; - DAC_Init(self->dac_channel, &DAC_InitStructure); - */ - - // Need to deinit DMA first - DMA_Handle.State = HAL_DMA_STATE_READY; - HAL_DMA_DeInit(&DMA_Handle); - - if (self->bits == 8) { - DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - DMA_Handle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - } else { - DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; - DMA_Handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; - } - DMA_Handle.Init.Mode = args[2].u_int; - HAL_DMA_Init(&DMA_Handle); + dac_config_channel(self->dac_channel, DAC_CR_DMAEN1 | dac_trigger, self->outbuf_waveform); + const dma_descr_t *tx_dma_descr; if (self->dac_channel == DAC_CHANNEL_1) { - __HAL_LINKDMA(&DAC_Handle, DMA_Handle1, DMA_Handle); + tx_dma_descr = &dma_DAC_1_TX; } else { - __HAL_LINKDMA(&DAC_Handle, DMA_Handle2, DMA_Handle); - } - - DAC_Handle.Instance = DAC; - DAC_Handle.State = HAL_DAC_STATE_RESET; - HAL_DAC_Init(&DAC_Handle); - - if (self->state != DAC_STATE_DMA_WAVEFORM + dac_trigger) { - DAC_ChannelConfTypeDef config; - config.DAC_Trigger = dac_trigger; - config.DAC_OutputBuffer = self->outbuf_waveform; - HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel); - self->state = DAC_STATE_DMA_WAVEFORM + dac_trigger; + tx_dma_descr = &dma_DAC_2_TX; } + uint32_t align; if (self->bits == 8) { - HAL_DAC_Start_DMA(&DAC_Handle, self->dac_channel, - (uint32_t*)bufinfo.buf, bufinfo.len, DAC_ALIGN_8B_R); + align = DAC_ALIGN_8B_R; } else { - HAL_DAC_Start_DMA(&DAC_Handle, self->dac_channel, - (uint32_t*)bufinfo.buf, bufinfo.len / 2, DAC_ALIGN_12B_R); + align = DAC_ALIGN_12B_R; + bufinfo.len /= 2; } - /* - // enable DMA stream - DMA_Cmd(DMA_Handle->Instance, ENABLE); - while (DMA_GetCmdStatus(DMA_Handle->Instance) == DISABLE) { - } - - // enable DAC channel - DAC_Cmd(self->dac_channel, ENABLE); - - // enable DMA for DAC channel - DAC_DMACmd(self->dac_channel, ENABLE); - */ - - //printf("DMA: %p %lu\n", bufinfo.buf, bufinfo.len); + dac_start_dma(self->dac_channel, tx_dma_descr, args[2].u_int, self->bits, align, bufinfo.len, bufinfo.buf); return mp_const_none; } diff --git a/ports/stm32/dac.h b/ports/stm32/dac.h index 1d8f0ab61..fca36e019 100644 --- a/ports/stm32/dac.h +++ b/ports/stm32/dac.h @@ -26,8 +26,6 @@ #ifndef MICROPY_INCLUDED_STM32_DAC_H #define MICROPY_INCLUDED_STM32_DAC_H -void dac_init(void); - extern const mp_obj_type_t pyb_dac_type; #endif // MICROPY_INCLUDED_STM32_DAC_H diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c index 3b8b74081..a4ddcc42f 100644 --- a/ports/stm32/dma.c +++ b/ports/stm32/dma.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2015 Damien P. George + * Copyright (c) 2015-2019 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,6 +29,7 @@ #include <stdint.h> #include "py/obj.h" +#include "py/mphal.h" #include "systick.h" #include "dma.h" #include "irq.h" @@ -729,3 +730,100 @@ static void dma_idle_handler(uint32_t tick) { } } } + +#if defined(STM32F0) || defined(STM32L4) + +void dma_nohal_init(const dma_descr_t *descr, uint32_t config) { + DMA_Channel_TypeDef *dma = descr->instance; + + // Enable the DMA peripheral + dma_enable_clock(descr->id); + + // Set main configuration register + dma->CCR = + descr->init->Priority // PL + | descr->init->MemInc // MINC + | descr->init->PeriphInc // PINC + | config // MSIZE | PSIZE | CIRC | DIR + ; + + // Select channel that the DMA stream uses + #if defined(STM32F0) + if (dma < DMA2_Channel1) { + __HAL_DMA1_REMAP(descr->sub_instance); + } else { + __HAL_DMA2_REMAP(descr->sub_instance); + } + #else + DMA_Request_TypeDef *dma_ctrl = (void*)(((uint32_t)dma & ~0xff) + (DMA1_CSELR_BASE - DMA1_BASE)); // DMA1_CSELR or DMA2_CSELR + uint32_t channel_number = (((uint32_t)dma & 0xff) - 0x08) / 20; // 0 through 6 + uint32_t channel_pos = channel_number * 4; + dma_ctrl->CSELR = (dma_ctrl->CSELR & ~(0xf << channel_pos)) | (descr->sub_instance << channel_pos); + #endif +} + +void dma_nohal_deinit(const dma_descr_t *descr) { + DMA_Channel_TypeDef *dma = descr->instance; + dma->CCR &= ~DMA_CCR_EN; + dma->CCR = 0; + dma->CNDTR = 0; + dma_deinit(descr); +} + +void dma_nohal_start(const dma_descr_t *descr, uint32_t src_addr, uint32_t dst_addr, uint16_t len) { + DMA_Channel_TypeDef *dma = descr->instance; + dma->CNDTR = len; + dma->CPAR = dst_addr; + dma->CMAR = src_addr; + dma->CCR |= DMA_CCR_EN; +} + +#else + +void dma_nohal_init(const dma_descr_t *descr, uint32_t config) { + DMA_Stream_TypeDef *dma = descr->instance; + + // Enable the DMA peripheral + dma_enable_clock(descr->id); + + // Set main configuration register + const DMA_InitTypeDef *init = descr->init; + dma->CR = + descr->sub_instance // CHSEL + | init->MemBurst // MBURST + | init->PeriphBurst // PBURST + | init->Priority // PL + | init->MemInc // MINC + | init->PeriphInc // PINC + | config // MSIZE | PSIZE | CIRC | DIR + ; + + // Set FIFO control register + dma->FCR = + init->FIFOMode // DMDIS + | init->FIFOThreshold // FTH + ; +} + +void dma_nohal_deinit(const dma_descr_t *descr) { + DMA_Stream_TypeDef *dma = descr->instance; + dma->CR &= ~DMA_SxCR_EN; + uint32_t t0 = mp_hal_ticks_ms(); + while ((dma->CR & DMA_SxCR_EN) && mp_hal_ticks_ms() - t0 < 100) { + } + dma->CR = 0; + dma->NDTR = 0; + dma->FCR = 0x21; + dma_deinit(descr); +} + +void dma_nohal_start(const dma_descr_t *descr, uint32_t src_addr, uint32_t dst_addr, uint16_t len) { + DMA_Stream_TypeDef *dma = descr->instance; + dma->CR &= ~DMA_SxCR_DBM; + dma->NDTR = len; + dma->PAR = dst_addr; + dma->M0AR = src_addr; + dma->CR |= DMA_SxCR_EN; +} + +#endif diff --git a/ports/stm32/dma.h b/ports/stm32/dma.h index 73cb9c328..7b74a7399 100644 --- a/ports/stm32/dma.h +++ b/ports/stm32/dma.h @@ -86,4 +86,8 @@ void dma_init_handle(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint3 void dma_deinit(const dma_descr_t *dma_descr); void dma_invalidate_channel(const dma_descr_t *dma_descr); +void dma_nohal_init(const dma_descr_t *descr, uint32_t config); +void dma_nohal_deinit(const dma_descr_t *descr); +void dma_nohal_start(const dma_descr_t *descr, uint32_t src_addr, uint32_t dst_addr, uint16_t len); + #endif // MICROPY_INCLUDED_STM32_DMA_H diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 8c2d7d529..6fa6a6267 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -721,10 +721,6 @@ soft_reset: servo_init(); #endif - #if MICROPY_HW_ENABLE_DAC - dac_init(); - #endif - #if MICROPY_PY_NETWORK mod_network_init(); #endif |