diff options
author | Yuuki NAGAO <wf.yn386@gmail.com> | 2025-07-22 20:14:14 +0900 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2025-08-18 13:11:01 +1000 |
commit | 1b35116c920550ba7bfc0f06bd4bad7d20f33b21 (patch) | |
tree | 76b2e9767ecca3552ac86fef885a6006f3f9eb6a | |
parent | 1588c455c41b445bfd1c65b5055847ab63114c96 (diff) |
stm32/dac: Fix 12-bit DAC issue on STM32H5.
For STM32H5, to use 12-bit DAC, the DMA parameter should set:
- Actual DMA source datawidth to CTR1.
- The length is the amount of data to be transferred from source to
destination in bytes.
Also, this commit modifies the (dummy) definition of DMA_CIRCULAR for
STM32H5 to prevent conflict with data width specification.
Signed-off-by: Yuuki NAGAO <wf.yn386@gmail.com>
-rw-r--r-- | ports/stm32/dac.c | 7 | ||||
-rw-r--r-- | ports/stm32/dma.c | 4 | ||||
-rw-r--r-- | ports/stm32/dma.h | 2 |
3 files changed, 8 insertions, 5 deletions
diff --git a/ports/stm32/dac.c b/ports/stm32/dac.c index 54d5acc6c..0be0fd930 100644 --- a/ports/stm32/dac.c +++ b/ports/stm32/dac.c @@ -174,7 +174,7 @@ static void dac_start_dma(uint32_t dac_channel, const dma_descr_t *dma_descr, ui // For STM32G4, DAC registers have to be accessed by words (32-bit). dma_align = DMA_MDATAALIGN_BYTE | DMA_PDATAALIGN_WORD; #elif defined(STM32H5) - dma_align = 0; + dma_align = DMA_SRC_DATAWIDTH_BYTE | DMA_DEST_DATAWIDTH_WORD; #else dma_align = DMA_MDATAALIGN_BYTE | DMA_PDATAALIGN_BYTE; #endif @@ -183,7 +183,7 @@ static void dac_start_dma(uint32_t dac_channel, const dma_descr_t *dma_descr, ui // For STM32G4, DAC registers have to be accessed by words (32-bit). dma_align = DMA_MDATAALIGN_HALFWORD | DMA_PDATAALIGN_WORD; #elif defined(STM32H5) - dma_align = 0; + dma_align = DMA_SRC_DATAWIDTH_HALFWORD | DMA_DEST_DATAWIDTH_WORD; #else dma_align = DMA_MDATAALIGN_HALFWORD | DMA_PDATAALIGN_HALFWORD; #endif @@ -490,7 +490,10 @@ mp_obj_t pyb_dac_write_timed(size_t n_args, const mp_obj_t *pos_args, mp_map_t * align = DAC_ALIGN_8B_R; } else { align = DAC_ALIGN_12B_R; + // For STM32H5, the length is the amount of data to be transferred from source to destination in bytes. + #if !defined(STM32H5) bufinfo.len /= 2; + #endif } dac_start_dma(self->dac_channel, tx_dma_descr, args[2].u_int, self->bits, align, bufinfo.len, bufinfo.buf); diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c index c25277074..c2923f7ae 100644 --- a/ports/stm32/dma.c +++ b/ports/stm32/dma.c @@ -1737,10 +1737,10 @@ void dma_nohal_init(const dma_descr_t *descr, uint32_t config) { dma->CCR = init->Priority; uint32_t ctr1reg = 0; - ctr1reg |= init->SrcDataWidth; + ctr1reg |= config & DMA_CTR1_SDW_LOG2_Msk; ctr1reg |= init->SrcInc; ctr1reg |= (((init->SrcBurstLength - 1) << DMA_CTR1_SBL_1_Pos)) & DMA_CTR1_SBL_1_Msk; - ctr1reg |= init->DestDataWidth; + ctr1reg |= config & DMA_CTR1_DDW_LOG2_Msk; ctr1reg |= init->DestInc; ctr1reg |= (((init->DestBurstLength - 1) << DMA_CTR1_DBL_1_Pos)) & DMA_CTR1_DBL_1_Msk; diff --git a/ports/stm32/dma.h b/ports/stm32/dma.h index f05b22b5d..75e007bc9 100644 --- a/ports/stm32/dma.h +++ b/ports/stm32/dma.h @@ -33,7 +33,7 @@ typedef struct _dma_descr_t dma_descr_t; #if defined(STM32H5) // STM32H5 GPDMA doesn't feature circular mode directly, so define doesn't exist in // stm32 driver header. Define it here to make users like DAC driver happy. -#define DMA_CIRCULAR 0x00000001 +#define DMA_CIRCULAR 0x20000000 #endif #if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32G0) || defined(STM32H5) || defined(STM32H7) |