diff --git a/include/libopencm3/stm32/common/dac_common_all.h b/include/libopencm3/stm32/common/dac_common_all.h index 2f555e34..fc3ca40c 100644 --- a/include/libopencm3/stm32/common/dac_common_all.h +++ b/include/libopencm3/stm32/common/dac_common_all.h @@ -2,6 +2,8 @@ @author @htmlonly © @endhtmlonly 2012 Felix Held +@author @htmlonly © @endhtmlonly 2020 +Ben Brewer */ @@ -9,6 +11,7 @@ Felix Held * This file is part of the libopencm3 project. * * Copyright (C) 2012 Felix Held + * Copyright (C) 2020 Ben Brewer * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -39,48 +42,48 @@ specific memorymap.h header before including this header file.*/ /* --- DAC registers ------------------------------------------------------- */ /* DAC control register (DAC_CR) */ -#define DAC_CR MMIO32(DAC_BASE + 0x00) +#define DAC_CR(dac) MMIO32((dac) + 0x00) /* DAC software trigger register (DAC_SWTRIGR) */ -#define DAC_SWTRIGR MMIO32(DAC_BASE + 0x04) +#define DAC_SWTRIGR(dac) MMIO32((dac) + 0x04) /* DAC channel1 12-bit right-aligned data holding register (DAC_DHR12R1) */ -#define DAC_DHR12R1 MMIO32(DAC_BASE + 0x08) +#define DAC_DHR12R1(dac) MMIO32((dac) + 0x08) /* DAC channel1 12-bit left aligned data holding register (DAC_DHR12L1) */ -#define DAC_DHR12L1 MMIO32(DAC_BASE + 0x0C) +#define DAC_DHR12L1(dac) MMIO32((dac) + 0x0C) /* DAC channel1 8-bit right aligned data holding register (DAC_DHR8R1) */ -#define DAC_DHR8R1 MMIO32(DAC_BASE + 0x10) +#define DAC_DHR8R1(dac) MMIO32((dac) + 0x10) /* DAC channel2 12-bit right aligned data holding register (DAC_DHR12R2) */ -#define DAC_DHR12R2 MMIO32(DAC_BASE + 0x14) +#define DAC_DHR12R2(dac) MMIO32((dac) + 0x14) /* DAC channel2 12-bit left aligned data holding register (DAC_DHR12L2) */ -#define DAC_DHR12L2 MMIO32(DAC_BASE + 0x18) +#define DAC_DHR12L2(dac) MMIO32((dac) + 0x18) /* DAC channel2 8-bit right-aligned data holding register (DAC_DHR8R2) */ -#define DAC_DHR8R2 MMIO32(DAC_BASE + 0x1C) +#define DAC_DHR8R2(dac) MMIO32((dac) + 0x1C) /* Dual DAC 12-bit right-aligned data holding register (DAC_DHR12RD) */ -#define DAC_DHR12RD MMIO32(DAC_BASE + 0x20) +#define DAC_DHR12RD(dac) MMIO32((dac) + 0x20) /* DUAL DAC 12-bit left aligned data holding register (DAC_DHR12LD) */ -#define DAC_DHR12LD MMIO32(DAC_BASE + 0x24) +#define DAC_DHR12LD(dac) MMIO32((dac) + 0x24) /* DUAL DAC 8-bit right aligned data holding register (DAC_DHR8RD) */ -#define DAC_DHR8RD MMIO32(DAC_BASE + 0x28) +#define DAC_DHR8RD(dac) MMIO32((dac) + 0x28) /* DAC channel1 data output register (DAC_DOR1) */ -#define DAC_DOR1 MMIO32(DAC_BASE + 0x2C) +#define DAC_DOR1(dac) MMIO32((dac) + 0x2C) /* DAC channel2 data output register (DAC_DOR2) */ -#define DAC_DOR2 MMIO32(DAC_BASE + 0x30) +#define DAC_DOR2(dac) MMIO32((dac) + 0x30) /** DAC status register. * @note not available on F1 */ -#define DAC_SR MMIO32(DAC_BASE + 0x34) +#define DAC_SR(dac) MMIO32((dac) + 0x34) /* --- DAC_CR values ------------------------------------------------------- */ @@ -92,221 +95,28 @@ specific memorymap.h header before including this header file.*/ #define DAC_CR_DMAEN2 (1 << 28) /* MAMP2[3:0]: DAC channel2 mask/amplitude selector */ -/* DAC_CR_MAMP2_n: - * Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**n)-1 - */ #define DAC_CR_MAMP2_SHIFT 24 -/** @defgroup dac_mamp2 DAC Channel 2 LFSR Mask and Triangle Wave Amplitude -values -@ingroup dac_defines - -Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n)-1 -@{*/ -#define DAC_CR_MAMP2_1 (0x0 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_2 (0x1 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_3 (0x2 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_4 (0x3 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_5 (0x4 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_6 (0x5 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_7 (0x6 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_8 (0x7 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_9 (0x8 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_10 (0x9 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_11 (0xA << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_12 (0xB << DAC_CR_MAMP2_SHIFT) -/**@}*/ /* WAVE2[1:0]: DAC channel2 noise/triangle wave generation enable */ -/* Legend: - * DIS: wave generation disabled - * NOISE: Noise wave generation enabled - * TRI: Triangle wave generation enabled - * - * Note: only used if bit TEN2 = 1 (DAC channel2 trigger enabled) - */ #define DAC_CR_WAVE2_SHIFT 22 -#define DAC_CR_WAVE2_DIS (0x3 << DAC_CR_WAVE2_SHIFT) -/** @defgroup dac_wave2_en DAC Channel 2 Waveform Generation Enable -@ingroup dac_defines - -@li NOISE: Noise wave generation enabled -@li TRI: Triangle wave generation enabled - -@note: only used if bit TEN2 is set (DAC channel2 trigger enabled) -@{*/ -#define DAC_CR_WAVE2_NOISE (0x1 << DAC_CR_WAVE2_SHIFT) -#define DAC_CR_WAVE2_TRI (0x2 << DAC_CR_WAVE2_SHIFT) -/**@}*/ - -/* TSEL2[2:0]: DAC channel2 trigger selection */ -/* Legend: - * - * T6: Timer 6 TRGO event - * T3: Timer 3 TRGO event - * T8: Timer 8 TRGO event - * T7: Timer 7 TRGO event - * T5: Timer 5 TRGO event - * T15: Timer 15 TRGO event - * T2: Timer 2 TRGO event - * T4: Timer 4 TRGO event - * E9: External line9 - * SW: Software trigger - * - * Note: only used if bit TEN2 = 1 (DAC channel2 trigger enabled) - * Note: T3 == T8; T5 == T15; not both present on one device - * Note: this is *not* valid for the STM32L1 family - */ -#define DAC_CR_TSEL2_SHIFT 19 -/** @defgroup dac_trig2_sel DAC Channel 2 Trigger Source Selection -@ingroup dac_defines - -@li T6: Timer 6 TRGO event -@li T3: Timer 3 TRGO event -@li T8: Timer 8 TRGO event -@li T7: Timer 7 TRGO event -@li T5: Timer 5 TRGO event -@li T15: Timer 15 TRGO event -@li T2: Timer 2 TRGO event -@li T4: Timer 4 TRGO event -@li E9: External line9 -@li SW: Software trigger - -@note: Refer to the timer documentation for details of the TRGO event. -@note: T3 replaced by T8 and T5 replaced by T15 in some devices. -@note: this is not valid for the STM32L1 family. -@note: only used if bit TEN2 is set (DAC channel 2 trigger enabled) -@{*/ -#define DAC_CR_TSEL2_T6 (0x0 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_T3 (0x1 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_T8 (0x1 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_T7 (0x2 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_T5 (0x3 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_T15 (0x3 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_T2 (0x4 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_T4 (0x5 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_E9 (0x6 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_SW (0x7 << DAC_CR_TSEL2_SHIFT) -/**@}*/ - -/* TEN2: DAC channel2 trigger enable */ -#define DAC_CR_TEN2 (1 << 18) - -/* BOFF2: DAC channel2 output buffer disable */ -#define DAC_CR_BOFF2 (1 << 17) +#define DAC_CR_WAVE2_MASK 0x3 /* EN2: DAC channel2 enable */ #define DAC_CR_EN2 (1 << 16) /* DMAUDRIE1: DAC channel1 DMA underrun interrupt enable */ /* doesn't exist in most members of the STM32F1 family */ -#define DAC_CR_DMAUDRIE1 (1 << 13) +#define DAC_CR_DMAUDRIE1 (1 << 13) /* DMAEN1: DAC channel1 DMA enable */ #define DAC_CR_DMAEN1 (1 << 12) /* MAMP1[3:0]: DAC channel1 mask/amplitude selector */ -/* DAC_CR_MAMP1_n: - * Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**n)-1 - */ #define DAC_CR_MAMP1_SHIFT 8 -/** @defgroup dac_mamp1 DAC Channel 1 LFSR Mask and Triangle Wave Amplitude -values -@ingroup dac_defines -Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n+1)-1 -@{*/ -#define DAC_CR_MAMP1_1 (0x0 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_2 (0x1 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_3 (0x2 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_4 (0x3 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_5 (0x4 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_6 (0x5 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_7 (0x6 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_8 (0x7 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_9 (0x8 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_10 (0x9 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_11 (0xA << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_12 (0xB << DAC_CR_MAMP1_SHIFT) -/**@}*/ - -/* WAVE1[1:0]: DAC channel1 noise/triangle wave generation enable */ -/* Legend: - * DIS: wave generation disabled - * NOISE: Noise wave generation enabled - * TRI: Triangle wave generation enabled - * - * Note: only used if bit TEN1 = 1 (DAC channel1 trigger enabled) - */ +/* WAVEn[1:0]: DAC channel1 noise/triangle wave generation enable */ #define DAC_CR_WAVE1_SHIFT 6 -#define DAC_CR_WAVE1_DIS (0x3 << DAC_CR_WAVE1_SHIFT) -/** @defgroup dac_wave1_en DAC Channel 1 Waveform Generation Enable -@ingroup dac_defines - -@li DIS: wave generation disabled -@li NOISE: Noise wave generation enabled -@li TRI: Triangle wave generation enabled - -@note: only used if bit TEN2 = 1 (DAC channel2 trigger enabled) -@{*/ -#define DAC_CR_WAVE1_NOISE (0x1 << DAC_CR_WAVE1_SHIFT) -#define DAC_CR_WAVE1_TRI (0x2 << DAC_CR_WAVE1_SHIFT) -/**@}*/ - -/* TSEL1[2:0]: DAC channel1 trigger selection */ -/* Legend: - * - * T6: Timer 6 TRGO event - * T3: Timer 3 TRGO event in connectivity line devices - * T8: Timer 8 TRGO event in high-density and XL-density devices - * T7: Timer 7 TRGO event - * T5: Timer 5 TRGO event - * T15: Timer 15 TRGO event - * T2: Timer 2 TRGO event - * T4: Timer 4 TRGO event - * E9: External line9 - * SW: Software trigger - * - * Note: only used if bit TEN1 = 1 (DAC channel1 trigger enabled) - * Note: T3 == T8; T5 == T15; not both present on one device - * Note: this is *not* valid for the STM32L1 family - */ -#define DAC_CR_TSEL1_SHIFT 3 -/** @defgroup dac_trig1_sel DAC Channel 1 Trigger Source Selection -@ingroup dac_defines - -@li T6: Timer 6 TRGO event -@li T3: Timer 3 TRGO event -@li T8: Timer 8 TRGO event -@li T7: Timer 7 TRGO event -@li T5: Timer 5 TRGO event -@li T15: Timer 15 TRGO event -@li T2: Timer 2 TRGO event -@li T4: Timer 4 TRGO event -@li E9: External line 9 -@li SW: Software trigger - -@note: Refer to the timer documentation for details of the TRGO event. -@note: T3 replaced by T8 and T5 replaced by T15 in some devices. -@note: this is not valid for the STM32L1 family. -@note: only used if bit TEN2 is set (DAC channel 1 trigger enabled). -@{*/ -#define DAC_CR_TSEL1_T6 (0x0 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_T3 (0x1 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_T8 (0x1 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_T7 (0x2 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_T5 (0x3 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_T15 (0x3 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_T2 (0x4 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_T4 (0x5 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_E9 (0x6 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_SW (0x7 << DAC_CR_TSEL1_SHIFT) -/**@}*/ - -/* TEN1: DAC channel1 trigger enable */ -#define DAC_CR_TEN1 (1 << 2) - -/* BOFF1: DAC channel1 output buffer disable */ -#define DAC_CR_BOFF1 (1 << 1) +#define DAC_CR_WAVE1_MASK 0x3 /* EN1: DAC channel1 enable */ #define DAC_CR_EN1 (1 << 0) @@ -322,105 +132,114 @@ Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n+1)-1 /* --- DAC_DHR12R1 values -------------------------------------------------- */ -#define DAC_DHR12R1_DACC1DHR_LSB (1 << 0) -#define DAC_DHR12R1_DACC1DHR_MSK (0x0FFF << 0) +#define DAC_DHR12R1_DACC1DHR_SHIFT 0 +#define DAC_DHR12R1_DACC1DHR_MASK 0xFFF /* --- DAC_DHR12L1 values -------------------------------------------------- */ -#define DAC_DHR12L1_DACC1DHR_LSB (1 << 4) -#define DAC_DHR12L1_DACC1DHR_MSK (0x0FFF << 4) +#define DAC_DHR12L1_DACC1DHR_SHIFT 4 +#define DAC_DHR12L1_DACC1DHR_MASK 0xFFF /* --- DAC_DHR8R1 values --------------------------------------------------- */ -#define DAC_DHR8R1_DACC1DHR_LSB (1 << 0) -#define DAC_DHR8R1_DACC1DHR_MSK (0x00FF << 0) +#define DAC_DHR8R1_DACC1DHR_SHIFT 0 +#define DAC_DHR8R1_DACC1DHR_MASK 0xFF /* --- DAC_DHR12R2 values -------------------------------------------------- */ -#define DAC_DHR12R2_DACC2DHR_LSB (1 << 0) -#define DAC_DHR12R2_DACC2DHR_MSK (0x00FFF << 0) +#define DAC_DHR12R2_DACC2DHR_SHIFT 0 +#define DAC_DHR12R2_DACC2DHR_MASK 0xFFF /* --- DAC_DHR12L2 values -------------------------------------------------- */ -#define DAC_DHR12L2_DACC2DHR_LSB (1 << 4) -#define DAC_DHR12L2_DACC2DHR_MSK (0x0FFF << 4) +#define DAC_DHR12L2_DACC2DHR_SHIFT 4 +#define DAC_DHR12L2_DACC2DHR_MASK 0xFFF /* --- DAC_DHR8R2 values --------------------------------------------------- */ -#define DAC_DHR8R2_DACC2DHR_LSB (1 << 0) -#define DAC_DHR8R2_DACC2DHR_MSK (0x00FF << 0) +#define DAC_DHR8R2_DACC2DHR_SHIFT 0 +#define DAC_DHR8R2_DACC2DHR_MASK 0xFF /* --- DAC_DHR12RD values -------------------------------------------------- */ -#define DAC_DHR12RD_DACC2DHR_LSB (1 << 16) -#define DAC_DHR12RD_DACC2DHR_MSK (0x0FFF << 16) -#define DAC_DHR12RD_DACC1DHR_LSB (1 << 0) -#define DAC_DHR12RD_DACC1DHR_MSK (0x0FFF << 0) +#define DAC_DHR12RD_DACC2DHR_SHIFT 16 +#define DAC_DHR12RD_DACC2DHR_MASK 0xFFF +#define DAC_DHR12RD_DACC1DHR_SHIFT 0 +#define DAC_DHR12RD_DACC1DHR_MSK 0xFFF /* --- DAC_DHR12LD values -------------------------------------------------- */ -#define DAC_DHR12LD_DACC2DHR_LSB (1 << 16) -#define DAC_DHR12LD_DACC2DHR_MSK (0x0FFF << 20) -#define DAC_DHR12LD_DACC1DHR_LSB (1 << 0) -#define DAC_DHR12LD_DACC1DHR_MSK (0x0FFF << 4) +#define DAC_DHR12LD_DACC2DHR_SHIFT 16 +#define DAC_DHR12LD_DACC2DHR_MSK 0xFFF +#define DAC_DHR12LD_DACC1DHR_SHIFT 0 +#define DAC_DHR12LD_DACC1DHR_MSK 0xFFF /* --- DAC_DHR8RD values --------------------------------------------------- */ -#define DAC_DHR8RD_DACC2DHR_LSB (1 << 8) -#define DAC_DHR8RD_DACC2DHR_MSK (0x00FF << 8) -#define DAC_DHR8RD_DACC1DHR_LSB (1 << 0) -#define DAC_DHR8RD_DACC1DHR_MSK (0x00FF << 0) +#define DAC_DHR8RD_DACC2DHR_SHIFT 8 +#define DAC_DHR8RD_DACC2DHR_MSK 0xFF +#define DAC_DHR8RD_DACC1DHR_SHIFT 0 +#define DAC_DHR8RD_DACC1DHR_MSK 0xFF /* --- DAC_DOR1 values ----------------------------------------------------- */ -#define DAC_DOR1_DACC1DOR_LSB (1 << 0) -#define DAC_DOR1_DACC1DOR_MSK (0x0FFF << 0) +#define DAC_DOR1_DACC1DOR_SHIFT 0 +#define DAC_DOR1_DACC1DOR_MSK 0xFFF /* --- DAC_DOR2 values ----------------------------------------------------- */ -#define DAC_DOR2_DACC2DOR_LSB (1 << 0) -#define DAC_DOR2_DACC2DOR_MSK (0x0FFF << 0) +#define DAC_DOR2_DACC2DOR_SHIFT 0 +#define DAC_DOR2_DACC2DOR_MSK 0xFFF + +/* --- DAC_SR values ------------------------------------------------------- */ -/** @defgroup dac_sr_values DAC_SR Values -@{*/ /** DAC channel 1 DMA underrun flag */ -#define DAC_SR_DMAUDR1 (1 << 13) +#define DAC_SR_DMAUDR1 (1 << 13) /** DAC channel 2 DMA underrun flag */ -#define DAC_SR_DMAUDR2 (1 << 29) -/**@}*/ - -/** DAC channel identifier */ -typedef enum { - CHANNEL_1, CHANNEL_2, CHANNEL_D -} data_channel; - -/** DAC data size (8/12 bits), alignment (right/left) */ -typedef enum { - RIGHT8, RIGHT12, LEFT12 -} data_align; +#define DAC_SR_DMAUDR2 (1 << 29) /* --- Function prototypes ------------------------------------------------- */ +/** DAC channel identifier */ +#define DAC_CHANNEL1 (1 << 0) +#define DAC_CHANNEL2 (1 << 1) +#define DAC_CHANNEL_BOTH (DAC_CHANNEL1 | DAC_CHANNEL2) + +/** DAC data size (8/12 bits), alignment (right/left) */ +enum dac_align { + DAC_ALIGN_RIGHT8, + DAC_ALIGN_RIGHT12, + DAC_ALIGN_LEFT12, +}; + +/* DAC waveform generation options. */ +enum dac_wave { + DAC_WAVE_DISABLE = 0, + DAC_WAVE_NOISE = 1, + DAC_WAVE_TRIANGLE = 2, + DAC_WAVE_SAWTOOTH = 3, +}; + BEGIN_DECLS -void dac_enable(data_channel dac_channel); -void dac_disable(data_channel dac_channel); -void dac_buffer_enable(data_channel dac_channel); -void dac_buffer_disable(data_channel dac_channel); -void dac_dma_enable(data_channel dac_channel); -void dac_dma_disable(data_channel dac_channel); -void dac_trigger_enable(data_channel dac_channel); -void dac_trigger_disable(data_channel dac_channel); -void dac_set_trigger_source(uint32_t dac_trig_src); -void dac_set_waveform_generation(uint32_t dac_wave_ens); -void dac_disable_waveform_generation(data_channel dac_channel); -void dac_set_waveform_characteristics(uint32_t dac_mamp); -void dac_load_data_buffer_single(uint16_t dac_data, data_align dac_data_format, - data_channel dac_channel); -void dac_load_data_buffer_dual(uint16_t dac_data1, uint16_t dac_data2, - data_align dac_data_format); -void dac_software_trigger(data_channel dac_channel); +void dac_enable(uint32_t dac, int channel); +void dac_disable(uint32_t dac, int channel); +void dac_buffer_enable(uint32_t dac, int channel); +void dac_buffer_disable(uint32_t dac, int channel); +void dac_dma_enable(uint32_t dac, int channel); +void dac_dma_disable(uint32_t dac, int channel); +void dac_trigger_enable(uint32_t dac, int channel); +void dac_trigger_disable(uint32_t dac, int channel); +void dac_set_trigger_source(uint32_t dac, uint32_t source); +void dac_set_waveform_generation(uint32_t dac, enum dac_wave wave); +void dac_disable_waveform_generation(uint32_t dac, int channel); +void dac_set_waveform_characteristics(uint32_t dac, uint8_t mamp); +void dac_load_data_buffer_single(uint32_t dac, uint16_t data, + enum dac_align align, int channel); +void dac_load_data_buffer_dual(uint32_t dac, uint16_t data1, uint16_t data2, + enum dac_align align); +void dac_software_trigger(uint32_t dac, int channel); END_DECLS diff --git a/include/libopencm3/stm32/common/dac_common_v1.h b/include/libopencm3/stm32/common/dac_common_v1.h new file mode 100644 index 00000000..38101fb0 --- /dev/null +++ b/include/libopencm3/stm32/common/dac_common_v1.h @@ -0,0 +1,136 @@ +/** @addtogroup dac_defines + +@author @htmlonly © @endhtmlonly 2020 +Ben Brewer + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2020 Ben Brewer + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA DAC.H +The order of header inclusion is important. dac.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_DAC_H +/** @endcond */ +#ifndef LIBOPENCM3_DAC_COMMON_V1_H +#define LIBOPENCM3_DAC_COMMON_V1_H + +#include + +/* --- DAC_CR values ------------------------------------------------------- */ + +/* TSEL2[2:0]: DAC channel2 trigger selection */ +#define DAC_CR_TSEL2_SHIFT 19 +/** @defgroup dac_trig2_sel DAC Channel 2 Trigger Source Selection +@ingroup dac_defines + +@li T6: Timer 6 TRGO event +@li T3: Timer 3 TRGO event +@li T8: Timer 8 TRGO event +@li T7: Timer 7 TRGO event +@li T5: Timer 5 TRGO event +@li T15: Timer 15 TRGO event +@li T2: Timer 2 TRGO event +@li T4: Timer 4 TRGO event +@li E9: External line9 +@li SW: Software trigger + +@note: Refer to the timer documentation for details of the TRGO event. +@note: T3 replaced by T8 and T5 replaced by T15 in some devices. +@note: this is not valid for the STM32L1 family. +@note: only used if bit TEN2 is set (DAC channel 2 trigger enabled) +@{*/ +#define DAC_CR_TSEL2_T6 (0x0 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T3 (0x1 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T8 (0x1 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T7 (0x2 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T5 (0x3 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T15 (0x3 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T2 (0x4 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T4 (0x5 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_E9 (0x6 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_SW (0x7 << DAC_CR_TSEL2_SHIFT) +/**@}*/ + +/* TEN2: DAC channel2 trigger enable */ +#define DAC_CR_TEN2 (1 << 18) + +/* BOFF2: DAC channel2 output buffer disable */ +#define DAC_CR_BOFF2 (1 << 17) + +/* TSEL1[2:0]: DAC channel1 trigger selection */ +#define DAC_CR_TSEL1_SHIFT 3 +/** @defgroup dac_trig1_sel DAC Channel 1 Trigger Source Selection +@ingroup dac_defines + +@li T6: Timer 6 TRGO event +@li T3: Timer 3 TRGO event +@li T8: Timer 8 TRGO event +@li T7: Timer 7 TRGO event +@li T5: Timer 5 TRGO event +@li T15: Timer 15 TRGO event +@li T2: Timer 2 TRGO event +@li T4: Timer 4 TRGO event +@li E9: External line 9 +@li SW: Software trigger + +@note: Refer to the timer documentation for details of the TRGO event. +@note: T3 replaced by T8 and T5 replaced by T15 in some devices. +@note: this is not valid for the STM32L1 family. +@note: only used if bit TEN1 is set (DAC channel 1 trigger enabled). +@{*/ +#define DAC_CR_TSEL1_T6 (0x0 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T3 (0x1 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T8 (0x1 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T7 (0x2 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T5 (0x3 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T15 (0x3 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T2 (0x4 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T4 (0x5 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_E9 (0x6 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_SW (0x7 << DAC_CR_TSEL1_SHIFT) +/**@}*/ + +/* TEN1: DAC channel1 trigger enable */ +#define DAC_CR_TEN1 (1 << 2) + +/* BOFF1: DAC channel1 output buffer disable */ +#define DAC_CR_BOFF1 (1 << 1) + + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +END_DECLS + +#endif +/** @cond */ +#else +#warning "dac_common_v1.h should not be included explicitly, only via dac.h" +#endif +/** @endcond */ + +/**@}*/ + diff --git a/include/libopencm3/stm32/common/dac_common_v2.h b/include/libopencm3/stm32/common/dac_common_v2.h new file mode 100644 index 00000000..cc5453eb --- /dev/null +++ b/include/libopencm3/stm32/common/dac_common_v2.h @@ -0,0 +1,570 @@ +/** @addtogroup dac_defines + +@author @htmlonly © @endhtmlonly 2020 +Ben Brewer + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2020 Ben Brewer + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA DAC.H +The order of header inclusion is important. dac.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_DAC_H +/** @endcond */ +#ifndef LIBOPENCM3_DAC_COMMON_V2_H +#define LIBOPENCM3_DAC_COMMON_V2_H + +#include + +/* --- DAC registers ------------------------------------------------------- */ + +/* DAC calibration control register (DAC_CCR) */ +#define DAC_CCR(dac) MMIO32((dac) + 0x38) + +/* DAC mode control register (DAC_MCR) */ +#define DAC_MCR(dac) MMIO32((dac) + 0x3C) + +/* DAC channel1 sample and hold sample time register (DAC_SHSR1) */ +#define DAC_SHSR1(dac) MMIO32((dac) + 0x40) + +/* DAC channel2 sample and hold sample time register (DAC_SHSR2) */ +#define DAC_SHSR2(dac) MMIO32((dac) + 0x44) + +/* DAC sample and hold time register (DAC_SHHR) */ +#define DAC_SHHR(dac) MMIO32((dac) + 0x48) + +/* DAC sample and hold refresh time register (DAC_SHRR) */ +#define DAC_SHRR(dac) MMIO32((dac) + 0x4C) + +/* DAC channel1 sawtooth register (DAC_STR1) */ +#define DAC_STR1(dac) MMIO32((dac) + 0x58) + +/* DAC channel2 sawtooth register (DAC_STR2) */ +#define DAC_STR2(dac) MMIO32((dac) + 0x5C) + +/* DAC sawtooth mode register (DAC_STMODR) */ +#define DAC_STMODR(dac) MMIO32((dac) + 0x60) + +/* --- DAC_CR values ------------------------------------------------------- */ + +/* CEN2: DAC channel2 calibration enable */ +#define DAC_CR_CEN2 (1 << 30) + +/* TSEL2[3:0]: DAC channel2 trigger selection */ +#define DAC_CR_TSEL2_SHIFT 18 +/** @defgroup dac_trig2_sel DAC Channel 2 Trigger Source Selection +@ingroup dac_defines + +@li SW: Software trigger +@li T8: Timer 8 TRGO event +@li T7: Timer 7 TRGO event +@li T15: Timer 15 TRGO event +@li T2: Timer 2 TRGO event +@li T4: Timer 4 TRGO event +@li E9: External line 9 +@li T6: Timer 6 TRGO event +@li T3: Timer 3 TRGO event +@li HRR1: hrtim_dac_reset_trg1 +@li HRR2: hrtim_dac_reset_trg2 +@li HRR3: hrtim_dac_reset_trg3 +@li HRR4: hrtim_dac_reset_trg4 +@li HRR5: hrtim_dac_reset_trg5 +@li HRR6: hrtim_dac_reset_trg6 +@li HR2: hrtim_dac_trg2 + +@note: only used if bit TEN2 is set (DAC channel 2 trigger enabled) +@{*/ +#define DAC_CR_TSEL2_SW (0x0 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T8 (0x1 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T7 (0x2 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T15 (0x3 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T2 (0x4 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T4 (0x5 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_E9 (0x6 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T6 (0x7 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T3 (0x8 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_HRR1 (0x9 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_HRR2 (0xA << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_HRR3 (0xB << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_HRR4 (0xC << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_HRR5 (0xD << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_HRR6 (0xE << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_HR2 (0xF << DAC_CR_TSEL2_SHIFT) +/**@}*/ + +/* TEN2: DAC channel2 trigger enable */ +#define DAC_CR_TEN2 (1 << 17) + +/* CEN1: DAC channel1 calibration enable */ +#define DAC_CR_CEN1 (1 << 14) + +/* TSEL1[3:0]: DAC channel1 trigger selection */ +#define DAC_CR_TSEL1_SHIFT 2 +/** @defgroup dac_trig1_sel DAC Channel 1 Trigger Source Selection +@ingroup dac_defines + +@li CK: ck_lsi or ck_lse (selected in the RCC) +@li T8: Timer 8 TRGO event +@li T7: Timer 7 TRGO event in connectivity line devices +@li T15: Timer 15 TRGO event in high-density and XL-density devices +@li T2: Timer 2 TRGO event +@li T4: Timer 4 TRGO event +@li E9: External line9 +@li T6: Timer 6 TRGO event +@li T3: Timer 3 TRGO event +@li HRR1: hrtim_dac_reset_trg1 +@li HRR2: hrtim_dac_reset_trg2 +@li HRR3: hrtim_dac_reset_trg3 +@li HRR4: hrtim_dac_reset_trg4 +@li HRR5: hrtim_dac_reset_trg5 +@li HRR6: hrtim_dac_reset_trg6 +@li HR2: hrtim_dac_trg2 + +@note: only used if bit TEN1 is set (DAC channel 1 trigger enabled). +@{*/ +#define DAC_CR_TSEL1_CK (0x0 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T8 (0x1 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T7 (0x2 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T15 (0x3 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T2 (0x4 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T4 (0x5 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_E9 (0x6 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T6 (0x7 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T3 (0x8 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_HRR1 (0x9 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_HRR2 (0xA << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_HRR3 (0xB << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_HRR4 (0xC << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_HRR5 (0xD << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_HRR6 (0xE << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_HR3 (0xF << DAC_CR_TSEL1_SHIFT) +/**@}*/ + +/* TEN1: DAC channel1 trigger enable */ +#define DAC_CR_TEN1 (1 << 1) + + +/* --- DAC_SWTRIGR values -------------------------------------------------- */ + +/* SWTRIG2: DAC channel2 software trigger B */ +#define DAC_SWTRIGR_SWTRIGB2 (1 << 17) + +/* SWTRIG1: DAC channel1 software trigger B */ +#define DAC_SWTRIGR_SWTRIGB1 (1 << 16) + + +/* --- DAC_DOR1 values ----------------------------------------------------- */ +#define DAC_DOR1_DACC1DORB_SHIFT 16 +#define DAC_DOR1_DACC1DORB_MASK 0xFFF + + +/* --- DAC_DOR2 values ----------------------------------------------------- */ +#define DAC_DOR2_DACC2DORB_SHIFT 16 +#define DAC_DOR2_DACC2DORB_MASK 0xFFF + +/* --- DAC_SR values ----------------------------------------------------- */ + +/* DAC channel2 busy writing sample time flag */ +#define DAC_SR_BWST2 (1 << 31) + +/* DAC channel2 calibration offset status */ +#define DAC_SR_CAL_FLAG2 (1 << 30) + +/** DAC channel2 DMA underrun flag */ +#define DAC_SR_DMAUDR2 (1 << 29) + +/* DAC channel2 output register status bit */ +#define DAC_SR_DORSTAT2 (1 << 28) + +/* DAC channel2 ready status bit */ +#define DAC_SR_DAC2RDY (1 << 27) + +/* DAC channel1 busy writing sample time flag */ +#define DAC_SR_BWST1 (1 << 15) + +/* DAC channel1 calibration offset status */ +#define DAC_SR_CAL_FLAG1 (1 << 14) + +/** DAC channel1 DMA underrun flag */ +#define DAC_SR_DMAUDR1 (1 << 13) + +/* DAC channel1 output register status bit */ +#define DAC_SR_DORSTAT1 (1 << 12) + +/* DAC channel1 ready status bit */ +#define DAC_SR_DAC1RDY (1 << 11) + +/* --- DAC_CCR values ----------------------------------------------------- */ + +/* DAC channel2 offset trimming value */ +#define DAC_CCR_OTRIM2_SHIFT 16 +#define DAC_CCR_OTRIM2_MASK 0x1F + +/* DAC channel1 offset trimming value */ +#define DAC_CCR_OTRIM1_SHIFT 0 +#define DAC_CCR_OTRIM1_MASK 0x1F + +/* --- DAC_MCR values ----------------------------------------------------- */ + +/* Enable signed format for DAC channel2 */ +#define DAC_MCR_SINFORMAT2 (1 << 25) + +/* DAC channel2 DMA double data mode */ +#define DAC_MCR_DMADOUBLE2 (1 << 24) + +/* MODE2[2:0]: DAC channel2 mode */ +#define DAC_MCR_MODE2_SHIFT 16 +/** @defgroup dac_mode2_sel DAC Channel 2 Mode Selection +@ingroup dac_defines + +@li E_BUFF: External pin with buffer enabled +@li EP_BUFF: External pin and on-chip peripherals with buffer +@li E: External pin without buffer +@li EP: External pin and on-chip peripherals without buffer +@li SH_E_BUFF: Sample & Hold, External pin with buffer enabled +@li SH_EP_BUFF: Sample & Hold, External pin and on-chip peripherals with buffer +@li SH_E: Sample & Hold, External pin without buffer +@li SH_EP: Sample & Hold, External pin and on-chip peripherals without buffer +@{*/ +#define DAC_MCR_MODE2_E_BUFF (0x0 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_EP_BUFF (0x1 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_E (0x2 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_EP (0x3 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_SH_E_BUFF (0x4 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_SH_EP_BUFF (0x5 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_SH_E (0x6 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_SH_EP (0x7 << DAC_MCR_MODE2_SHIFT) +/**@}*/ + +#define DAC_MCR_MODE2_PERIPHERAL (0x1 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_UNBUFFERED (0x2 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_SAMPLEHOLD (0x4 << DAC_MCR_MODE2_SHIFT) + +/* HFSEL[1:0]: High frequency interface mode selection */ +#define DAC_MCR_HFSEL_SHIFT 14 +#define DAC_MCR_HFSEL_MASK 0x3 +/** @defgroup dac_hfsel High frequency interface mode selection +@ingroup dac_defines + +@li DIS: High frequency mode disabled +@li AHB80: High frequency interface mode compatible to AHB>80MHz enabled +@li AHB160: High frequency interface mode compatible to AHB>160MHz enabled +@{*/ +#define DAC_MCR_HFSEL_DIS (0x0 << DAC_MCR_HFSEL_SHIFT) +#define DAC_MCR_HFSEL_AHB80 (0x1 << DAC_MCR_HFSEL_SHIFT) +#define DAC_MCR_HFSEL_AHB160 (0x2 << DAC_MCR_HFSEL_SHIFT) +/**@}*/ + +/* Enable signed format for DAC channel1 */ +#define DAC_MCR_SINFORMAT1 (1 << 9) + +/* DAC channel1 DMA double data mode */ +#define DAC_MCR_DMADOUBLE1 (1 << 8) + +/* MODE1[2:0]: DAC channel1 mode */ +#define DAC_MCR_MODE1_SHIFT 0 +/** @defgroup dac_mode1_sel DAC Channel 1 Mode Selection +@ingroup dac_defines + +@li E_BUFF: External pin with buffer enabled +@li EP_BUFF: External pin and on-chip peripherals with buffer +@li E: External pin without buffer +@li EP: External pin and on-chip peripherals without buffer +@li SH_E_BUFF: Sample & Hold, External pin with buffer enabled +@li SH_EP_BUFF: Sample & Hold, External pin and on-chip peripherals with buffer +@li SH_E: Sample & Hold, External pin without buffer +@li SH_EP: Sample & Hold , External pin and on-chip peripherals without buffer +@{*/ +#define DAC_MCR_MODE1_E_BUFF (0x0 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_EP_BUFF (0x1 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_E (0x2 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_EP (0x3 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_SH_E_BUFF (0x4 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_SH_EP_BUFF (0x5 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_SH_E (0x6 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_SH_EP (0x7 << DAC_MCR_MODE1_SHIFT) +/**@}*/ + +#define DAC_MCR_MODE1_PERIPHERAL (0x1 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_UNBUFFERED (0x2 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_SAMPLEHOLD (0x4 << DAC_MCR_MODE1_SHIFT) + +/* --- DAC_SHSR1 values ----------------------------------------------------- */ + +/* DAC channel1 sample time (only valid in Sample and hold mode) */ +#define DAC_SHSR1_TSAMPLE1_SHIFT 0 +#define DAC_SHSR1_TSAMPLE1_MASK 0x1FF + +/* --- DAC_SHSR2 values ----------------------------------------------------- */ + +/* DAC channel2 sample time (only valid in Sample and hold mode) */ +#define DAC_SHSR2_TSAMPLE2_SHIFT 0 +#define DAC_SHSR2_TSAMPLE2_MASK 0x1FF + +/* --- DAC_SHHR values ----------------------------------------------------- */ + +/* DAC channel2 hold time (only valid in Sample and hold mode) */ +#define DAC_SHHSR_THOLD2_SHIFT 16 +#define DAC_SHHSR_THOLD2_MASK 0x1FF + +/* DAC channel1 hold time (only valid in Sample and hold mode) */ +#define DAC_SHHSR_THOLD1_SHIFT 0 +#define DAC_SHHSR_THOLD1_MASK 0x1FF + +/* --- DAC_STR1 values ----------------------------------------------------- */ + +/* DAC channel1 sawtooth increment value (12.4 bit format) */ +#define DAC_STR1_STINCDATA1_SHIFT 16 +#define DAC_STR1_STINCDATA1_MASK 0xFFFF + +/* STDIR1: DAC channel1 sawtooth direction setting */ +#define DAC_STR1_STDIR1_SHIFT 12 +/** @defgroup dac_stdir1 DAC Channel 1 Sawtooth Direction Setting +@ingroup dac_defines + +@li DEC: Decrement +@li INC: Increment +@{*/ +#define DAC_STR1_STDIR1_DEC (0x0 << DAC_STR_STDIR1_SHIFT) +#define DAC_STR1_STDIR1_INC (0x1 << DAC_STR_STDIR1_SHIFT) +/**@}*/ + +/* DAC channel1 sawtooth reset value */ +#define DAC_STR1_STRSTDATA1_SHIFT 0 +#define DAC_STR1_STRSTDATA1_MASK 0xFFF + +/* --- DAC_STR2 values ----------------------------------------------------- */ + +/* DAC channel2 sawtooth increment value (12.4 bit format) */ +#define DAC_STR2_STINCDATA2_SHIFT 16 +#define DAC_STR2_STINCDATA2_MASK 0xFFFF + +/* STDIR1: DAC channel2 sawtooth direction setting */ +#define DAC_STR2_STDIR2_SHIFT 12 +/** @defgroup dac_stdir2 DAC Channel 2 Sawtooth Direction Setting +@ingroup dac_defines + +@li DEC: Decrement +@li INC: Increment +@{*/ +#define DAC_STR2_STDIR2_DEC (0x0 << DAC_STR_STDIR2_SHIFT) +#define DAC_STR2_STDIR2_INC (0x1 << DAC_STR_STDIR2_SHIFT) +/**@}*/ + +/* DAC channel1 sawtooth reset value */ +#define DAC_STR2_STRSTDATA2_SHIFT 0 +#define DAC_STR2_STRSTDATA2_MASK 0xFFF + +/* --- DAC_STMODR values ----------------------------------------------------- */ + +/* STINCTRIGSEL2[3:0]: DAC channel2 sawtooth increment trigger selection */ +#define DAC_STMODR_STINCTRIGSEL2_SHIFT 24 +/** @defgroup dac_sawtooth2_inc DAC Channel 2 Sawtooth Increment Trigger +@ingroup dac_defines + +@li SW: SWTRIGB2 +@li T1: dac_inc_ch2_trg1 +@li T2: dac_inc_ch2_trg2 +@li T3: dac_inc_ch2_trg3 +@li T4: dac_inc_ch2_trg4 +@li T5: dac_inc_ch2_trg5 +@li T6: dac_inc_ch2_trg6 +@li T7: dac_inc_ch2_trg7 +@li T8: dac_inc_ch2_trg8 +@li T9: dac_inc_ch2_trg9 +@li T10: dac_inc_ch2_trg10 +@li T11: dac_inc_ch2_trg11 +@li T12: dac_inc_ch2_trg12 +@li T13: dac_inc_ch2_trg13 +@li T14: dac_inc_ch2_trg14 +@li T15: dac_inc_ch2_trg15 + +@note: These bits are only available only on dual-channel DACs. +@{*/ +#define DAC_STMODR_STINCTRIGSEL2_SW (0x0 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T1 (0x1 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T2 (0x2 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T3 (0x3 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T4 (0x4 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T5 (0x5 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T6 (0x6 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T7 (0x7 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T8 (0x8 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T9 (0x9 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T10 (0xA << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T11 (0xB << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T12 (0xC << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T13 (0xD << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T14 (0xE << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T15 (0xF << DAC_STMODR_STINCTRIGSEL2_SHIFT) +/**@}*/ + +/* STRSTTRIGSEL2[3:0]: DAC channel2 sawtooth reset trigger selection */ +#define DAC_STMODR_STRSTTRIGSEL2_SHIFT 16 +/** @defgroup dac_sawtooth2_rst DAC Channel 2 Sawtooth Reset Trigger +@ingroup dac_defines + +@li SW: SWTRIGB2 +@li T1: dac_ch2_trg1 +@li T2: dac_ch2_trg2 +@li T3: dac_ch2_trg3 +@li T4: dac_ch2_trg4 +@li T5: dac_ch2_trg5 +@li T6: dac_ch2_trg6 +@li T7: dac_ch2_trg7 +@li T8: dac_ch2_trg8 +@li T9: dac_ch2_trg9 +@li T10: dac_ch2_trg10 +@li T11: dac_ch2_trg11 +@li T12: dac_ch2_trg12 +@li T13: dac_ch2_trg13 +@li T14: dac_ch2_trg14 +@li T15: dac_ch2_trg15 + +@note: These bits are only available only on dual-channel DACs. +@{*/ +#define DAC_STMODR_STRSTTRIGSEL2_SW (0x0 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T1 (0x1 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T2 (0x2 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T3 (0x3 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T4 (0x4 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T5 (0x5 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T6 (0x6 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T7 (0x7 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T8 (0x8 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T9 (0x9 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T10 (0xA << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T11 (0xB << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T12 (0xC << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T13 (0xD << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T14 (0xE << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T15 (0xF << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +/**@}*/ + + +/* STINCTRIGSEL1[3:0]: DAC channel1 sawtooth increment trigger selection */ +#define DAC_STMODR_STINCTRIGSEL1_SHIFT 8 +/** @defgroup dac_sawtooth2_inc DAC Channel 1 Sawtooth Increment Trigger +@ingroup dac_defines + +@li SW: SWTRIGB2 +@li T1: dac_inc_ch1_trg1 +@li T2: dac_inc_ch1_trg2 +@li T3: dac_inc_ch1_trg3 +@li T4: dac_inc_ch1_trg4 +@li T5: dac_inc_ch1_trg5 +@li T6: dac_inc_ch1_trg6 +@li T7: dac_inc_ch1_trg7 +@li T8: dac_inc_ch1_trg8 +@li T9: dac_inc_ch1_trg9 +@li T10: dac_inc_ch1_trg10 +@li T11: dac_inc_ch1_trg11 +@li T12: dac_inc_ch1_trg12 +@li T13: dac_inc_ch1_trg13 +@li T14: dac_inc_ch1_trg14 +@li T15: dac_inc_ch1_trg15 + +@note: These bits are only available only on dual-channel DACs. +@{*/ +#define DAC_STMODR_STINCTRIGSEL1_SW (0x0 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T1 (0x1 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T2 (0x2 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T3 (0x3 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T4 (0x4 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T5 (0x5 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T6 (0x6 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T7 (0x7 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T8 (0x8 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T9 (0x9 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T10 (0xA << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T11 (0xB << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T12 (0xC << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T13 (0xD << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T14 (0xE << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T15 (0xF << DAC_STMODR_STINCTRIGSEL1_SHIFT) +/**@}*/ + +/* STRSTTRIGSEL1[3:0]: DAC channel1 sawtooth reset trigger selection */ +#define DAC_STMODR_STRSTTRIGSEL1_SHIFT 0 +/** @defgroup dac_sawtooth2_rst DAC Channel 1 Sawtooth Reset Trigger +@ingroup dac_defines + +@li SW: SWTRIGB2 +@li T1: dac_ch1_trg1 +@li T2: dac_ch1_trg2 +@li T3: dac_ch1_trg3 +@li T4: dac_ch1_trg4 +@li T5: dac_ch1_trg5 +@li T6: dac_ch1_trg6 +@li T7: dac_ch1_trg7 +@li T8: dac_ch1_trg8 +@li T9: dac_ch1_trg9 +@li T10: dac_ch1_trg10 +@li T11: dac_ch1_trg11 +@li T12: dac_ch1_trg12 +@li T13: dac_ch1_trg13 +@li T14: dac_ch1_trg14 +@li T15: dac_ch1_trg15 + +@note: These bits are only available only on dual-channel DACs. +@{*/ +#define DAC_STMODR_STRSTTRIGSEL1_SW (0x0 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T1 (0x1 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T2 (0x2 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T3 (0x3 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T4 (0x4 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T5 (0x5 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T6 (0x6 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T7 (0x7 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T8 (0x8 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T9 (0x9 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T10 (0xA << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T11 (0xB << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T12 (0xC << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T13 (0xD << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T14 (0xE << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T15 (0xF << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +/**@}*/ + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void dac_set_mode(uint32_t dac, uint32_t mode); +bool dac_is_ready(uint32_t dac, int channel); +void dac_wait_on_ready(uint32_t dac, int channel); +void dac_set_high_frequency_mode(uint32_t dac, uint32_t hfsel); + +END_DECLS + +#endif +/** @cond */ +#else +#warning "dac_common_v2.h should not be included explicitly, only via dac.h" +#endif +/** @endcond */ + +/**@}*/ + diff --git a/include/libopencm3/stm32/dac.h b/include/libopencm3/stm32/dac.h index 196d2e8e..a3efb12e 100644 --- a/include/libopencm3/stm32/dac.h +++ b/include/libopencm3/stm32/dac.h @@ -36,6 +36,8 @@ # include #elif defined(STM32L4) # include +#elif defined(STM32G4) +# include #elif defined(STM32H7) # include #else diff --git a/include/libopencm3/stm32/f0/dac.h b/include/libopencm3/stm32/f0/dac.h index 7f544843..74b334c5 100644 --- a/include/libopencm3/stm32/f0/dac.h +++ b/include/libopencm3/stm32/f0/dac.h @@ -33,26 +33,13 @@ #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include /*****************************************************************************/ /* Module definitions */ /*****************************************************************************/ -#define DAC DAC_BASE - -/*****************************************************************************/ -/* Register definitions */ -/*****************************************************************************/ - -#define DAC_CR MMIO32(DAC_BASE + 0x00) -#define DAC_SWTRIGR MMIO32(DAC_BASE + 0x04) -#define DAC_DHR12R1 MMIO32(DAC_BASE + 0x08) -#define DAC_DHR12L1 MMIO32(DAC_BASE + 0x0C) -#define DAC_DHR8R1 MMIO32(DAC_BASE + 0x10) -#define DAC_DOR1 MMIO32(DAC_BASE + 0x2C) -#define DAC_SR MMIO32(DAC_BASE + 0x34) - +#define DAC1 DAC_BASE /*****************************************************************************/ /* Register values */ @@ -60,10 +47,6 @@ /* DAC_CR Values ------------------------------------------------------------*/ -#define DAC_CR_DMAUDRIE1 (1 << 13) -#define DAC_CR_DMAEN1 (1 << 12) - -#define DAC_CR_TSEL1_SHIFT 3 #define DAC_CR_TSEL1 (7 << DAC_CR_TSEL1_SHIFT) #define DAC_CR_TSEL1_TIM6_TRGO (0 << DAC_CR_TSEL1_SHIFT) #define DAC_CR_TSEL1_TIM8_TRGO (1 << DAC_CR_TSEL1_SHIFT) @@ -74,44 +57,4 @@ #define DAC_CR_TSEL1_EXT_9 (6 << DAC_CR_TSEL1_SHIFT) #define DAC_CR_TSEL1_SWTRG (7 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TEN1 (1 << 2) -#define DAC_CR_BOFF1 (1 << 1) -#define DAC_CR_EN1 (1 << 0) - -/* DAC_SWTRIGR Values -------------------------------------------------------*/ - -#define DAC_SWTRIGR_SWTRIG1 (1 << 0) - -/* DAC_DHR12R1 Values -------------------------------------------------------*/ - -#define DAC_DHR12R1_DACC1DHR 0xFFF - -/* DAC_DHR12L1 Values -------------------------------------------------------*/ - -#define DAC_DHR12L1_DACC1DHR (0xFFF << 4) - -/* DAC_DHR8R1 Values --------------------------------------------------------*/ - -#define DAC_DHR8R1_DACC1DHR 0xFF - -/* DAC_DOR1 Values ----------------------------------------------------------*/ - -#define DAC_DOR1_DACC1DOR 0xFFF - -/* DAC_SR Values ------------------------------------------------------------*/ - -#define DAC_SR_DMAUDR1 (1 << 13) - -/*****************************************************************************/ -/* API definitions */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* API Functions */ -/*****************************************************************************/ - -BEGIN_DECLS - -END_DECLS - #endif diff --git a/include/libopencm3/stm32/f1/dac.h b/include/libopencm3/stm32/f1/dac.h index 145df731..4db221be 100644 --- a/include/libopencm3/stm32/f1/dac.h +++ b/include/libopencm3/stm32/f1/dac.h @@ -31,7 +31,13 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC_BASE #endif diff --git a/include/libopencm3/stm32/f2/dac.h b/include/libopencm3/stm32/f2/dac.h index 5d148a6d..60bf6924 100644 --- a/include/libopencm3/stm32/f2/dac.h +++ b/include/libopencm3/stm32/f2/dac.h @@ -31,7 +31,13 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC_BASE #endif diff --git a/include/libopencm3/stm32/f3/dac.h b/include/libopencm3/stm32/f3/dac.h index aceea8c5..ab82f494 100644 --- a/include/libopencm3/stm32/f3/dac.h +++ b/include/libopencm3/stm32/f3/dac.h @@ -31,7 +31,14 @@ #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/** @defgroup dac_reg_base DAC register base addresses +@ingroup STM32xx_dac_defines +@{*/ +#define DAC1 DAC1_BASE +#define DAC2 DAC2_BASE +/**@}*/ #endif diff --git a/include/libopencm3/stm32/f3/memorymap.h b/include/libopencm3/stm32/f3/memorymap.h index 369192e3..877cd8dc 100644 --- a/include/libopencm3/stm32/f3/memorymap.h +++ b/include/libopencm3/stm32/f3/memorymap.h @@ -63,8 +63,9 @@ /* PERIPH_BASE_APB1 + 0x6800 (0x4000 6800 - 0x4000 6BFF): Reserved */ /* PERIPH_BASE_APB1 + 0x6C00 (0x4000 6C00 - 0x4000 6FFF): Reserved */ #define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000) -#define DAC_BASE (PERIPH_BASE_APB1 + 0x7400) +#define DAC1_BASE (PERIPH_BASE_APB1 + 0x7400) #define I2C3_BASE (PERIPH_BASE_APB1 + 0x7800) +#define DAC2_BASE (PERIPH_BASE_APB1 + 0x9800) /* PERIPH_BASE_APB1 + 0x7800 (0x4000 7800 - 0x4000 7FFF): Reserved */ diff --git a/include/libopencm3/stm32/f4/dac.h b/include/libopencm3/stm32/f4/dac.h index 3a384032..c6279636 100644 --- a/include/libopencm3/stm32/f4/dac.h +++ b/include/libopencm3/stm32/f4/dac.h @@ -31,6 +31,12 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC_BASE #endif diff --git a/include/libopencm3/stm32/f7/dac.h b/include/libopencm3/stm32/f7/dac.h index 1e5607e4..5f9df3f5 100644 --- a/include/libopencm3/stm32/f7/dac.h +++ b/include/libopencm3/stm32/f7/dac.h @@ -31,6 +31,12 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC_BASE #endif diff --git a/include/libopencm3/stm32/g4/dac.h b/include/libopencm3/stm32/g4/dac.h new file mode 100644 index 00000000..bd1c1ce2 --- /dev/null +++ b/include/libopencm3/stm32/g4/dac.h @@ -0,0 +1,46 @@ +/** @defgroup dac_defines DAC Defines + +@brief Defined Constants and Types for the STM32G4xx DAC + +@ingroup STM32G4xx_defines + +@version 1.0.0 + +@date 3 August 2020 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DAC_H +#define LIBOPENCM3_DAC_H + +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC1_BASE +#define DAC2 DAC2_BASE +#define DAC3 DAC3_BASE +#define DAC4 DAC4_BASE +#define DAC5 DAC5_BASE + +#endif diff --git a/include/libopencm3/stm32/h7/dac.h b/include/libopencm3/stm32/h7/dac.h index 3106378c..834ecd77 100644 --- a/include/libopencm3/stm32/h7/dac.h +++ b/include/libopencm3/stm32/h7/dac.h @@ -31,6 +31,12 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC_BASE #endif diff --git a/include/libopencm3/stm32/l1/dac.h b/include/libopencm3/stm32/l1/dac.h index 207c59d4..267b6184 100644 --- a/include/libopencm3/stm32/l1/dac.h +++ b/include/libopencm3/stm32/l1/dac.h @@ -31,7 +31,13 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC_BASE #endif diff --git a/include/libopencm3/stm32/l4/dac.h b/include/libopencm3/stm32/l4/dac.h index 10b275a7..82cddded 100644 --- a/include/libopencm3/stm32/l4/dac.h +++ b/include/libopencm3/stm32/l4/dac.h @@ -31,7 +31,13 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC_BASE #endif diff --git a/lib/stm32/common/dac_common_all.c b/lib/stm32/common/dac_common_all.c index 0aa2277b..4e54feb9 100644 --- a/lib/stm32/common/dac_common_all.c +++ b/lib/stm32/common/dac_common_all.c @@ -1,7 +1,8 @@ /** @addtogroup dac_file DAC peripheral API * @ingroup peripheral_apis -@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies +@author @htmlonly © @endhtmlonly 2020 Ben Brewer This library supports the Digital to Analog Conversion System in the STM32 series of ARM Cortex Microcontrollers by ST Microelectronics. @@ -63,15 +64,16 @@ sent out. gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO4); rcc_periph_clock_enable(RCC_DAC); - dac_disable(CHANNEL_1); - dac_set_waveform_characteristics(DAC_CR_MAMP1_8); - dac_set_waveform_generation(DAC_CR_WAVE1_NOISE); - dac_enable(CHANNEL_1); - dac_set_trigger_source(DAC_CR_TSEL1_SW); - dac_load_data_buffer_single(0, RIGHT12, CHANNEL_1); + dac_disable(DAC1, DAC_CHANNEL1); + dac_set_waveform_characteristics(DAC1, DAC_CR_MAMP1_8); + dac_set_waveform_generation(DAC1, DAC_CR_WAVE1_NOISE); + dac_enable(DAC1, DAC_CHANNEL1); + dac_set_trigger_source(DAC1, DAC_CR_TSEL1_SW); + dac_load_data_buffer_single(DAC1, 0, DAC_ALIGN_RIGHT12, DAC_CHANNEL1); .... - dac_software_trigger(CHANNEL_1); - dac_load_data_buffer_single(value, RIGHT12, CHANNEL_1); + dac_software_trigger(DAC1, DAC_CHANNEL1); + dac_load_data_buffer_single(DAC1, value, + DAC_ALIGN_RIGHT12, DAC_CHANNEL1); @endcode @section dac_api_dma_ex Simultaneous Dual DAC with DMA. @@ -89,10 +91,10 @@ Both DAC channels are enabled, and both triggers are set to the same timer dma_set_peripheral_address(DMA2,DMA_CHANNEL3,(uint32_t) &DAC_DHR8RD); dma_enable_channel(DMA2,DMA_CHANNEL3); ... - dac_trigger_enable(CHANNEL_D); - dac_set_trigger_source(DAC_CR_TSEL1_T2 | DAC_CR_TSEL2_T2); - dac_dma_enable(CHANNEL_1); - dac_enable(CHANNEL_D); + dac_trigger_enable(DAC1, DAC_CHANNEL_BOTH); + dac_set_trigger_source(DAC1, DAC_CR_TSEL1_T2 | DAC_CR_TSEL2_T2); + dac_dma_enable(DAC1, DAC_CHANNEL1); + dac_enable(DAC1, DAC_CHANNEL_BOTH); @endcode LGPL License Terms @ref lgpl_license @@ -102,6 +104,7 @@ LGPL License Terms @ref lgpl_license * This file is part of the libopencm3 project. * * Copyright (C) 2012 Ken Sarkies + * Copyright (C) 2020 Ben Brewer * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -121,9 +124,6 @@ LGPL License Terms @ref lgpl_license #include -#define MASK8 0xFF -#define MASK12 0xFFF - /*---------------------------------------------------------------------------*/ /** @brief DAC Channel Enable. @@ -131,20 +131,21 @@ Enable a digital to analog converter channel. After setting this enable, the DAC requires a twakeup time typically around 10 microseconds before it actually wakes up. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_enable(data_channel dac_channel) +void dac_enable(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_CR |= DAC_CR_EN1; + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) |= DAC_CR_EN1; break; - case CHANNEL_2: - DAC_CR |= DAC_CR_EN2; + case DAC_CHANNEL2: + DAC_CR(dac) |= DAC_CR_EN2; break; - case CHANNEL_D: - DAC_CR |= (DAC_CR_EN1 | DAC_CR_EN2); + case DAC_CHANNEL_BOTH: + DAC_CR(dac) |= (DAC_CR_EN1 | DAC_CR_EN2); break; } } @@ -154,73 +155,27 @@ void dac_enable(data_channel dac_channel) Disable a digital to analog converter channel. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_disable(data_channel dac_channel) +void dac_disable(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_CR &= ~DAC_CR_EN1; + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) &= ~DAC_CR_EN1; break; - case CHANNEL_2: - DAC_CR &= ~DAC_CR_EN2; + case DAC_CHANNEL2: + DAC_CR(dac) &= ~DAC_CR_EN2; break; - case CHANNEL_D: - DAC_CR &= ~(DAC_CR_EN1 | DAC_CR_EN2); + case DAC_CHANNEL_BOTH: + DAC_CR(dac) &= ~(DAC_CR_EN1 | DAC_CR_EN2); + break; + default: break; } } -/*---------------------------------------------------------------------------*/ -/** @brief DAC Channel Output Buffer Enable. - -Enable a digital to analog converter channel output drive buffer. This is an -optional amplifying buffer that provides additional drive for the output -signal. The buffer is enabled by default after a reset and needs to be -explicitly disabled if required. - -@param[in] dac_channel enum ::data_channel. -*/ - -void dac_buffer_enable(data_channel dac_channel) -{ - switch (dac_channel) { - case CHANNEL_1: - DAC_CR &= ~DAC_CR_BOFF1; - break; - case CHANNEL_2: - DAC_CR &= ~DAC_CR_BOFF2; - break; - case CHANNEL_D: - DAC_CR &= ~(DAC_CR_BOFF1 | DAC_CR_BOFF2); - break; - } -} -/*---------------------------------------------------------------------------*/ -/** @brief DAC Channel Output Buffer Disable. - -Disable a digital to analog converter channel output drive buffer. Disabling -this will reduce power consumption slightly and will increase the output -impedance of the DAC. The buffers are enabled by default after a reset. - -@param[in] dac_channel enum ::data_channel. -*/ - -void dac_buffer_disable(data_channel dac_channel) -{ - switch (dac_channel) { - case CHANNEL_1: - DAC_CR |= DAC_CR_BOFF1; - break; - case CHANNEL_2: - DAC_CR |= DAC_CR_BOFF2; - break; - case CHANNEL_D: - DAC_CR |= (DAC_CR_BOFF1 | DAC_CR_BOFF2); - break; - } -} /*---------------------------------------------------------------------------*/ /** @brief DAC Channel DMA Enable. @@ -228,20 +183,23 @@ Enable a digital to analog converter channel DMA mode (connected to DMA2 channel 3 for DAC channel 1 and DMA2 channel 4 for DAC channel 2). A DMA request is generated following an external trigger. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_dma_enable(data_channel dac_channel) +void dac_dma_enable(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_CR |= DAC_CR_DMAEN1; + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) |= DAC_CR_DMAEN1; break; - case CHANNEL_2: - DAC_CR |= DAC_CR_DMAEN2; + case DAC_CHANNEL2: + DAC_CR(dac) |= DAC_CR_DMAEN2; break; - case CHANNEL_D: - DAC_CR |= (DAC_CR_DMAEN1 | DAC_CR_DMAEN2); + case DAC_CHANNEL_BOTH: + DAC_CR(dac) |= (DAC_CR_DMAEN1 | DAC_CR_DMAEN2); + break; + default: break; } } @@ -251,20 +209,23 @@ void dac_dma_enable(data_channel dac_channel) Disable a digital to analog converter channel DMA mode. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_dma_disable(data_channel dac_channel) +void dac_dma_disable(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_CR &= ~DAC_CR_DMAEN1; + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) &= ~DAC_CR_DMAEN1; break; - case CHANNEL_2: - DAC_CR &= ~DAC_CR_DMAEN2; + case DAC_CHANNEL2: + DAC_CR(dac) &= ~DAC_CR_DMAEN2; break; - case CHANNEL_D: - DAC_CR &= ~(DAC_CR_DMAEN1 | DAC_CR_DMAEN2); + case DAC_CHANNEL_BOTH: + DAC_CR(dac) &= ~(DAC_CR_DMAEN1 | DAC_CR_DMAEN2); + break; + default: break; } } @@ -277,20 +238,23 @@ an external trigger to initiate register transfers from the buffer register to the DAC output register, followed by a DMA transfer to the buffer register if DMA is enabled. The trigger source must also be selected. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_trigger_enable(data_channel dac_channel) +void dac_trigger_enable(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_CR |= DAC_CR_TEN1; + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) |= DAC_CR_TEN1; break; - case CHANNEL_2: - DAC_CR |= DAC_CR_TEN2; + case DAC_CHANNEL2: + DAC_CR(dac) |= DAC_CR_TEN2; break; - case CHANNEL_D: - DAC_CR |= (DAC_CR_TEN1 | DAC_CR_TEN2); + case DAC_CHANNEL_BOTH: + DAC_CR(dac) |= (DAC_CR_TEN1 | DAC_CR_TEN2); + break; + default: break; } } @@ -300,20 +264,23 @@ void dac_trigger_enable(data_channel dac_channel) Disable a digital to analog converter channel external trigger. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_trigger_disable(data_channel dac_channel) +void dac_trigger_disable(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_CR &= ~DAC_CR_TEN1; + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) &= ~DAC_CR_TEN1; break; - case CHANNEL_2: - DAC_CR &= ~DAC_CR_TEN2; + case DAC_CHANNEL2: + DAC_CR(dac) &= ~DAC_CR_TEN2; break; - case CHANNEL_D: - DAC_CR &= ~(DAC_CR_TEN1 | DAC_CR_TEN2); + case DAC_CHANNEL_BOTH: + DAC_CR(dac) &= ~(DAC_CR_TEN1 | DAC_CR_TEN2); + break; + default: break; } } @@ -324,14 +291,15 @@ void dac_trigger_disable(data_channel dac_channel) Sets the digital to analog converter trigger source, which can be taken from various timers, an external trigger or a software trigger. -@param[in] dac_trig_src uint32_t. Taken from @ref dac_trig2_sel or @ref +@param[in] dac uint32_t the base address of the DAC. +@param[in] source uint32_t. Taken from @ref dac_trig2_sel or @ref dac_trig1_sel or a logical OR of one of each of these to set both channels simultaneously. */ -void dac_set_trigger_source(uint32_t dac_trig_src) +void dac_set_trigger_source(uint32_t dac, uint32_t source) { - DAC_CR |= dac_trig_src; + DAC_CR(dac) |= source; } /*---------------------------------------------------------------------------*/ @@ -343,14 +311,14 @@ existing output values in the DAC output registers. @note The DAC trigger must be enabled for this to work. -@param[in] dac_wave_ens uint32_t. Taken from @ref dac_wave1_en or @ref +@param[in] wave enum ::dac_wave. Taken from @ref dac_wave1_en or @ref dac_wave2_en or a logical OR of one of each of these to set both channels simultaneously. */ -void dac_set_waveform_generation(uint32_t dac_wave_ens) +void dac_set_waveform_generation(uint32_t dac, enum dac_wave wave) { - DAC_CR |= dac_wave_ens; + DAC_CR(dac) |= wave; } /*---------------------------------------------------------------------------*/ @@ -358,20 +326,24 @@ void dac_set_waveform_generation(uint32_t dac_wave_ens) Disable a digital to analog converter channel superimposed waveform generation. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_disable_waveform_generation(data_channel dac_channel) +void dac_disable_waveform_generation(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_CR &= ~DAC_CR_WAVE1_DIS; + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) &= ~(DAC_CR_WAVE1_MASK << DAC_CR_WAVE1_SHIFT); break; - case CHANNEL_2: - DAC_CR &= ~DAC_CR_WAVE2_DIS; + case DAC_CHANNEL2: + DAC_CR(dac) &= ~(DAC_CR_WAVE2_MASK << DAC_CR_WAVE2_SHIFT); break; - case CHANNEL_D: - DAC_CR &= ~(DAC_CR_WAVE1_DIS | DAC_CR_WAVE2_DIS); + case DAC_CHANNEL_BOTH: + DAC_CR(dac) &= ~(DAC_CR_WAVE1_MASK << DAC_CR_WAVE1_SHIFT) + | ~(DAC_CR_WAVE2_MASK << DAC_CR_WAVE2_SHIFT); + break; + default: break; } } @@ -392,13 +364,14 @@ the signal output. become read-only. @note The DAC trigger must be enabled for this to work. -@param[in] dac_mamp uint32_t. Taken from @ref dac_mamp2 or @ref dac_mamp1 or a +@param[in] dac uint32_t the base address of the DAC. +@param[in] mamp uint8_t. Taken from @ref dac_mamp2 or @ref dac_mamp1 or a logical OR of one of each of these to set both channels simultaneously. */ -void dac_set_waveform_characteristics(uint32_t dac_mamp) +void dac_set_waveform_characteristics(uint32_t dac, uint8_t mamp) { - DAC_CR |= dac_mamp; + DAC_CR(dac) |= mamp; } /*---------------------------------------------------------------------------*/ @@ -410,36 +383,42 @@ data to be converted on a channel. The data can be aligned as follows: @li right-aligned 12 bit data in bits 0-11 @li left aligned 12 bit data in bits 4-15 -@param[in] dac_data uint16_t with appropriate alignment. -@param[in] dac_data_format enum ::data_align. Alignment and size. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] data uint16_t with appropriate alignment. +@param[in] align enum ::dac_align. Alignment and size. +@param[in] channel uint8_t with DAC mask. */ -void dac_load_data_buffer_single(uint16_t dac_data, data_align dac_data_format, - data_channel dac_channel) +void dac_load_data_buffer_single(uint32_t dac, uint16_t data, + enum dac_align align, + int channel) { - if (dac_channel == CHANNEL_1) { - switch (dac_data_format) { - case RIGHT8: - DAC_DHR8R1 = dac_data; + if (channel == DAC_CHANNEL1) { + switch (align) { + case DAC_ALIGN_RIGHT8: + DAC_DHR8R1(dac) = data; break; - case RIGHT12: - DAC_DHR12R1 = dac_data; + case DAC_ALIGN_RIGHT12: + DAC_DHR12R1(dac) = data; break; - case LEFT12: - DAC_DHR12L1 = dac_data; + case DAC_ALIGN_LEFT12: + DAC_DHR12L1(dac) = data; + break; + default: break; } - } else if (dac_channel == CHANNEL_2) { - switch (dac_data_format) { - case RIGHT8: - DAC_DHR8R2 = dac_data; + } else if (channel == DAC_CHANNEL2) { + switch (align) { + case DAC_ALIGN_RIGHT8: + DAC_DHR8R2(dac) = data; break; - case RIGHT12: - DAC_DHR12R2 = dac_data; + case DAC_ALIGN_RIGHT12: + DAC_DHR12R2(dac) = data; break; - case LEFT12: - DAC_DHR12L2 = dac_data; + case DAC_ALIGN_LEFT12: + DAC_DHR12L2(dac) = data; + break; + default: break; } } @@ -453,26 +432,30 @@ Loads the appropriate digital to analog converter dual data register with 12 or simultaneous or independent analog output. The data in both channels are aligned identically. -@param[in] dac_data1 uint16_t for channel 1 with appropriate alignment. -@param[in] dac_data2 uint16_t for channel 2 with appropriate alignment. -@param[in] dac_data_format enum ::data_align. Right or left aligned, and 8 or +@param[in] dac uint32_t the base address of the DAC. +@param[in] data1 uint16_t for channel 1 with appropriate alignment. +@param[in] data2 uint16_t for channel 2 with appropriate alignment. +@param[in] align enum ::dac_align. Right or left aligned, and 8 or 12 bit. */ -void dac_load_data_buffer_dual(uint16_t dac_data1, uint16_t dac_data2, - data_align dac_data_format) +void dac_load_data_buffer_dual(uint32_t dac, + uint16_t data1, uint16_t data2, + enum dac_align align) { - switch (dac_data_format) { - case RIGHT8: - DAC_DHR8RD = ((dac_data1 & MASK8) | ((dac_data2 & MASK8) << 8)); + switch (align) { + case DAC_ALIGN_RIGHT8: + DAC_DHR8RD(dac) = ((data1 & 0xFF) | ((data2 & 0xFF) << 8)); break; - case RIGHT12: - DAC_DHR12RD = ((dac_data1 & MASK12) | - ((dac_data2 & MASK12) << 16)); + case DAC_ALIGN_RIGHT12: + DAC_DHR12RD(dac) = ((data1 & 0xFFF) | + ((data2 & 0xFFF) << 16)); break; - case LEFT12: - DAC_DHR12LD = ((dac_data1 & MASK12) | - ((dac_data2 & MASK12) << 16)); + case DAC_ALIGN_LEFT12: + DAC_DHR12LD(dac) = ((data1 & 0xFFF) | + ((data2 & 0xFFF) << 16)); + break; + default: break; } } @@ -483,20 +466,23 @@ void dac_load_data_buffer_dual(uint16_t dac_data1, uint16_t dac_data2, If the trigger source is set to be a software trigger, cause a trigger to occur. The trigger is cleared by hardware after conversion. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_software_trigger(data_channel dac_channel) +void dac_software_trigger(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_SWTRIGR |= DAC_SWTRIGR_SWTRIG1; + switch (channel) { + case DAC_CHANNEL1: + DAC_SWTRIGR(dac) |= DAC_SWTRIGR_SWTRIG1; break; - case CHANNEL_2: - DAC_SWTRIGR |= DAC_SWTRIGR_SWTRIG2; + case DAC_CHANNEL2: + DAC_SWTRIGR(dac) |= DAC_SWTRIGR_SWTRIG2; break; - case CHANNEL_D: - DAC_SWTRIGR |= (DAC_SWTRIGR_SWTRIG1 | DAC_SWTRIGR_SWTRIG2); + case DAC_CHANNEL_BOTH: + DAC_SWTRIGR(dac) |= (DAC_SWTRIGR_SWTRIG1 | DAC_SWTRIGR_SWTRIG2); + break; + default: break; } } diff --git a/lib/stm32/common/dac_common_v1.c b/lib/stm32/common/dac_common_v1.c new file mode 100644 index 00000000..13c73f06 --- /dev/null +++ b/lib/stm32/common/dac_common_v1.c @@ -0,0 +1,85 @@ +/** @addtogroup dac_file DAC peripheral API + * @ingroup peripheral_apis + +@author @htmlonly © @endhtmlonly 2020 Ben Brewer + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2020 Ben Brewer + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Buffer Enable. + +Enable a digital to analog converter channel output drive buffer. This is an +optional amplifying buffer that provides additional drive for the output +signal. The buffer is enabled by default after a reset and needs to be +explicitly disabled if required. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. +*/ + +void dac_buffer_enable(uint32_t dac, int channel) +{ + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) &= ~DAC_CR_BOFF1; + break; + case DAC_CHANNEL2: + DAC_CR(dac) &= ~DAC_CR_BOFF2; + break; + case DAC_CHANNEL_BOTH: + DAC_CR(dac) &= ~(DAC_CR_BOFF1 | DAC_CR_BOFF2); + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Buffer Disable. + +Disable a digital to analog converter channel output drive buffer. Disabling +this will reduce power consumption slightly and will increase the output +impedance of the DAC. The buffers are enabled by default after a reset. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. +*/ + +void dac_buffer_disable(uint32_t dac, int channel) +{ + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) |= DAC_CR_BOFF1; + break; + case DAC_CHANNEL2: + DAC_CR(dac) |= DAC_CR_BOFF2; + break; + case DAC_CHANNEL_BOTH: + DAC_CR(dac) |= (DAC_CR_BOFF1 | DAC_CR_BOFF2); + break; + } +} +/**@}*/ + diff --git a/lib/stm32/common/dac_common_v2.c b/lib/stm32/common/dac_common_v2.c new file mode 100644 index 00000000..c7e4699e --- /dev/null +++ b/lib/stm32/common/dac_common_v2.c @@ -0,0 +1,163 @@ +/** @addtogroup dac_file DAC peripheral API + * @ingroup peripheral_apis + +@author @htmlonly © @endhtmlonly 2020 Ben Brewer + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2020 Ben Brewer + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Buffer Enable. + +Enable a digital to analog converter channel output drive buffer. This is an +optional amplifying buffer that provides additional drive for the output +signal. The buffer is enabled by default after a reset and needs to be +explicitly disabled if required. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. +*/ + +void dac_buffer_enable(uint32_t dac, int channel) +{ + switch (channel) { + case DAC_CHANNEL1: + DAC_MCR(dac) &= ~DAC_MCR_MODE1_UNBUFFERED; + break; + case DAC_CHANNEL2: + DAC_MCR(dac) &= ~DAC_MCR_MODE2_UNBUFFERED; + break; + case DAC_CHANNEL_BOTH: + DAC_MCR(dac) &= ~(DAC_MCR_MODE1_UNBUFFERED | + DAC_MCR_MODE2_UNBUFFERED); + break; + default: + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Buffer Disable. + +Disable a digital to analog converter channel output drive buffer. Disabling +this will reduce power consumption slightly and will increase the output +impedance of the DAC. The buffers are enabled by default after a reset. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. +*/ + +void dac_buffer_disable(uint32_t dac, int channel) +{ + switch (channel) { + case DAC_CHANNEL1: + DAC_MCR(dac) |= DAC_MCR_MODE1_UNBUFFERED; + break; + case DAC_CHANNEL2: + DAC_MCR(dac) |= DAC_MCR_MODE2_UNBUFFERED; + break; + case DAC_CHANNEL_BOTH: + DAC_MCR(dac) |= (DAC_MCR_MODE1_UNBUFFERED + | DAC_MCR_MODE2_UNBUFFERED); + break; + default: + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Mode. + +Each DAC channel can be configured in Normal mode or Sample and hold mode. The +output buffer can be enabled to allow a high drive capability. Before enabling +output buffer, the voltage offset needs to be calibrated. This calibration is +performed at the factory (loaded after reset) and can be adjusted by software +during application operation. + +@note This must be called before enabling the DAC as the settings will then +become read-only. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] mamp uint32_t. Taken from @ref dac_mode2_sel or @ref dac_mode1_sel or +a logical OR of one of each of these to set both channels simultaneously. +*/ + +void dac_set_mode(uint32_t dac, uint32_t mode) +{ + DAC_MCR(dac) |= mode; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Check if DAC channel is ready to receive data. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. +*/ + +bool dac_is_ready(uint32_t dac, int channel) +{ + uint32_t mask = 0; + if (channel & DAC_CHANNEL1) { + mask |= DAC_SR_DAC1RDY; + } + if (channel & DAC_CHANNEL2) { + mask |= DAC_SR_DAC2RDY; + } + + return (DAC_SR(dac) & mask) != 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Wait until DAC channel is ready to receive data. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. +*/ + +void dac_wait_on_ready(uint32_t dac, int channel) +{ + while (!dac_is_ready(dac, channel)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief High frequency interface mode selection. + +If the AHB frequency of the DAC is above 80MHz then this value needs setting +to an appropriate value. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] hfsel uint32_t with appropriate HFSEL mask. +*/ + +void dac_set_high_frequency_mode(uint32_t dac, uint32_t hfsel) +{ + uint32_t reg32 = DAC_MCR(dac); + reg32 &= ~(DAC_MCR_HFSEL_MASK << DAC_MCR_HFSEL_SHIFT); + reg32 |= hfsel; + DAC_MCR(dac) = reg32; +} +/**@}*/ + diff --git a/lib/stm32/f0/Makefile b/lib/stm32/f0/Makefile index d50f0232..ba7ce654 100644 --- a/lib/stm32/f0/Makefile +++ b/lib/stm32/f0/Makefile @@ -39,7 +39,7 @@ OBJS += can.o OBJS += comparator.o OBJS += crc_common_all.o crc_v2.o OBJS += crs_common_all.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += desig_common_all.o desig_common_v1.o OBJS += dma_common_l1f013.o dma_common_csel.o OBJS += exti_common_all.o diff --git a/lib/stm32/f1/Makefile b/lib/stm32/f1/Makefile index 9371f46e..da0419c0 100755 --- a/lib/stm32/f1/Makefile +++ b/lib/stm32/f1/Makefile @@ -37,7 +37,7 @@ ARFLAGS = rcs OBJS += adc.o adc_common_v1.o OBJS += can.o OBJS += crc_common_all.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += desig_common_all.o desig_common_v1.o OBJS += dma_common_l1f013.o OBJS += exti_common_all.o diff --git a/lib/stm32/f2/Makefile b/lib/stm32/f2/Makefile index 42fb2838..9e3203c2 100644 --- a/lib/stm32/f2/Makefile +++ b/lib/stm32/f2/Makefile @@ -36,7 +36,7 @@ ARFLAGS = rcs OBJS += crc_common_all.o OBJS += crypto_common_f24.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += desig_common_all.o desig_common_v1.o OBJS += dma_common_f24.o OBJS += exti_common_all.o diff --git a/lib/stm32/f3/Makefile b/lib/stm32/f3/Makefile index 6d6df239..f4e471cb 100644 --- a/lib/stm32/f3/Makefile +++ b/lib/stm32/f3/Makefile @@ -38,7 +38,7 @@ ARFLAGS = rcs OBJS += adc.o adc_common_v2.o adc_common_v2_multi.o OBJS += can.o OBJS += crc_common_all.o crc_v2.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += desig_common_all.o desig_common_v1.o OBJS += dma_common_l1f013.o OBJS += exti_common_all.o diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile index 80c88572..2fe12925 100644 --- a/lib/stm32/f4/Makefile +++ b/lib/stm32/f4/Makefile @@ -41,7 +41,7 @@ OBJS += adc_common_v1.o adc_common_v1_multi.o adc_common_f47.o OBJS += can.o OBJS += crc_common_all.o OBJS += crypto_common_f24.o crypto.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += dcmi_common_f47.o OBJS += desig_common_all.o desig_common_v1.o OBJS += dma_common_f24.o diff --git a/lib/stm32/f7/Makefile b/lib/stm32/f7/Makefile index 6fc8c1f3..2e41e406 100644 --- a/lib/stm32/f7/Makefile +++ b/lib/stm32/f7/Makefile @@ -43,7 +43,7 @@ ARFLAGS = rcs OBJS += adc_common_v1.o adc_common_v1_multi.o adc_common_f47.o OBJS += can.o OBJS += crc_common_all.o crc_v2.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += dcmi_common_f47.o OBJS += desig_common_all.o desig.o OBJS += dma_common_f24.o diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index c9ac6fd6..ba2f42e9 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -37,6 +37,7 @@ ARFLAGS = rcs OBJS += adc.o adc_common_v2.o adc_common_v2_multi.o OBJS += crs_common_all.o +OBJS += dac_common_all.o dac_common_v2.o OBJS += dma_common_l1f013.o OBJS += dmamux.o OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o diff --git a/lib/stm32/h7/Makefile b/lib/stm32/h7/Makefile index 737c2fc7..5a930d39 100644 --- a/lib/stm32/h7/Makefile +++ b/lib/stm32/h7/Makefile @@ -37,7 +37,7 @@ TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v2.o OBJS += exti_common_all.o OBJS += flash_common_all.o flash_common_f.o flash_common_f24.o OBJS += fmc_common_f47.o diff --git a/lib/stm32/l1/Makefile b/lib/stm32/l1/Makefile index b2bf7381..55c92a89 100644 --- a/lib/stm32/l1/Makefile +++ b/lib/stm32/l1/Makefile @@ -36,7 +36,7 @@ ARFLAGS = rcs OBJS += adc.o adc_common_v1.o adc_common_v1_multi.o OBJS += flash.o OBJS += crc_common_all.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += desig_common_all.o desig.o OBJS += dma_common_l1f013.o OBJS += exti_common_all.o diff --git a/lib/stm32/l4/Makefile b/lib/stm32/l4/Makefile index 31822b75..56a00838 100644 --- a/lib/stm32/l4/Makefile +++ b/lib/stm32/l4/Makefile @@ -39,7 +39,7 @@ OBJS += adc.o adc_common_v2.o adc_common_v2_multi.o OBJS += can.o OBJS += crc_common_all.o crc_v2.o OBJS += crs_common_all.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += dma_common_l1f013.o dma_common_csel.o OBJS += exti_common_all.o OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o