aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Sarkies2012-08-14 14:47:22 +0930
committerKen Sarkies2012-08-14 14:47:22 +0930
commitcb07ab7c6e2d029864495aa4dba29f4e616e4d3e (patch)
tree19b9f60218385419f304fd649647692896048915
parent9cff0c962b3bbfcde697100ac851d43be560b3d6 (diff)
parenta2c5b6391d82684838e923c6d7437367110f5480 (diff)
Merge branch 'master' into nvic
-rw-r--r--.gitignore4
-rw-r--r--include/libopencm3/stm32/dac.h130
-rw-r--r--include/libopencm3/stm32/doc-stm32f.h13
-rw-r--r--include/libopencm3/stm32/timer.h226
-rw-r--r--lib/stm32/dac.c517
-rw-r--r--lib/stm32/f1/timer.c900
6 files changed, 1723 insertions, 67 deletions
diff --git a/.gitignore b/.gitignore
index f0c86ce..63b7b48 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,7 @@
*.swp
\#*
.\#*
+*~
+*.map
+*.log
+doxygen/
diff --git a/include/libopencm3/stm32/dac.h b/include/libopencm3/stm32/dac.h
index 0402eb0..96ac8d0 100644
--- a/include/libopencm3/stm32/dac.h
+++ b/include/libopencm3/stm32/dac.h
@@ -1,3 +1,27 @@
+/** @file
+
+@ingroup STM32F
+
+@brief <b>libopencm3 STM32F Digital to Analog Converter</b>
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2012 Felix Held <felix-libopencm3@felixheld.de>
+@author @htmlonly &copy; @endhtmlonly 2012 Ken Sarkies
+
+@date 30 June 2012
+
+LGPL License Terms @ref lgpl_license
+ */
+/** @defgroup STM32F_dac_defines
+
+@brief Defined Constants and Types for the STM32F Digital to Analog Converter
+
+@ingroup STM32F_defines
+
+LGPL License Terms @ref lgpl_license
+
+ */
/*
* This file is part of the libopencm3 project.
*
@@ -69,7 +93,7 @@
/* --- DAC_CR values ------------------------------------------------------- */
/* DMAUDRIE2: DAC channel2 DMA underrun interrupt enable */
-/* doesn't exist in most members of the stm32f1 family */
+/* doesn't exist in most members of the STM32F1 family */
#define DAC_CR_DMAUDRIE2 (1 << 29)
/* DMAEN2: DAC channel2 DMA enable */
@@ -80,6 +104,11 @@
* 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 STM32F_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)
@@ -92,6 +121,7 @@
#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:
@@ -102,9 +132,18 @@
* Note: only used if bit TEN2 = 1 (DAC channel2 trigger enabled)
*/
#define DAC_CR_WAVE2_SHIFT 22
-#define DAC_CR_WAVE2_DIS (0x0 << DAC_CR_WAVE2_SHIFT)
+#define DAC_CR_WAVE2_DIS (0x3 << DAC_CR_WAVE2_SHIFT)
+/** @defgroup dac_wave2_en DAC Channel 2 Waveform Generation Enable
+@ingroup STM32F_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:
@@ -125,6 +164,25 @@
* 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 STM32F_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 <b>not</b> 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)
@@ -135,6 +193,7 @@
#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)
@@ -146,7 +205,7 @@
#define DAC_CR_EN2 (1 << 16)
/* DMAUDRIE1: DAC channel1 DMA underrun interrupt enable */
-/* doesn't exist in most members of the stm32f1 family */
+/* doesn't exist in most members of the STM32F1 family */
#define DAC_CR_DMAUDRIE1 (1 << 13)
/* DMAEN1: DAC channel1 DMA enable */
@@ -157,6 +216,11 @@
* 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 STM32F_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)
@@ -169,6 +233,7 @@
#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:
@@ -179,9 +244,19 @@
* Note: only used if bit TEN1 = 1 (DAC channel1 trigger enabled)
*/
#define DAC_CR_WAVE1_SHIFT 6
-#define DAC_CR_WAVE1_DIS (0x0 << DAC_CR_WAVE1_SHIFT)
+#define DAC_CR_WAVE1_DIS (0x3 << DAC_CR_WAVE1_SHIFT)
+/** @defgroup dac_wave1_en DAC Channel 1 Waveform Generation Enable
+@ingroup STM32F_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:
@@ -202,6 +277,25 @@
* 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 STM32F_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 <b>not</b> 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)
@@ -212,6 +306,7 @@
#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)
@@ -292,11 +387,32 @@
#define DAC_DOR2_DACC2DOR_LSB (1 << 0)
#define DAC_DOR2_DACC2DOR_MSK (0x0FFF << 0)
+/** DAC channel identifier */
+typedef enum {
+ CHANNEL_1, CHANNEL_2, CHANNEL_D
+} data_channel;
-/* --- Function prototypes ------------------------------------------------- */
+/** DAC data size (8/12 bits), alignment (right/left) */
+typedef enum {
+ RIGHT8, RIGHT12, LEFT12
+} data_align;
+/* --- Function prototypes ------------------------------------------------- */
-/* TODO */
-
+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(u32 dac_trig_src);
+void dac_set_waveform_generation(u32 dac_wave_ens);
+void dac_disable_waveform_generation(data_channel dac_channel);
+void dac_set_waveform_characteristics(u32 dac_mamp);
+void dac_load_data_buffer_single(u32 dac_data, data_align dac_data_format, data_channel dac_channel);
+void dac_load_data_buffer_dual(u32 dac_data1, u32 dac_data2, data_align dac_data_format);
+void dac_software_trigger(data_channel dac_channel);
#endif
diff --git a/include/libopencm3/stm32/doc-stm32f.h b/include/libopencm3/stm32/doc-stm32f.h
new file mode 100644
index 0000000..e592c12
--- /dev/null
+++ b/include/libopencm3/stm32/doc-stm32f.h
@@ -0,0 +1,13 @@
+/** @defgroup STM32F_defines
+
+@brief Defined Constants and Types for the STM32F series
+
+@ingroup STM32F
+
+@version 1.0.0
+
+@date 8 July 2012
+
+LGPL License Terms @ref lgpl_license
+ */
+
diff --git a/include/libopencm3/stm32/timer.h b/include/libopencm3/stm32/timer.h
index 3c8c8c2..3066fd3 100644
--- a/include/libopencm3/stm32/timer.h
+++ b/include/libopencm3/stm32/timer.h
@@ -1,3 +1,26 @@
+/** @file
+
+@ingroup STM32F1xx
+
+@brief <b>libopencm3 STM32F1xx Timers</b>
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2009 Piotr Esden-Tempski <piotr@esden.net>
+
+@date 18 May 2012
+
+LGPL License Terms @ref lgpl_license
+ */
+/** @defgroup STM32F1xx_tim_defines
+
+@brief Defined Constants and Types for the STM32F1xx Timers
+
+@ingroup STM32F1xx_defines
+
+LGPL License Terms @ref lgpl_license
+
+ */
/*
* This file is part of the libopencm3 project.
*
@@ -26,6 +49,11 @@
/* --- Convenience macros -------------------------------------------------- */
/* Timer register base adresses (for convenience) */
+/****************************************************************************/
+/** @defgroup tim_reg_base Timer register base addresses
+@ingroup STM32F1xx_tim_defines
+
+@{*/
#define TIM1 TIM1_BASE
#define TIM2 TIM2_BASE
#define TIM3 TIM3_BASE
@@ -34,6 +62,7 @@
#define TIM6 TIM6_BASE
#define TIM7 TIM7_BASE
#define TIM8 TIM8_BASE
+/*@}*/
/* --- Timer registers ----------------------------------------------------- */
@@ -227,25 +256,43 @@
/* --- TIMx_CR1 values ----------------------------------------------------- */
+/****************************************************************************/
+/** @defgroup tim_x_cr1_cdr TIMx_CR1 CKD[1:0] Clock Division Ratio
+@ingroup STM32F1xx_tim_defines
+
+@{*/
/* CKD[1:0]: Clock division */
#define TIM_CR1_CKD_CK_INT (0x0 << 8)
#define TIM_CR1_CKD_CK_INT_MUL_2 (0x1 << 8)
#define TIM_CR1_CKD_CK_INT_MUL_4 (0x2 << 8)
#define TIM_CR1_CKD_CK_INT_MASK (0x3 << 8)
+/*@}*/
/* ARPE: Auto-reload preload enable */
#define TIM_CR1_ARPE (1 << 7)
/* CMS[1:0]: Center-aligned mode selection */
+/****************************************************************************/
+/** @defgroup tim_x_cr1_cms TIMx_CR1 CMS[1:0]: Center-aligned Mode Selection
+@ingroup STM32F1xx_tim_defines
+
+@{*/
#define TIM_CR1_CMS_EDGE (0x0 << 5)
#define TIM_CR1_CMS_CENTER_1 (0x1 << 5)
#define TIM_CR1_CMS_CENTER_2 (0x2 << 5)
#define TIM_CR1_CMS_CENTER_3 (0x3 << 5)
#define TIM_CR1_CMS_MASK (0x3 << 5)
+/*@}*/
/* DIR: Direction */
+/****************************************************************************/
+/** @defgroup tim_x_cr1_dir TIMx_CR1 DIR: Direction
+@ingroup STM32F1xx_tim_defines
+
+@{*/
#define TIM_CR1_DIR_UP (0 << 4)
#define TIM_CR1_DIR_DOWN (1 << 4)
+/*@}*/
/* OPM: One pulse mode */
#define TIM_CR1_OPM (1 << 3)
@@ -261,32 +308,43 @@
/* --- TIMx_CR2 values ----------------------------------------------------- */
-/* OIS4: Output idle state 4 (OC4 output) */
+/****************************************************************************/
+/** @defgroup tim_x_cr2_ois TIMx_CR2_OIS: Force Output Idle State Control Values
+@ingroup STM32F1xx_tim_defines
+
+@{*/
+/* OIS4:*//** Output idle state 4 (OC4 output) */
#define TIM_CR2_OIS4 (1 << 14)
-/* OIS3N: Output idle state 3 (OC3N output) */
+/* OIS3N:*//** Output idle state 3 (OC3N output) */
#define TIM_CR2_OIS3N (1 << 13)
-/* OIS3: Output idle state 3 (OC3 output) */
+/* OIS3:*//** Output idle state 3 (OC3 output) */
#define TIM_CR2_OIS3 (1 << 12)
-/* OIS2N: Output idle state 2 (OC2N output) */
+/* OIS2N:*//** Output idle state 2 (OC2N output) */
#define TIM_CR2_OIS2N (1 << 11)
-/* OIS2: Output idle state 2 (OC2 output) */
+/* OIS2:*//** Output idle state 2 (OC2 output) */
#define TIM_CR2_OIS2 (1 << 10)
-/* OIS1N: Output idle state 1 (OC1N output) */
+/* OIS1N:*//** Output idle state 1 (OC1N output) */
#define TIM_CR2_OIS1N (1 << 9)
-/* OIS1: Output idle state 1 (OC1 output) */
+/* OIS1:*//** Output idle state 1 (OC1 output) */
#define TIM_CR2_OIS1 (1 << 8)
#define TIM_CR2_OIS_MASK (0x7f << 8)
+/*@}*/
/* TI1S: TI1 selection */
#define TIM_CR2_TI1S (1 << 7)
/* MMS[2:0]: Master mode selection */
+/****************************************************************************/
+/** @defgroup tim_mastermode TIMx_CR2 MMS[6:4]: Master Mode Selection
+@ingroup STM32F1xx_tim_defines
+
+@{*/
#define TIM_CR2_MMS_RESET (0x0 << 4)
#define TIM_CR2_MMS_ENABLE (0x1 << 4)
#define TIM_CR2_MMS_UPDATE (0x2 << 4)
@@ -296,6 +354,7 @@
#define TIM_CR2_MMS_COMPARE_OC3REF (0x6 << 4)
#define TIM_CR2_MMS_COMPARE_OC4REF (0x7 << 4)
#define TIM_CR2_MMS_MASK (0x7 << 4)
+/*@}*/
/* CCDS: Capture/compare DMA selection */
#define TIM_CR2_CCDS (1 << 3)
@@ -344,137 +403,186 @@
#define TIM_SMCR_MSM (1 << 7)
/* TS[2:0]: Trigger selection */
+/** @defgroup tim_ts TS Trigger selection
+@ingroup STM32F1xx_tim_defines
+
+@{*/
+/** Internal Trigger 0 (ITR0) */
#define TIM_SMCR_TS_ITR0 (0x0 << 4)
+/** Internal Trigger 1 (ITR1) */
#define TIM_SMCR_TS_ITR1 (0x1 << 4)
+/** Internal Trigger 2 (ITR2) */
#define TIM_SMCR_TS_ITR2 (0x2 << 4)
+/** Internal Trigger 3 (ITR3) */
#define TIM_SMCR_TS_ITR3 (0x3 << 4)
+/** TI1 Edge Detector (TI1F_ED) */
#define TIM_SMCR_TS_IT1F_ED (0x4 << 4)
+/** Filtered Timer Input 1 (TI1FP1) */
#define TIM_SMCR_TS_IT1FP1 (0x5 << 4)
+/** Filtered Timer Input 2 (TI1FP2) */
#define TIM_SMCR_TS_IT1FP2 (0x6 << 4)
+/** External Trigger input (ETRF) */
#define TIM_SMCR_TS_ETRF (0x7 << 4)
#define TIM_SMCR_TS_MASK (0x7 << 4)
+/*@}*/
/* SMS[2:0]: Slave mode selection */
+/** @defgroup tim_sms SMS Slave mode selection
+@ingroup STM32F1xx_tim_defines
+
+@{*/
+/** Slave mode disabled */
#define TIM_SMCR_SMS_OFF (0x0 << 0)
+/** Encoder mode 1 - Counter counts up/down on TI2FP2 edge depending on TI1FP1
+level. */
#define TIM_SMCR_SMS_EM1 (0x1 << 0)
+/** Encoder mode 2 - Counter counts up/down on TI1FP1 edge depending on TI2FP2
+level. */
#define TIM_SMCR_SMS_EM2 (0x2 << 0)
+/** Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges
+depending on the level of the complementary input. */
#define TIM_SMCR_SMS_EM3 (0x3 << 0)
+/** Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter
+and generates an update of the registers. */
#define TIM_SMCR_SMS_RM (0x4 << 0)
+/** Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. */
#define TIM_SMCR_SMS_GM (0x5 << 0)
+/** Trigger Mode - The counter starts at a rising edge of the trigger TRGI. */
#define TIM_SMCR_SMS_TM (0x6 << 0)
+/** External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. */
#define TIM_SMCR_SMS_ECM1 (0x7 << 0)
#define TIM_SMCR_SMS_MASK (0x7 << 0)
+/*@}*/
/* --- TIMx_DIER values ---------------------------------------------------- */
-/* TDE: Trigger DMA request enable */
+/****************************************************************************/
+/** @defgroup tim_irq_enable TIMx_DIER Timer DMA and Interrupt Enable Values
+@ingroup STM32F1xx_tim_defines
+
+@{*/
+/* TDE:*//** Trigger DMA request enable */
#define TIM_DIER_TDE (1 << 14)
-/* COMDE: COM DMA request enable */
+/* COMDE:*//** COM DMA request enable */
#define TIM_DIER_COMDE (1 << 13)
-/* CC4DE: Capture/Compare 4 DMA request enable */
+/* CC4DE:*//** Capture/Compare 4 DMA request enable */
#define TIM_DIER_CC4DE (1 << 12)
-/* CC3DE: Capture/Compare 3 DMA request enable */
+/* CC3DE:*//** Capture/Compare 3 DMA request enable */
#define TIM_DIER_CC3DE (1 << 11)
-/* CC2DE: Capture/Compare 2 DMA request enable */
+/* CC2DE:*//** Capture/Compare 2 DMA request enable */
#define TIM_DIER_CC2DE (1 << 10)
-/* CC1DE: Capture/Compare 1 DMA request enable */
+/* CC1DE:*//** Capture/Compare 1 DMA request enable */
#define TIM_DIER_CC1DE (1 << 9)
-/* UDE: Update DMA request enable */
+/* UDE*//**: Update DMA request enable */
#define TIM_DIER_UDE (1 << 8)
-/* BIE: Break interrupt enable */
+/* BIE:*//** Break interrupt enable */
#define TIM_DIER_BIE (1 << 7)
-/* TIE: Trigger interrupt enable */
+/* TIE:*//** Trigger interrupt enable */
#define TIM_DIER_TIE (1 << 6)
-/* COMIE: COM interrupt enable */
+/* COMIE:*//** COM interrupt enable */
#define TIM_DIER_COMIE (1 << 5)
-/* CC4IE: Capture/compare 4 interrupt enable */
+/* CC4IE:*//** Capture/compare 4 interrupt enable */
#define TIM_DIER_CC4IE (1 << 4)
-/* CC3IE: Capture/compare 3 interrupt enable */
+/* CC3IE:*//** Capture/compare 3 interrupt enable */
#define TIM_DIER_CC3IE (1 << 3)
-/* CC2IE: Capture/compare 2 interrupt enable */
+/* CC2IE:*//** Capture/compare 2 interrupt enable */
#define TIM_DIER_CC2IE (1 << 2)
-/* CC1IE: Capture/compare 1 interrupt enable */
+/* CC1IE:*//** Capture/compare 1 interrupt enable */
#define TIM_DIER_CC1IE (1 << 1)
-/* UIE: Update interrupt enable */
+/* UIE:*//** Update interrupt enable */
#define TIM_DIER_UIE (1 << 0)
+/*@}*/
/* --- TIMx_SR values ------------------------------------------------------ */
+/****************************************************************************/
+/** @defgroup tim_sr_values TIMx_SR Timer Status Register Flags
+@ingroup STM32F1xx_tim_defines
-/* CC4OF: Capture/compare 4 overcapture flag */
+@{*/
+
+/* CC4OF:*//** Capture/compare 4 overcapture flag */
#define TIM_SR_CC4OF (1 << 12)
-/* CC3OF: Capture/compare 3 overcapture flag */
+/* CC3OF:*//** Capture/compare 3 overcapture flag */
#define TIM_SR_CC3OF (1 << 11)
-/* CC2OF: Capture/compare 2 overcapture flag */
+/* CC2OF:*//** Capture/compare 2 overcapture flag */
#define TIM_SR_CC2OF (1 << 10)
-/* CC1OF: Capture/compare 1 overcapture flag */
+/* CC1OF:*//** Capture/compare 1 overcapture flag */
#define TIM_SR_CC1OF (1 << 9)
-/* BIF: Break interrupt flag */
+/* BIF:*//** Break interrupt flag */
#define TIM_SR_BIF (1 << 7)
-/* TIF: Trigger interrupt flag */
+/* TIF:*//** Trigger interrupt flag */
#define TIM_SR_TIF (1 << 6)
-/* COMIF: COM interrupt flag */
+/* COMIF:*//** COM interrupt flag */
#define TIM_SR_COMIF (1 << 5)
-/* CC4IF: Capture/compare 4 interrupt flag */
+/* CC4IF:*//** Capture/compare 4 interrupt flag */
#define TIM_SR_CC4IF (1 << 4)
-/* CC3IF: Capture/compare 3 interrupt flag */
+/* CC3IF:*//** Capture/compare 3 interrupt flag */
#define TIM_SR_CC3IF (1 << 3)
-/* CC2IF: Capture/compare 2 interrupt flag */
+/* CC2IF:*//** Capture/compare 2 interrupt flag */
#define TIM_SR_CC2IF (1 << 2)
-/* CC1IF: Capture/compare 1 interrupt flag */
+/* CC1IF:*//** Capture/compare 1 interrupt flag */
#define TIM_SR_CC1IF (1 << 1)
-/* UIF: Update interrupt flag */
+/* UIF:*//** Update interrupt flag */
#define TIM_SR_UIF (1 << 0)
+/*@}*/
/* --- TIMx_EGR values ----------------------------------------------------- */
-/* BG: Break generation */
+/****************************************************************************/
+/** @defgroup tim_event_gen TIMx_EGR Timer Event Generator Values
+@ingroup STM32F1xx_tim_defines
+
+@{*/
+
+/* BG:*//** Break generation */
#define TIM_EGR_BG (1 << 7)
-/* TG: Trigger generation */
+/* TG:*//** Trigger generation */
#define TIM_EGR_TG (1 << 6)
-/* COMG: Capture/compare control update generation */
+/* COMG:*//** Capture/compare control update generation */
#define TIM_EGR_COMG (1 << 5)
-/* CC4G: Capture/compare 4 generation */
+/* CC4G:*//** Capture/compare 4 generation */
#define TIM_EGR_CC4G (1 << 4)
-/* CC3G: Capture/compare 3 generation */
+/* CC3G:*//** Capture/compare 3 generation */
#define TIM_EGR_CC3G (1 << 3)
-/* CC2G: Capture/compare 2 generation */
+/* CC2G:*//** Capture/compare 2 generation */
#define TIM_EGR_CC2G (1 << 2)
-/* CC1G: Capture/compare 1 generation */
+/* CC1G:*//** Capture/compare 1 generation */
#define TIM_EGR_CC1G (1 << 1)
-/* UG: Update generation */
+/* UG:*//** Update generation */
#define TIM_EGR_UG (1 << 0)
+/*@}*/
/* --- TIMx_CCMR1 values --------------------------------------------------- */
@@ -805,11 +913,17 @@
#define TIM_BDTR_OSSI (1 << 10)
/* LOCK[1:0]: Lock configuration */
+/****************************************************************************/
+/** @defgroup tim_lock TIM_BDTR_LOCK Timer Lock Values
+@ingroup STM32F1xx_tim_defines
+
+@{*/
#define TIM_BDTR_LOCK_OFF (0x0 << 8)
#define TIM_BDTR_LOCK_LEVEL_1 (0x1 << 8)
#define TIM_BDTR_LOCK_LEVEL_2 (0x2 << 8)
#define TIM_BDTR_LOCK_LEVEL_3 (0x3 << 8)
#define TIM_BDTR_LOCK_MASK (0x3 << 8)
+/*@}*/
/* DTG[7:0]: Dead-time generator set-up */
#define TIM_BDTR_DTG_MASK 0x00FF
@@ -828,7 +942,7 @@
/* --- TIMx convenience defines -------------------------------------------- */
-/* Output Compare channel designators */
+/** Output Compare channel designators */
enum tim_oc_id {
TIM_OC1=0,
TIM_OC1N,
@@ -839,7 +953,7 @@ enum tim_oc_id {
TIM_OC4,
};
-/* Output Compare mode designators */
+/** Output Compare mode designators */
enum tim_oc_mode {
TIM_OCM_FROZEN,
TIM_OCM_ACTIVE,
@@ -851,7 +965,7 @@ enum tim_oc_mode {
TIM_OCM_PWM2,
};
-/* Input Capture channel designators */
+/** Input Capture channel designators */
enum tim_ic_id {
TIM_IC1,
TIM_IC2,
@@ -859,7 +973,13 @@ enum tim_ic_id {
TIM_IC4,
};
-/* Input Capture input filter */
+/** Input Capture input filter. The frequency used to sample the
+input and the number of events needed to validate an output transition.
+
+TIM_IC_CK_INT_N_x No division from the Deadtime and Sampling Clock frequency (DTF),
+filter length x
+TIM_IC_DTF_DIV_y_N_x Division by y from the DTF, filter length x
+ */
enum tim_ic_filter {
TIM_IC_OFF,
TIM_IC_CK_INT_N_2,
@@ -879,7 +999,9 @@ enum tim_ic_filter {
TIM_IC_DTF_DIV_32_N_8,
};
-/* Input Capture input prescaler */
+/** Input Capture input prescaler.
+
+TIM_IC_PSC_x Input capture is done every x events*/
enum tim_ic_psc {
TIM_IC_PSC_OFF,
TIM_IC_PSC_2,
@@ -887,7 +1009,10 @@ enum tim_ic_psc {
TIM_IC_PSC_8,
};
-/* Input Capture input prescaler */
+/** Input Capture input source.
+
+The direction of the channel (input/output) as well as the input used.
+ */
enum tim_ic_input {
TIM_IC_OUT = 0,
TIM_IC_IN_TI1 = 1,
@@ -897,13 +1022,13 @@ enum tim_ic_input {
TIM_IC_IN_TI4 = 6,
};
-/* Input Capture input prescaler */
+/** Input Capture input polarity */
enum tim_ic_pol {
TIM_IC_RISING,
TIM_IC_FALLING,
};
-/* --- TIM functions ------------------------------------------------------- */
+/* --- TIM function prototypes ------------------------------------------------------- */
void timer_reset(u32 timer_peripheral);
void timer_enable_irq(u32 timer_peripheral, u32 irq);
void timer_disable_irq(u32 timer_peripheral, u32 irq);
@@ -982,5 +1107,6 @@ void timer_slave_set_prescaler(u32 timer, enum tim_ic_psc psc);
void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol);
void timer_slave_set_mode(u32 timer, u8 mode);
void timer_slave_set_trigger(u32 timer, u8 trigger);
+void timer_force_event(u32 timer, u8 event);
#endif
diff --git a/lib/stm32/dac.c b/lib/stm32/dac.c
new file mode 100644
index 0000000..deec130
--- /dev/null
+++ b/lib/stm32/dac.c
@@ -0,0 +1,517 @@
+/** @file
+
+@ingroup STM32F
+
+@brief <b>libopencm3 STM32Fxx Digital to Analog Converter</b>
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2012 Ken Sarkies
+
+@date 30 June 2012
+
+This library supports the Digital to Analog Conversion System in the
+STM32F series of ARM Cortex Microcontrollers by ST Microelectronics.
+
+The DAC is present only in a limited set of devices, notably some
+of the connection line, high density and XL devices.
+
+Two DAC channels are available, however unlike the ADC channels these
+are separate DAC devices controlled by the same register block.
+
+The DAC is on APB1. Its clock must be enabled in RCC and the GPIO
+ports set to alternate function output before it can be used.
+The digital output driver is disabled so the output driver mode
+(push-pull/open drain) is arbitrary.
+
+The DAC has a holding (buffer) register and an output register from
+which the analog output is derived. The holding register must be
+loaded first. If triggering is enabled the output register is loaded
+from the holding register after a trigger occurs. If triggering is
+not enabled the holding register contents are transferred directly
+to the output register.
+
+@note To avoid nonlinearities, do not allow outputs to range close
+to zero or V_analog.
+
+@section dac_api_dual Dual Channel Conversion
+
+There are dual modes in which both DACs are used to output data
+simultaneously or independently on both channels. The data must be
+presented according to the formats described in the datasheets. A
+convenience function @ref dac_load_data_buffer_dual is provided
+for software controlled use.
+
+A variety of modes are available depending on whether independent
+or simultaneous output is desired, and whether waveforms are to be
+superimposed. Refer to the datasheets.
+
+If DMA is used, only enable it for one of the channels. The DMA
+requests will then serve data in dual format to the data register
+dedicated to dual mode. The data will then be split and loaded to the
+appropriate DAC following the next trigger. There are three registers
+available, one for each of the formats: 12 bit right-aligned, 12 bit
+left-aligned and 8 bit right-aligned. The desired format is determined
+by specifying the appropriate register to the DMA controller.
+
+@section dac_api_basic_ex Basic DAC handling API.
+
+Set the DAC's GPIO port to any alternate function output mode. Enable the
+DAC clock. Enable the DAC, set a trigger source and load the buffer
+with the first value. After the DAC is triggered, load the buffer with
+the next value. This example uses software triggering and added noise.
+The trigger and further buffer load calls are made when data is to be
+sent out.
+
+@code
+ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO4);
+ rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_DACEN);
+ 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_software_trigger(CHANNEL_1);
+ dac_load_data_buffer_single(value, RIGHT12, CHANNEL_1);
+@endcode
+
+@section dac_api_dma_ex Simultaneous Dual DAC with DMA.
+
+This example in part sets up the DAC channel 1 DMA (DMA2 channel 3) to read
+16 bit data from memory into the right-aligned 8 bit dual register DAC_DHR8RD.
+Both DAC channels are enabled, and both triggers are set to the same timer
+2 input as required for simultaneous operation. DMA is enabled for DAC channel
+1 only to ensure that only one DMA request is generated.
+
+@code
+ dma_set_memory_size(DMA2,DMA_CHANNEL3,DMA_CCR_MSIZE_16BIT);
+ dma_set_peripheral_size(DMA2,DMA_CHANNEL3,DMA_CCR_PSIZE_16BIT);
+ dma_set_read_from_memory(DMA2,DMA_CHANNEL3);
+ dma_set_peripheral_address(DMA2,DMA_CHANNEL3,(u32) &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);
+@endcode
+
+LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 Ken Sarkies
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/dac.h>
+
+#define MASK8 0xFF
+#define MASK12 0xFFF
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DAC Channel Enable.
+
+Enable a digital to analog converter channel. After setting this enable, the DAC
+requires a t<sub>wakeup</sub> time typically around 10 microseconds before it
+actually wakes up.
+
+@param[in] enum ::data_channel, dac_channel.
+*/
+
+void dac_enable(data_channel dac_channel)
+{
+ switch (dac_channel) {
+ case CHANNEL_1:
+ DAC_CR |= DAC_CR_EN1;
+ break;
+ case CHANNEL_2:
+ DAC_CR |= DAC_CR_EN2;
+ break;
+ case CHANNEL_D:
+ DAC_CR |= (DAC_CR_EN1 | DAC_CR_EN2);
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DAC Channel Disable.
+
+Disable a digital to analog converter channel.
+
+@param[in] enum ::data_channel, dac_channel.
+*/
+
+void dac_disable(data_channel dac_channel)
+{
+ switch (dac_channel) {
+ case CHANNEL_1:
+ DAC_CR &= ~DAC_CR_EN1;
+ break;
+ case CHANNEL_2:
+ DAC_CR &= ~DAC_CR_EN2;
+ break;
+ case CHANNEL_D:
+ DAC_CR &= ~(DAC_CR_EN1 | DAC_CR_EN2);
+ 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] enum ::data_channel, dac_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] enum ::data_channel, dac_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.
+
+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] enum ::data_channel, dac_channel.
+*/
+
+void dac_dma_enable(data_channel dac_channel)
+{
+ switch (dac_channel) {
+ case CHANNEL_1:
+ DAC_CR |= DAC_CR_DMAEN1;
+ break;
+ case CHANNEL_2:
+ DAC_CR |= DAC_CR_DMAEN2;
+ break;
+ case CHANNEL_D:
+ DAC_CR |= (DAC_CR_DMAEN1 | DAC_CR_DMAEN2);
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DAC Channel DMA Disable.
+
+Disable a digital to analog converter channel DMA mode.
+
+@param[in] enum ::data_channel, dac_channel.
+*/
+
+void dac_dma_disable(data_channel dac_channel)
+{
+ switch (dac_channel) {
+ case CHANNEL_1:
+ DAC_CR &= ~DAC_CR_DMAEN1;
+ break;
+ case CHANNEL_2:
+ DAC_CR &= ~DAC_CR_DMAEN2;
+ break;
+ case CHANNEL_D:
+ DAC_CR &= ~(DAC_CR_DMAEN1 | DAC_CR_DMAEN2);
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DAC Channel Trigger Enable.
+
+Enable a digital to analog converter channel external trigger mode. This allows 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] enum ::data_channel, dac_channel.
+*/
+
+void dac_trigger_enable(data_channel dac_channel)
+{
+ switch (dac_channel) {
+ case CHANNEL_1:
+ DAC_CR |= DAC_CR_TEN1;
+ break;
+ case CHANNEL_2:
+ DAC_CR |= DAC_CR_TEN2;
+ break;
+ case CHANNEL_D:
+ DAC_CR |= (DAC_CR_TEN1 | DAC_CR_TEN2);
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DAC Channel Trigger Disable.
+
+Disable a digital to analog converter channel external trigger.
+
+@param[in] enum ::data_channel, dac_channel.
+*/
+
+void dac_trigger_disable(data_channel dac_channel)
+{
+ switch (dac_channel) {
+ case CHANNEL_1:
+ DAC_CR &= ~DAC_CR_TEN1;
+ break;
+ case CHANNEL_2:
+ DAC_CR &= ~DAC_CR_TEN2;
+ break;
+ case CHANNEL_D:
+ DAC_CR &= ~(DAC_CR_TEN1 | DAC_CR_TEN2);
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief Set DAC Channel Trigger Source.
+
+Sets the digital to analog converter trigger source, which can be taken from various
+timers, an external trigger or a software trigger.
+
+@param[in] u32 dac_trig_src. 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(u32 dac_trig_src)
+{
+ DAC_CR |= dac_trig_src;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief Enable and Set DAC Channel Waveform Generation.
+
+Enable the digital to analog converter waveform generation as either pseudo-random
+noise or triangular wave. These signals are superimposed on existing output values
+in the DAC output registers.
+
+@note The DAC trigger must be enabled for this to work.
+
+@param[in] u32 dac_trig_src. 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(u32 dac_wave_ens)
+{
+ DAC_CR |= dac_wave_ens;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief Disable DAC Channel Waveform Generation.
+
+Disable a digital to analog converter channel superimposed waveform generation.
+
+@param[in] enum ::data_channel, dac_channel.
+*/
+
+void dac_disable_waveform_generation(data_channel dac_channel)
+{
+ switch (dac_channel) {
+ case CHANNEL_1:
+ DAC_CR &= ~DAC_CR_WAVE1_DIS;
+ break;
+ case CHANNEL_2:
+ DAC_CR &= ~DAC_CR_WAVE2_DIS;
+ break;
+ case CHANNEL_D:
+ DAC_CR &= ~(DAC_CR_WAVE1_DIS | DAC_CR_WAVE2_DIS);
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief Set DAC Channel LFSR Mask or Triangle Wave Amplitude.
+
+Sets the digital to analog converter superimposed waveform generation characteristics.
+@li If the noise generation mode is set, this sets the length of the PRBS sequence and
+hence the amplitude of the output noise signal. Default setting is length 1.
+@li If the triangle wave generation mode is set, this sets the amplitude of the
+output signal as 2^(n)-1 where n is the parameter value. Default setting is 1.
+
+@note High amplitude levels of these waveforms can overload the DAC and distort the
+signal output.
+@note This must be called before enabling the DAC as the settings will then become read-only.
+@note The DAC trigger must be enabled for this to work.
+
+@param[in] u32 dac_mamp. 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(u32 dac_mamp)
+{
+ DAC_CR |= dac_mamp;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief Load DAC Data Register.
+
+Loads the appropriate digital to analog converter data register with 12 or 8 bit
+data to be converted on a channel. The data can be aligned as follows:
+@li right-aligned 8 bit data in bits 0-7
+@li right-aligned 12 bit data in bits 0-11
+@li left aligned 12 bit data in bits 4-15
+
+This function can also be used to load the dual channel registers if the data is
+formatted according to the datasheets:
+@li right-aligned 8 bit data in bits 0-7 for channel 1 and 8-15 for channel 2
+@li right-aligned 12 bit data in bits 0-11 for channel 1 and 16-27 for channel 2
+@li left aligned 12 bit data in bits 4-15 for channel 1 and 20-31 for channel 2
+
+@param[in] u32 dac_data with appropriate alignment.
+@param[in] enum ::data_align, dac_data_format. Alignment and size.
+@param[in] enum ::data_channel, dac_channel.
+*/
+
+void dac_load_data_buffer_single(u32 dac_data, data_align dac_data_format, data_channel dac_channel)
+{
+ if (dac_channel == CHANNEL_1)
+ {
+ switch (dac_data_format) {
+ case RIGHT8:
+ DAC_DHR8R1 = dac_data;
+ break;
+ case RIGHT12:
+ DAC_DHR12R1 = dac_data;
+ break;
+ case LEFT12:
+ DAC_DHR12L1 = dac_data;
+ break;
+ }
+ }
+ else if (dac_channel == CHANNEL_2)
+ {
+ switch (dac_data_format) {
+ case RIGHT8:
+ DAC_DHR8R2 = dac_data;
+ break;
+ case RIGHT12:
+ DAC_DHR12R2 = dac_data;
+ break;
+ case LEFT12:
+ DAC_DHR12L2 = dac_data;
+ break;
+ }
+ }
+ else
+ switch (dac_data_format) {
+ case RIGHT8:
+ DAC_DHR8RD = dac_data;
+ break;
+ case RIGHT12:
+ DAC_DHR12RD = dac_data;
+ break;
+ case LEFT12:
+ DAC_DHR12LD = dac_data;
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief Load DAC Dual Data Register.
+
+Loads the appropriate digital to analog converter dual data register with 12 or
+8 bit data to be converted for both channels. This allows high bandwidth
+simultaneous or independent analog output. The data in both channels are aligned
+identically.
+
+@param[in] u32 dac_data for channel 1 with appropriate alignment.
+@param[in] u32 dac_data for channel 2 with appropriate alignment.
+@param[in] enum ::data_align, dac_data_format. Right or left aligned, and 8 or 12 bit.
+*/
+
+void dac_load_data_buffer_dual(u32 dac_data1, u32 dac_data2, data_align dac_data_format)
+{
+ switch (dac_data_format) {
+ case RIGHT8:
+ DAC_DHR8RD = ((dac_data1 & MASK8) | ((dac_data2 & MASK8) << 8));
+ break;
+ case RIGHT12:
+ DAC_DHR12RD = ((dac_data1 & MASK12) | ((dac_data2 & MASK12) << 12));
+ break;
+ case LEFT12:
+ DAC_DHR12LD = ((dac_data1 & MASK12) | ((dac_data2 & MASK12) << 16));
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief Trigger the DAC by a Software Trigger.
+
+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] enum ::data_channel, dac_channel.
+*/
+
+void dac_software_trigger(data_channel dac_channel)
+{
+ switch (dac_channel) {
+ case CHANNEL_1:
+ DAC_SWTRIGR |= DAC_SWTRIGR_SWTRIG1;
+ break;
+ case CHANNEL_2:
+ DAC_SWTRIGR |= DAC_SWTRIGR_SWTRIG2;
+ break;
+ case CHANNEL_D:
+ DAC_SWTRIGR |= (DAC_SWTRIGR_SWTRIG1 | DAC_SWTRIGR_SWTRIG2);
+ break;
+ }
+}
+
diff --git a/lib/stm32/f1/timer.c b/lib/stm32/f1/timer.c
index cf5b411..11cb954 100644
--- a/lib/stm32/f1/timer.c
+++ b/lib/stm32/f1/timer.c
@@ -1,3 +1,71 @@
+/** @file
+
+@ingroup STM32F1xx
+
+@brief <b>libopencm3 STM32F1xx Timers</b>
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2010 Edward Cheeseman <evbuilder@users.sourceforge.org>
+
+@date 8 July 2012
+
+This library supports the General Purpose and Advanced Control Timers for
+the STM32F1xx series of ARM Cortex Microcontrollers by ST Microelectronics.
+
+The STM32F1xx series have four general purpose timers (2-5), while some have
+an additional two advanced timers (1,8), and some have two basic timers (6,7).
+Some of the larger devices have additional general purpose timers (9-14).
+
+@todo Add timer DMA burst settings
+
+@section tim_api_ex Basic TIMER handling API.
+
+Enable the timer clock first. The timer mode sets the clock division ratio,
+the count alignment (edge or centred) and count direction. Finally enable the timer.
+
+The timer output compare block produces a signal that can be configured for
+output to a pin or passed to other peripherals for use as a trigger. In all cases
+the output compare mode must be set to define how the output responds to a compare
+match, and the output must be enabled. If output to a pin is required, enable the
+appropriate GPIO clock and set the pin to alternate output mode.
+
+Example: Timer 2 with 2x clock divide, edge aligned and up counting.
+@code
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM2EN);
+ timer_reset(TIM2);
+ timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT_MUL_2,
+ TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
+ ...
+ timer_set_period(TIM2, 1000);
+ timer_enable_counter(TIM2);
+@endcode
+Example: Timer 1 with PWM output, no clock divide and centre alignment. Set the
+Output Compare mode to PWM and enable the output of channel 1. Note that for the
+advanced timers the break functionality must be enabled before the signal will
+appear at the output, even though break is not being used. This is in addition to
+the normal output enable. Enable the alternate function clock (APB2 only) and port A
+clock. Set ports A8 and A9 (timer 1 channel 1 compare outputs) to alternate function
+push-pull outputs where the PWM output will appear.
+
+@code
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN);
+ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO8 | GPIO9);
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM1EN);
+ timer_reset(TIM1);
+ timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_CENTER_1, TIM_CR1_DIR_UP);
+ timer_set_oc_mode(TIM1, TIM_OC1, TIM_OCM_PWM2);
+ timer_enable_oc_output(TIM1, TIM_OC1);
+ timer_enable_break_main_output(TIM1);
+ timer_set_oc_value(TIM1, TIM_OC1, 200);
+ timer_set_period(TIM1, 1000);
+ timer_enable_counter(TIM1);
+@endcode
+
+@todo input capture example
+
+*/
/*
* This file is part of the libopencm3 project.
*
@@ -28,6 +96,17 @@
#include <libopencm3/stm32/timer.h>
#include <libopencm3/stm32/f1/rcc.h>
+/*---------------------------------------------------------------------------*/
+/** @brief Reset a Timer.
+
+The counter and all its associated configuration registers
+are placed in the reset condition. The reset is effected via the RCC peripheral reset
+system.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+ (TIM9 .. TIM14 not yet supported here).
+*/
+
void timer_reset(u32 timer_peripheral)
{
switch (timer_peripheral) {
@@ -93,31 +172,84 @@ void timer_reset(u32 timer_peripheral)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Enable Interrupts for a Timer
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] irq Unsigned int32. @ref tim_irq_enable. Logical OR of all interrupt enable bits to be set
+*/
+
void timer_enable_irq(u32 timer_peripheral, u32 irq)
{
TIM_DIER(timer_peripheral) |= irq;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Disable Interrupts for a Timer.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] irq Unsigned int32. @ref tim_irq_enable. Logical OR of all interrupt enable bits to be cleared
+*/
+
void timer_disable_irq(u32 timer_peripheral, u32 irq)
{
TIM_DIER(timer_peripheral) &= ~irq;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Read a Status Flag.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] flag Unsigned int32. Status register flag @ref tim_sr_values.
+@returns boolean: flag set.
+*/
+
bool timer_get_flag(u32 timer_peripheral, u32 flag)
{
- if (((TIM_SR(timer_peripheral) & flag) != 0) &&
- ((TIM_DIER(timer_peripheral) & flag) != 0)) {
+ if ((TIM_SR(timer_peripheral) & flag) != 0) {
return true;
}
return false;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Clear a Status Flag.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] flag Unsigned int32. @ref tim_sr_values. Status register flag.
+*/
+
void timer_clear_flag(u32 timer_peripheral, u32 flag)
{
TIM_SR(timer_peripheral) &= ~flag;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set the Timer Mode.
+
+The modes are:
+
+@li Clock divider ratio (to form the sampling clock for the input filters,
+and the dead-time clock in the advanced timers 1 and 8)
+@li Edge/centre alignment
+@li Count direction
+
+The alignment and count direction are effective only for timers 1 to 5 and 8
+while the clock divider ratio is effective for all timers except 6,7
+The remaining timers are limited hardware timers which do not support these mode
+settings.
+
+@note: When center alignment mode is selected, count direction is controlled by
+hardware and cannot be written. The count direction setting has no effect
+in this case.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base (TIM1, TIM2 ... TIM5, TIM8)
+@param[in] clock_div Unsigned int32. Clock Divider Ratio in bits 8,9: @ref tim_x_cr1_cdr
+@param[in] alignment Unsigned int32. Alignment bits in 5,6: @ref tim_x_cr1_cms
+@param[in] direction Unsigned int32. Count direction in bit 4,: @ref tim_x_cr1_dir
+*/
+
void timer_set_mode(u32 timer_peripheral, u32 clock_div,
u32 alignment, u32 direction)
{
@@ -132,6 +264,16 @@ void timer_set_mode(u32 timer_peripheral, u32 clock_div,
TIM_CR1(timer_peripheral) = cr1;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Input Filter and Dead-time Clock Divider Ratio.
+
+This forms the sampling clock for the input filters and the dead-time clock
+in the advanced timers 1 and 8, by division from the timer clock.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] clock_div Unsigned int32. Clock Divider Ratio in bits 8,9: @ref tim_x_cr1_cdr
+*/
+
void timer_set_clock_division(u32 timer_peripheral, u32 clock_div)
{
clock_div &= TIM_CR1_CKD_CK_INT_MASK;
@@ -139,16 +281,44 @@ void timer_set_clock_division(u32 timer_peripheral, u32 clock_div)
TIM_CR1(timer_peripheral) |= clock_div;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Enable Auto-Reload Buffering.
+
+During counter operation this causes the counter to be loaded from its
+auto-reload register only at the next update event.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_enable_preload(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) |= TIM_CR1_ARPE;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Disable Auto-Reload Buffering.
+
+This causes the counter to be loaded immediately with a new count value when the
+auto-reload register is written, so that the new value becomes effective for the
+current count cycle rather than for the cycle following an update event.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_disable_preload(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) &= ~TIM_CR1_ARPE;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Specify the counter alignment mode.
+
+The mode can be edge aligned or centered.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] alignment Unsigned int32. Alignment bits in 5,6: @ref tim_x_cr1_cms
+*/
+
void timer_set_alignment(u32 timer_peripheral, u32 alignment)
{
alignment &= TIM_CR1_CMS_MASK;
@@ -156,128 +326,368 @@ void timer_set_alignment(u32 timer_peripheral, u32 alignment)
TIM_CR1(timer_peripheral) |= alignment;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set the Timer to Count Up.
+
+This has no effect if the timer is set to center aligned.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_direction_up(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) &= ~TIM_CR1_DIR_DOWN;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set the Timer to Count Down.
+
+This has no effect if the timer is set to center aligned.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_direction_down(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) |= TIM_CR1_DIR_DOWN;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Enable the Timer for One Cycle and Stop.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_one_shot_mode(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) |= TIM_CR1_OPM;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Enable the Timer to Run Continuously.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_continuous_mode(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) &= ~TIM_CR1_OPM;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set the Timer to Generate Update IRQ or DMA on any Event.
+
+The events which will generate an interrupt or DMA request can be
+@li a counter underflow/overflow,
+@li a forced update,
+@li an event from the slave mode controller.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_update_on_any(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) &= ~TIM_CR1_URS;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set the Timer to Generate Update IRQ or DMA only from Under/Overflow Events.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_update_on_overflow(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) |= TIM_CR1_URS;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Enable Timer Update Events.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_enable_update_event(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) &= ~TIM_CR1_UDIS;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Disable Timer Update Events.
+
+Update events are not generated and the shadow registers keep their values.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_disable_update_event(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) |= TIM_CR1_UDIS;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Enable the timer to start counting.
+
+This should be called after the timer initial configuration has been completed.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_enable_counter(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) |= TIM_CR1_CEN;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Stop the timer from counting.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_disable_counter(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) &= ~TIM_CR1_CEN;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Timer Output Idle States High.
+
+This determines the value of the timer output compare when it enters idle state.
+
+@sa @ref timer_set_oc_idle_state_set
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] outputs Unsigned int32. Timer Output Idle State Controls @ref tim_x_cr2_ois.
+If several settings are to be made, use the logical OR of the output control values.
+*/
+
void timer_set_output_idle_state(u32 timer_peripheral, u32 outputs)
{
- TIM_CR2(timer_peripheral) |= outputs & TIM_CR2_OIS_MASK;
+ if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
+ TIM_CR2(timer_peripheral) |= outputs & TIM_CR2_OIS_MASK;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Timer Output Idle States Low.
+
+This determines the value of the timer output compare when it enters idle state.
+
+@sa @ref timer_set_oc_idle_state_unset
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] outputs Unsigned int32. Timer Output Idle State Controls @ref tim_x_cr2_ois
+*/
+
void timer_reset_output_idle_state(u32 timer_peripheral, u32 outputs)
{
- TIM_CR2(timer_peripheral) &= ~(outputs & TIM_CR2_OIS_MASK);
+ if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
+ TIM_CR2(timer_peripheral) &= ~(outputs & TIM_CR2_OIS_MASK);
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Timer 1 Input to XOR of Three Channels.
+
+The first timer capture input is formed from the XOR of the first three timer input
+channels 1, 2, 3.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_set_ti1_ch123_xor(u32 timer_peripheral)
{
TIM_CR2(timer_peripheral) |= TIM_CR2_TI1S;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Timer 1 Input to Channel 1.
+
+The first timer capture input is taken from the timer input channel 1 only.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_set_ti1_ch1(u32 timer_peripheral)
{
TIM_CR2(timer_peripheral) &= ~TIM_CR2_TI1S;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set the Master Mode
+
+This sets the Trigger Output TRGO for synchronizing with slave timers or passing as
+an internal trigger to the ADC or DAC.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] mode Unsigned int32. Master Mode @ref tim_mastermode
+*/
+
void timer_set_master_mode(u32 timer_peripheral, u32 mode)
{
TIM_CR2(timer_peripheral) &= ~TIM_CR2_MMS_MASK;
TIM_CR2(timer_peripheral) |= mode;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Timer DMA Requests on Capture/Compare Events.
+
+Capture/compare events will cause DMA requests to be generated.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_set_dma_on_compare_event(u32 timer_peripheral)
{
TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCDS;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Timer DMA Requests on Update Events.
+
+Update events will cause DMA requests to be generated.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_set_dma_on_update_event(u32 timer_peripheral)
{
TIM_CR2(timer_peripheral) |= TIM_CR2_CCDS;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Enable Timer Capture/Compare Control Update with Trigger.
+
+If the capture/compare control bits CCxE, CCxNE and OCxM are set to be
+preloaded, they are updated by software setting the COM bit (@ref ) or when a
+rising edge occurs on the trigger input TRGI.
+
+@note This setting is only valid for the advanced timer channels with complementary
+outputs.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_enable_compare_control_update_on_trigger(u32 timer_peripheral)
{
- TIM_CR2(timer_peripheral) |= TIM_CR2_CCUS;
+ if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
+ TIM_CR2(timer_peripheral) |= TIM_CR2_CCUS;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Disable Timer Capture/Compare Control Update with Trigger.
+
+If the capture/compare control bits CCxE, CCxNE and OCxM are set to be
+preloaded, they are updated by software setting the COM bit (@ref ).
+
+@note This setting is only valid for the advanced timer channels with complementary
+outputs.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_disable_compare_control_update_on_trigger(u32 timer_peripheral)
{
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCUS;
+ if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
+ TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCUS;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Enable Timer Capture/Compare Control Preload.
+
+The capture/compare control bits CCxE, CCxNE and OCxM are set to be preloaded
+when a COM event occurs.
+
+@note This setting is only valid for the advanced timer channels with complementary
+outputs.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_enable_preload_complementry_enable_bits(u32 timer_peripheral)
{
- TIM_CR2(timer_peripheral) |= TIM_CR2_CCPC;
+ if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
+ TIM_CR2(timer_peripheral) |= TIM_CR2_CCPC;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Disable Timer Capture/Compare Control Preload.
+
+The capture/compare control bits CCxE, CCxNE and OCxM preload is disabled.
+
+@note This setting is only valid for the advanced timer channels with complementary
+outputs.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+*/
+
void timer_disable_preload_complementry_enable_bits(u32 timer_peripheral)
{
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC;
+ if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
+ TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set the Value for the Timer Prescaler.
+
+The timer clock is prescaled by the 16 bit scale value plus 1.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] value Unsigned int32. Prescaler values 0...0xFFFF.
+*/
+
void timer_set_prescaler(u32 timer_peripheral, u32 value)
{
TIM_PSC(timer_peripheral) = value;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set the Value for the Timer Repetition Counter.
+
+A timer update event is generated only after the specified number of repeat
+count cycles have been completed.
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] value Unsigned int32. Repetition values 0...0xFF.
+*/
+
void timer_set_repetition_counter(u32 timer_peripheral, u32 value)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_RCR(timer_peripheral) = value;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer Set Period
+
+Specify the timer period in the auto-reload register.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] period Unsigned int32. Period in counter clock ticks.
+*/
+
void timer_set_period(u32 timer_peripheral, u32 period)
{
TIM_ARR(timer_peripheral) = period;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer Enable the Output Compare Clear Function
+
+When this is enabled, the output compare signal is cleared when a high is detected
+on the external trigger input. This works in the output compare and PWM modes only
+(not forced mode).
+The output compare signal remains off until the next update event.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] oc_id enum ::tim_oc_id OC channel designators
+ TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken)
+*/
+
void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
@@ -296,11 +706,19 @@ void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id)
case TIM_OC1N:
case TIM_OC2N:
case TIM_OC3N:
- /* Ignoring as fast enable only applies to the whole channel. */
+ /* Ignoring as oc clear enable only applies to the whole channel. */
break;
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer Disable the Output Compare Clear Function
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] oc_id enum ::tim_oc_id OC channel designators
+ TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken)
+*/
+
void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
@@ -319,11 +737,24 @@ void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id)
case TIM_OC1N:
case TIM_OC2N:
case TIM_OC3N:
- /* Ignoring as fast enable only applies to the whole channel. */
+ /* Ignoring as oc clear enable only applies to the whole channel. */
break;
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer Enable the Output Compare Fast Mode
+
+When this is enabled, the output compare signal is forced to the compare state
+by a trigger input, independently of the compare match. This speeds up the
+setting of the output compare to 3 clock cycles as opposed to at least 5 in the
+slow mode. This works in the PWM1 and PWM2 modes only.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] oc_id enum ::tim_oc_id OC channel designators
+ TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken)
+*/
+
void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
@@ -347,6 +778,17 @@ void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer Enable the Output Compare Slow Mode
+
+This disables the fast compare mode and the output compare depends on the
+counter and compare register values.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] oc_id enum ::tim_oc_id OC channel designators
+ TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken)
+*/
+
void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
@@ -370,6 +812,29 @@ void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer Set Output Compare Mode
+
+Specifies how the comparator output will respond to a compare match. The mode can be:
+@li Frozen - the output does not respond to a match.
+@li Active - the output assumes the active state on the first match.
+@li Inactive - the output assumes the inactive state on the first match.
+@li Toggle - The output switches between active and inactive states on each match.
+@li Force inactive. The output is forced low regardless of the compare state.
+@li Force active. The output is forced high regardless of the compare state.
+@li PWM1 - The output is active when the counter is less than the compare register contents
+and inactive otherwise.
+@li PWM2 - The output is inactive when the counter is less than the compare register contents
+and active otherwise.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] oc_id enum ::tim_oc_id OC channel designators
+ TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken)
+@param[in] oc_mode enum ::tim_oc_mode. OC mode designators.
+ TIM_OCM_FROZEN, TIM_OCM_ACTIVE, TIM_OCM_INACTIVE, TIM_OCM_TOGGLE,
+ TIM_OCM_FORCE_LOW, TIM_OCM_FORCE_HIGH, TIM_OCM_PWM1, TIM_OCM_PWM2
+*/
+
void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id,
enum tim_oc_mode oc_mode)
{
@@ -510,6 +975,14 @@ void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id,
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer Enable the Output Compare Preload Register
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] oc_id enum ::tim_oc_id OC channel designators
+ TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken)
+*/
+
void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
@@ -533,6 +1006,14 @@ void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer Disable the Output Compare Preload Register
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] oc_id enum ::tim_oc_id OC channel designators
+ TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action)
+*/
+
void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
@@ -556,6 +1037,16 @@ void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer Set the Output Polarity High
+
+The polarity of the channel output is set active high.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] oc_id enum ::tim_oc_id OC channel designators
+ TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8)
+*/
+
void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
@@ -601,6 +1092,16 @@ void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer Set the Output Polarity Low
+
+The polarity of the channel output is set active low.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] oc_id enum ::tim_oc_id OC channel designators
+ TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8)
+*/
+
void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
@@ -646,6 +1147,16 @@ void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer Enable the Output Compare
+
+The channel output compare functionality is enabled.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] oc_id enum ::tim_oc_id OC channel designators
+ TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8)
+*/
+
void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
@@ -691,6 +1202,16 @@ void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer Disable the Output Compare
+
+The channel output compare functionality is disabled.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] oc_id enum ::tim_oc_id OC channel designators
+ TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8)
+*/
+
void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
@@ -736,6 +1257,19 @@ void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer set Output Compare Idle State High
+
+@sa Similar function suitable for multiple OC idle state settings
+@ref timer_set_output_idle_state
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] oc_id enum ::tim_oc_id OC channel designators
+ TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8)
+*/
+
void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id)
{
/* Acting for TIM1 and TIM8 only. */
@@ -767,6 +1301,19 @@ void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer Set Output Compare Idle State Low
+
+@sa Similar function suitable for multiple OC idle state settings
+@ref timer_reset_output_idle_state
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+@param[in] oc_id enum ::tim_oc_id OC channel designators
+ TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8)
+*/
+
void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id)
{
/* Acting for TIM1 and TIM8 only. */
@@ -798,6 +1345,19 @@ void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Timer Set Output Compare Value
+
+This is a convenience function to set the OC preload register value for loading
+to the compare register.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
+ (TIM9 .. TIM14 not yet supported here).
+@param[in] oc_id enum ::tim_oc_id OC channel designators
+ TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken)
+@param[in] value Unsigned int32. Compare value.
+*/
+
void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value)
{
switch (oc_id) {
@@ -821,100 +1381,306 @@ void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Enable Output in Break
+
+Enables the output in the Break feature of an advanced timer. This does not
+enable the break functionality itself but only sets the Master Output Enable in
+the Break and Deadtime Register.
+
+@note This setting is only valid for the advanced timers.
+
+@note It is necessary to call this function to enable the output on an advanced
+timer <b>even if break or deadtime features are not being used<\b>.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
+*/
+
void timer_enable_break_main_output(u32 timer_peripheral)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= TIM_BDTR_MOE;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Disable Output in Break
+
+Disables the output in the Break feature of an advanced timer. This clears
+the Master Output Enable in the Break and Deadtime Register.
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
+*/
+
void timer_disable_break_main_output(u32 timer_peripheral)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_MOE;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Enable Automatic Output in Break
+
+Enables the automatic output feature of the Break function of an advanced
+timer so that the output is re-enabled at the next update event following a
+break event.
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
+*/
+
void timer_enable_break_automatic_output(u32 timer_peripheral)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= TIM_BDTR_AOE;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Disable Automatic Output in Break
+
+Disables the automatic output feature of the Break function of an advanced
+timer so that the output is re-enabled at the next update event following a
+break event.
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
+*/
+
void timer_disable_break_automatic_output(u32 timer_peripheral)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_AOE;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Activate Break when Input High
+
+Sets the break function to activate when the break input becomes high.
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
+*/
+
void timer_set_break_polarity_high(u32 timer_peripheral)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKP;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Activate Break when Input Low
+
+Sets the break function to activate when the break input becomes low.
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
+*/
+
void timer_set_break_polarity_low(u32 timer_peripheral)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKP;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Enable Break
+
+Enables the break function of an advanced timer.
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
+*/
+
void timer_enable_break(u32 timer_peripheral)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKE;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Disable Break
+
+Disables the break function of an advanced timer.
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
+*/
+
void timer_disable_break(u32 timer_peripheral)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKE;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Enable Off-State in Run Mode
+
+Enables the off-state in run mode for the break function of an advanced
+timer in which the complementary outputs have been configured. It has no effect
+if no complementary output is present. When the capture-compare output is
+disabled while the complementary output is enabled, the output is set to its
+inactive level as defined by the output polarity.
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
+*/
+
void timer_set_enabled_off_state_in_run_mode(u32 timer_peripheral)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSR;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Disable Off-State in Run Mode
+
+Disables the off-state in run mode for the break function of an advanced
+timer in which the complementary outputs have been configured. It has no effect
+if no complementary output is present. When the capture-compare output is
+disabled, the output is also disabled.
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
+*/
+
void timer_set_disabled_off_state_in_run_mode(u32 timer_peripheral)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSR;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Enable Off-State in Idle Mode
+
+Enables the off-state in idle mode for the break function of an advanced
+timer. When the master output is disabled the output is set to its
+inactive level as defined by the output polarity.
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
+*/
+
void timer_set_enabled_off_state_in_idle_mode(u32 timer_peripheral)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSI;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Disable Off-State in Idle Mode
+
+Disables the off-state in idle mode for the break function of an advanced
+timer. When the master output is disabled the output is also disabled.
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
+*/
+
void timer_set_disabled_off_state_in_idle_mode(u32 timer_peripheral)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSI;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Lock Bits
+
+Set the lock bits for an advanced timer. Three levels of lock providing
+protection against software errors. Once written they cannot be changed until a
+timer reset has occurred.
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
+@param[in] lock Unsigned int32. Lock specification @ref tim_lock
+*/
+
void timer_set_break_lock(u32 timer_peripheral, u32 lock)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= lock;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Deadtime
+
+The deadtime and sampling clock (DTSC) is set in the clock division ratio part of the
+timer mode settings. The deadtime count is an 8 bit value defined in terms of the
+number of DTSC cycles:
+
+@li Bit 7 = 0, deadtime = bits(6:0)
+@li Bits 7:6 = 10, deadtime = 2x(64+bits(5:0))
+@li Bits 7:5 = 110, deadtime = 8x(32+bits(5:0))
+@li Bits 7:5 = 111, deadtime = 16x(32+bits(5:0))
+
+@note This setting is only valid for the advanced timers.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
+@param[in] deadtime Unsigned int32. Deadtime count specification as defined above.
+*/
+
void timer_set_deadtime(u32 timer_peripheral, u32 deadtime)
{
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= deadtime;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Force generate a timer event.
+
+The event specification consists of 8 possible events that can be forced on the
+timer. The forced events are automatically cleared by hardware. The UG event is
+useful to cause shadow registers to be preloaded before the timer is started to
+avoid uncertainties in the first cycle in case an update event may never be
+generated.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@param[in] event Unsigned int32. Event specification @ref tim_event_gen
+*/
+
void timer_generate_event(u32 timer_peripheral, u32 event)
{
TIM_EGR(timer_peripheral) |= event;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Read Counter
+
+Read back the value of a timer's counter register contents
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@returns Unsigned int32. Counter value.
+*/
+
u32 timer_get_counter(u32 timer_peripheral)
{
return TIM_CNT(timer_peripheral);
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Input Capture Filter Parameters
+
+Set the input filter parameters for an input channel, specifying:
+@li the frequency of sampling from the Deadtime and Sampling clock
+(@see @ref timer_set_clock_division)
+@li the number of events that must occur before a transition is considered valid.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@param[in] ic ::tim_ic_id. Input Capture channel designator.
+@param[in] flt ::tim_ic_filter. Input Capture Filter identifier.
+*/
+
void timer_ic_set_filter(u32 timer, enum tim_ic_id ic, enum tim_ic_filter flt)
{
switch (ic) {
@@ -937,6 +1703,16 @@ void timer_ic_set_filter(u32 timer, enum tim_ic_id ic, enum tim_ic_filter flt)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Input Capture Prescaler
+
+Set the number of events between each capture.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@param[in] ic ::tim_ic_id. Input Capture channel designator.
+@param[in] psc ::tim_ic_psc. Input Capture sample clock prescaler.
+*/
+
void timer_ic_set_prescaler(u32 timer, enum tim_ic_id ic, enum tim_ic_psc psc)
{
switch (ic) {
@@ -959,6 +1735,27 @@ void timer_ic_set_prescaler(u32 timer, enum tim_ic_id ic, enum tim_ic_psc psc)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Capture/Compare Channel Direction/Input
+
+The Capture/Compare channel is defined as output (compare) or input with the input
+mapping specified:
+
+@li channel is configured as output
+@li channel is configured as input and mapped on corresponding input
+@li channel is configured as input and mapped on alternate input
+(TI2 for channel 1, TI1 for channel 2, TI4 for channel 3, TI3 for channel 4)
+@li channel is configured as input and is mapped on TRC (requires an
+internal trigger input selected through TS bit
+
+@note not all combinations of the input and channel are valid, see datasheets.
+@note these parameters are writable only when the channel is off.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@param[in] ic ::tim_ic_id. Input Capture channel designator.
+@param[in] in ::tim_ic_input. Input Capture channel direction and source input.
+*/
+
void timer_ic_set_input(u32 timer, enum tim_ic_id ic, enum tim_ic_input in)
{
in &= 3;
@@ -989,6 +1786,14 @@ void timer_ic_set_input(u32 timer, enum tim_ic_id ic, enum tim_ic_input in)
}
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Input Polarity
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@param[in] ic ::tim_ic_id. Input Capture channel designator.
+@param[in] pol ::tim_ic_pol. Input Capture polarity.
+*/
+
void timer_ic_set_polarity(u32 timer, enum tim_ic_id ic, enum tim_ic_pol pol)
{
if (pol)
@@ -997,28 +1802,70 @@ void timer_ic_set_polarity(u32 timer, enum tim_ic_id ic, enum tim_ic_pol pol)
TIM_CCER(timer) &= ~(0x2 << (ic * 4));
}
+/*---------------------------------------------------------------------------*/
+/** @brief Enable Timer Input Capture
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@param[in] ic ::tim_ic_id. Input Capture channel designator.
+*/
+
void timer_ic_enable(u32 timer, enum tim_ic_id ic)
{
TIM_CCER(timer) |= (0x1 << (ic * 4));
}
+/*---------------------------------------------------------------------------*/
+/** @brief Disable Timer Input Capture
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@param[in] ic ::tim_ic_id. Input Capture channel designator.
+*/
+
void timer_ic_disable(u32 timer, enum tim_ic_id ic)
{
TIM_CCER(timer) &= ~(0x1 << (ic * 4));
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set External Trigger Filter Parameters for Slave
+
+Set the input filter parameters for the external trigger, specifying:
+@li the frequency of sampling from the Deadtime and Sampling clock
+(@see @ref timer_set_clock_division)
+@li the number of events that must occur before a transition is considered valid.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@param[in] flt ::tim_ic_filter. Input Capture Filter identifier.
+*/
+
void timer_slave_set_filter(u32 timer, enum tim_ic_filter flt)
{
TIM_SMCR(timer) &= ~TIM_SMCR_ETF_MASK;
TIM_SMCR(timer) |= flt << 8;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set External Trigger Prescaler for Slave
+
+Set the external trigger frequency division ratio.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@param[in] psc ::tim_ic_psc. Input Capture sample clock prescaler.
+*/
+
void timer_slave_set_prescaler(u32 timer, enum tim_ic_psc psc)
{
TIM_SMCR(timer) &= ~TIM_SMCR_ETPS_MASK;
TIM_SMCR(timer) |= psc << 12;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set External Trigger Polarity for Slave
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@param[in] pol ::tim_ic_pol. Input Capture polarity.
+*/
+
void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol)
{
if (pol)
@@ -1027,15 +1874,48 @@ void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol)
TIM_SMCR(timer) &= ~TIM_SMCR_ETP;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Slave Mode
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@param[in] mode Unsigned int8. Slave mode @ref tim_sms
+*/
+
void timer_slave_set_mode(u32 timer, u8 mode)
{
TIM_SMCR(timer) &= ~TIM_SMCR_SMS_MASK;
TIM_SMCR(timer) |= mode;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Set Slave Trigger Source
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@param[in] trigger Unsigned int8. Slave trigger source @ref tim_ts
+*/
+
void timer_slave_set_trigger(u32 timer, u8 trigger)
{
TIM_SMCR(timer) &= ~TIM_SMCR_TS_MASK;
TIM_SMCR(timer) |= trigger;
}
+/*---------------------------------------------------------------------------*/
+/** @brief Force Timer Event
+
+A number of events can be forced by software action. All events are cleared by
+hardware on completion.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@param[in] event Unsigned int8. Event identifier @ref tim_event_gen.
+More than one event can be forced at the same time by logical OR of the event
+identifiers.
+*/
+
+void timer_force_event(u32 timer, u8 event)
+{
+ TIM_EGR(timer) = event;
+}
+
+/* TODO Timer DMA burst */
+