diff --git a/global.h b/global.h index c1cbd56..c110f03 100644 --- a/global.h +++ b/global.h @@ -353,6 +353,8 @@ #define TIM(x) CAT2(TIM,x) /** get RCC for timer based on TIM identifier */ #define RCC_TIM(x) CAT2(RCC_TIM,x) +/** get RST for timer based on TIM identifier */ +#define RST_TIM(x) CAT2(RST_TIM,x) /** get NVIC IRQ for timer base on TIM identifier */ #define NVIC_TIM_IRQ(x) CAT3(NVIC_TIM,x,_IRQ) /** get interrupt service routine for timer base on TIM identifier */ diff --git a/lib/ir_nec.c b/lib/ir_nec.c index 9b4213a..f3a265f 100644 --- a/lib/ir_nec.c +++ b/lib/ir_nec.c @@ -60,7 +60,7 @@ void ir_nec_setup(bool extended) rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternative functions gpio_set(TIM_CH_PORT(IR_NEC_TIMER, IR_NEC_CHANNEL), TIM_CH_PIN(IR_NEC_TIMER, IR_NEC_CHANNEL)); // idle is high (using pull-up resistor) gpio_set_mode(TIM_CH_PORT(IR_NEC_TIMER, IR_NEC_CHANNEL), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, TIM_CH_PIN(IR_NEC_TIMER, IR_NEC_CHANNEL)); // setup GPIO pin as input - timer_reset(TIM(IR_NEC_TIMER)); // reset timer state + rcc_periph_reset_pulse(RST_TIM(IR_NEC_TIMER)); // reset timer state timer_set_mode(TIM(IR_NEC_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock,edge alignment (simple count), and count up // codes are repeated every 110 ms, thus we need to measure at least this duration to detect repeats correctly // the 16-bit timer is by far precise enough to measure the smallest 560 us burst diff --git a/lib/led_tm1637.c b/lib/led_tm1637.c index a63174d..385dfea 100644 --- a/lib/led_tm1637.c +++ b/lib/led_tm1637.c @@ -176,7 +176,7 @@ void led_tm1637_setup(void) // setup timer to create signal timing (each tick is used for a single GPIO transition) rcc_periph_clock_enable(RCC_TIM(LED_TM1637_TIMER)); // enable clock for timer block - timer_reset(TIM(LED_TM1637_TIMER)); // reset timer state + rcc_periph_reset_pulse(RST_TIM(LED_TM1637_TIMER)); // reset timer state timer_set_mode(TIM(LED_TM1637_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up timer_set_prescaler(TIM(LED_TM1637_TIMER), 0); // don't prescale to get most precise timing ( 1/(72E6/1/(2**16))=0.91 ms > 0.5 us ) timer_set_period(TIM(LED_TM1637_TIMER), 500); // set the clock frequency (emprical value until the signal starts to look bad) diff --git a/lib/led_ws2812b.c b/lib/led_ws2812b.c index 3c43ae7..c43ecb1 100644 --- a/lib/led_ws2812b.c +++ b/lib/led_ws2812b.c @@ -113,7 +113,7 @@ void led_ws2812b_setup(void) gpio_set_mode(TIM_CH_PORT(LED_WS2812B_TIMER, LED_WS2812B_CLK_CH), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, TIM_CH_PIN(LED_WS2812B_TIMER, LED_WS2812B_CLK_CH)); // set pin as output rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternate function (PWM) rcc_periph_clock_enable(RCC_TIM(LED_WS2812B_TIMER)); // enable clock for timer peripheral - timer_reset(TIM(LED_WS2812B_TIMER)); // reset timer state + rcc_periph_reset_pulse(RST_TIM(LED_WS2812B_TIMER)); // reset timer state timer_set_mode(TIM(LED_WS2812B_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up timer_set_prescaler(TIM(LED_WS2812B_TIMER), 0); // no prescaler to keep most precise timer (72MHz/2^16=1099<800kHz) timer_set_period(TIM(LED_WS2812B_TIMER), rcc_ahb_frequency/800000/3-1); // set the clock frequency to 800kHz*3bit since we need to send 3 bits to output a 800kbps stream diff --git a/lib/microwire_master.c b/lib/microwire_master.c index f0343d2..13c6335 100644 --- a/lib/microwire_master.c +++ b/lib/microwire_master.c @@ -78,7 +78,7 @@ void microwire_master_setup(uint32_t frequency, bool organization_x16, uint8_t a // setup timer to generate timing for the signal rcc_periph_clock_enable(RCC_TIM(MICROWIRE_MASTER_TIMER)); // enable clock for timer domain - timer_reset(TIM(MICROWIRE_MASTER_TIMER)); // reset timer state + rcc_periph_reset_pulse(RST_TIM(MICROWIRE_MASTER_TIMER)); // reset timer state timer_set_mode(TIM(MICROWIRE_MASTER_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up uint16_t prescaler = rcc_ahb_frequency/(frequency*2)/(uint32_t)(1<<16)+1; // calculate prescaler for most accurate timing for this speed timer_set_prescaler(TIM(MICROWIRE_MASTER_TIMER), prescaler-1); // set calculated prescaler diff --git a/lib/onewire_master.c b/lib/onewire_master.c index 674c3dd..51f444f 100644 --- a/lib/onewire_master.c +++ b/lib/onewire_master.c @@ -175,7 +175,7 @@ void onewire_master_setup(void) // setup timer to generate/measure signal timing rcc_periph_clock_enable(RCC_TIM(ONEWIRE_MASTER_TIMER)); // enable clock for timer peripheral - timer_reset(TIM(ONEWIRE_MASTER_TIMER)); // reset timer state + rcc_periph_reset_pulse(RST_TIM(ONEWIRE_MASTER_TIMER)); // reset timer state timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer to configure it timer_set_mode(TIM(ONEWIRE_MASTER_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up timer_set_prescaler(TIM(ONEWIRE_MASTER_TIMER), 1-1); // don't use prescale since this 16 bits timer allows to wait > 480 us used for the reset pulse ( 1/(72E6/1/(2**16))=910us ) @@ -207,7 +207,7 @@ void onewire_master_release(void) { // release timer timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer - timer_reset(TIM(ONEWIRE_MASTER_TIMER)); // reset timer state + rcc_periph_reset_pulse(RST_TIM(ONEWIRE_MASTER_TIMER)); // reset timer state rcc_periph_clock_disable(RCC_TIM(ONEWIRE_MASTER_TIMER)); // disable clock for timer peripheral // release GPIO diff --git a/lib/onewire_slave.c b/lib/onewire_slave.c index 5e08fb9..0bf87ab 100644 --- a/lib/onewire_slave.c +++ b/lib/onewire_slave.c @@ -123,7 +123,7 @@ void onewire_slave_setup(uint8_t family, uint64_t serial) // setup timer to generate/measure signal timing rcc_periph_clock_enable(RCC_TIM(ONEWIRE_SLAVE_TIMER)); // enable clock for timer peripheral - timer_reset(TIM(ONEWIRE_SLAVE_TIMER)); // reset timer state + rcc_periph_reset_pulse(RST_TIM(ONEWIRE_SLAVE_TIMER)); // reset timer state timer_set_mode(TIM(ONEWIRE_SLAVE_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up timer_set_prescaler(TIM(ONEWIRE_SLAVE_TIMER), 1-1); // don't use prescale since this 16 bits timer allows to wait > 480 us used for the reset pulse ( 1/(72E6/1/(2**16))=910us ) diff --git a/lib/rtc_dcf77.c b/lib/rtc_dcf77.c index 81e8049..bd56ac4 100644 --- a/lib/rtc_dcf77.c +++ b/lib/rtc_dcf77.c @@ -90,7 +90,7 @@ void rtc_dcf77_setup(void) // setup timer to sample signal at 1kHz rcc_periph_clock_enable(RCC_TIM(RTC_DCF77_TIMER)); // enable clock for timer peripheral - timer_reset(TIM(RTC_DCF77_TIMER)); // reset timer state + rcc_periph_reset_pulse(RST_TIM(RTC_DCF77_TIMER)); // reset timer state timer_set_mode(TIM(RTC_DCF77_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up timer_set_prescaler(TIM(RTC_DCF77_TIMER), 1); // set prescaler to divide frequency by two, to be able to have a period of 1 kHz (72MHz/2/2^16=549Hz<1kHz) timer_set_period(TIM(RTC_DCF77_TIMER), rcc_ahb_frequency/2/1000-1); // set period to 1kHz (plus hand tuning) diff --git a/lib/sensor_dht11.c b/lib/sensor_dht11.c index 3433724..54fda03 100644 --- a/lib/sensor_dht11.c +++ b/lib/sensor_dht11.c @@ -77,7 +77,7 @@ void sensor_dht11_setup(void) // setup timer to measure signal timing for bit decoding (use timer channel as input capture) rcc_periph_clock_enable(RCC_TIM_CH(SENSOR_DHT11_TIMER,SENSOR_DHT11_CHANNEL)); // enable clock for GPIO peripheral rcc_periph_clock_enable(RCC_TIM(SENSOR_DHT11_TIMER)); // enable clock for timer peripheral - timer_reset(TIM(SENSOR_DHT11_TIMER)); // reset timer state + rcc_periph_reset_pulse(RST_TIM(SENSOR_DHT11_TIMER)); // reset timer state timer_set_mode(TIM(SENSOR_DHT11_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock,edge alignment (simple count), and count up timer_set_prescaler(TIM(SENSOR_DHT11_TIMER), 20-1); // set the prescaler so this 16 bits timer allows to wait for 18 ms for the start signal ( 1/(72E6/20/(2**16))=18.20ms ) timer_ic_set_input(TIM(SENSOR_DHT11_TIMER), TIM_IC(SENSOR_DHT11_CHANNEL), TIM_IC_IN_TI(SENSOR_DHT11_CHANNEL)); // configure ICx to use TIn diff --git a/lib/sensor_dht22.c b/lib/sensor_dht22.c index 8c97e31..646d10e 100644 --- a/lib/sensor_dht22.c +++ b/lib/sensor_dht22.c @@ -81,7 +81,7 @@ void sensor_dht22_setup(void) // setup timer to measure signal timing for bit decoding (use timer channel as input capture) rcc_periph_clock_enable(RCC_TIM_CH(SENSOR_DHT22_TIMER,SENSOR_DHT22_CHANNEL)); // enable clock for GPIO peripheral rcc_periph_clock_enable(RCC_TIM(SENSOR_DHT22_TIMER)); // enable clock for timer peripheral - timer_reset(TIM(SENSOR_DHT22_TIMER)); // reset timer state + rcc_periph_reset_pulse(RST_TIM(SENSOR_DHT22_TIMER)); // reset timer state timer_set_mode(TIM(SENSOR_DHT22_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock,edge alignment (simple count), and count up timer_set_prescaler(TIM(SENSOR_DHT22_TIMER), 2-1); // set the prescaler so this 16 bits timer allows to wait for 18 ms for the start signal ( 1/(72E6/2/(2**16))=1.820ms ) timer_ic_set_input(TIM(SENSOR_DHT22_TIMER), TIM_IC(SENSOR_DHT22_CHANNEL), TIM_IC_IN_TI(SENSOR_DHT22_CHANNEL)); // configure ICx to use TIn diff --git a/lib/sensor_pzem.c b/lib/sensor_pzem.c index 283cf1c..998cc15 100644 --- a/lib/sensor_pzem.c +++ b/lib/sensor_pzem.c @@ -79,7 +79,7 @@ void sensor_pzem_setup(void) // setup timer to wait for minimal time before next transmission (after previous transmission or reception) rcc_periph_clock_enable(RCC_TIM(SENSOR_PZEM_TIMER)); // enable clock for timer block - timer_reset(TIM(SENSOR_PZEM_TIMER)); // reset timer state + rcc_periph_reset_pulse(RST_TIM(SENSOR_PZEM_TIMER)); // reset timer state timer_set_mode(TIM(SENSOR_PZEM_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock,edge alignment (simple count), and count up timer_one_shot_mode(TIM(SENSOR_PZEM_TIMER)); // stop counter after update event (we only need to count down once) timer_set_prescaler(TIM(SENSOR_PZEM_TIMER), 550-1); // set the prescaler so this 16 bits timer allows to wait for maximum 500 ms ( 1/(72E6/550/(2**16))=500.62ms ) diff --git a/lib/sensor_sdm120.c b/lib/sensor_sdm120.c index 06a5bdc..5b1d191 100644 --- a/lib/sensor_sdm120.c +++ b/lib/sensor_sdm120.c @@ -153,7 +153,7 @@ void sensor_sdm120_setup(uint32_t baudrate) // setup timer to wait for minimal time before next transmission rcc_periph_clock_enable(RCC_TIM(SENSOR_SDM120_TIMER)); // enable clock for timer block - timer_reset(TIM(SENSOR_SDM120_TIMER)); // reset timer state + rcc_periph_reset_pulse(RST_TIM(SENSOR_SDM120_TIMER)); // reset timer state timer_set_mode(TIM(SENSOR_SDM120_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock,edge alignment (simple count), and count up timer_one_shot_mode(TIM(SENSOR_SDM120_TIMER)); // stop counter after update event (we only need to count down once) timer_set_prescaler(TIM(SENSOR_SDM120_TIMER), 66-1); // set the prescaler so this 16 bits timer allows to wait for 60 ms ( 1/(72E6/66/(2**16))=60.07ms ) diff --git a/lib/uart_soft.c b/lib/uart_soft.c index 9759764..8475fa1 100644 --- a/lib/uart_soft.c +++ b/lib/uart_soft.c @@ -173,7 +173,7 @@ bool uart_soft_setup(uint32_t *rx_baudrates, uint32_t *tx_baudrates) // setup timer #if defined(UART_SOFT_RX_TIMER) rcc_periph_clock_enable(RCC_TIM(UART_SOFT_RX_TIMER)); // enable clock for timer peripheral - timer_reset(TIM(UART_SOFT_RX_TIMER)); // reset timer state + rcc_periph_reset_pulse(RST_TIM(UART_SOFT_RX_TIMER)); // reset timer state timer_set_mode(TIM(UART_SOFT_RX_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up timer_set_prescaler(TIM(UART_SOFT_RX_TIMER), 0); // prescaler to be able to sample 2400-115200 bps (72MHz/2^16=1099<2400bps) nvic_enable_irq(NVIC_TIM_IRQ(UART_SOFT_RX_TIMER)); // allow interrupt for timer @@ -181,7 +181,7 @@ bool uart_soft_setup(uint32_t *rx_baudrates, uint32_t *tx_baudrates) #endif #if defined(UART_SOFT_TX_TIMER) rcc_periph_clock_enable(RCC_TIM(UART_SOFT_TX_TIMER)); // enable clock for timer peripheral - timer_reset(TIM(UART_SOFT_TX_TIMER)); // reset timer state + rcc_periph_reset_pulse(RST_TIM(UART_SOFT_TX_TIMER)); // reset timer state timer_set_mode(TIM(UART_SOFT_TX_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up timer_set_prescaler(TIM(UART_SOFT_TX_TIMER), 0); // prescaler to be able to output 2400-115200 bps (72MHz/2^16=1099<2400bps) nvic_enable_irq(NVIC_TIM_IRQ(UART_SOFT_TX_TIMER)); // allow interrupt for timer diff --git a/lib/vfd_hv518.c b/lib/vfd_hv518.c index 58a82bf..c429ebc 100644 --- a/lib/vfd_hv518.c +++ b/lib/vfd_hv518.c @@ -459,7 +459,7 @@ void vfd_setup(void) /* setup timer to refresh display */ rcc_periph_clock_enable(VFD_TIMER_RCC); // enable clock for timer block - timer_reset(VFD_TIMER); // reset timer state + rcc_periph_reset_pulse(RST_VFD_TIMER); // reset timer state timer_set_mode(VFD_TIMER, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock,edge alignment (simple count), and count up timer_set_prescaler(VFD_TIMER, (SYSTEM_CLOCK_FREQ/(1<<16))-1); // set the prescaler so this 16 bits timer overflows at 1Hz timer_set_period(VFD_TIMER, 0xffff/LENGTH(driver_data)/100); // set the refresh frequency