add square wave tick counter using timer
This commit is contained in:
parent
c59e11fd6b
commit
39d17b4940
|
@ -17,7 +17,7 @@
|
|||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||
* @date 2016
|
||||
* @note user RAM is not handled
|
||||
* @note peripherals used: I2C @ref rtc_ds1307_i2c, GPIO @ref rtc_ds1307_square_wave
|
||||
* @note peripherals used: I2C @ref rtc_ds1307_i2c, GPIO & timer @ref rtc_ds1307_square_wave_timer
|
||||
*/
|
||||
|
||||
/* standard libraries */
|
||||
|
@ -31,34 +31,23 @@
|
|||
#include <libopencm3/stm32/i2c.h> // I2C library
|
||||
#include <libopencm3/cm3/nvic.h> // interrupt handler
|
||||
#include <libopencmsis/core_cm3.h> // Cortex M3 utilities
|
||||
#include <libopencm3/stm32/timer.h> // timer utilities
|
||||
|
||||
#include "global.h" // global utilities
|
||||
#include "rtc_ds1307.h" // RTC header and definitions
|
||||
|
||||
/** @defgroup rtc_ds1307_i2c I2C peripheral used to communication with the DS1307 RTC IC
|
||||
* @{
|
||||
*/
|
||||
/** I2C peripheral */
|
||||
#define I2C I2C1 /**< I2C peripheral */
|
||||
#define I2C_RCC RCC_I2C1 /**< I2C peripheral clock */
|
||||
#define I2C_PORT GPIOB /**< I2C peripheral port */
|
||||
#define I2C_PIN_SDA GPIO_I2C1_SDA /**< I2C peripheral data pin (PB7) */
|
||||
#define I2C_PIN_SCL GPIO_I2C1_SCL /**< I2C peripheral clock pin (PB6) */
|
||||
/** @} */
|
||||
#define I2C_ADDR 0x68 /**< DS1307 I2C address (fixed to 0b1101000) */
|
||||
|
||||
#if defined(SQUARE_WAVE_EXTI) && defined(SQUARE_WAVE_IRQ) && defined(SQUARE_WAVE_ISR) && defined(SQUARE_WAVE_HANDLING) && SQUARE_WAVE_HANDLING
|
||||
volatile bool square_wave_flag = false;
|
||||
#if defined(SQUARE_WAVE_TICKS)
|
||||
volatile bool rtc_tick_flag = false;
|
||||
#endif
|
||||
|
||||
void rtc_setup(void)
|
||||
{
|
||||
/* enable peripheral */
|
||||
// enable peripheral
|
||||
rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternate function
|
||||
rcc_periph_clock_enable(I2C_RCC); // enable clock for I2C peripheral
|
||||
gpio_set_mode(I2C_PORT, GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, I2C_PIN_SDA | I2C_PIN_SCL); // setup I2C pin
|
||||
|
||||
/* configure I2C peripheral (see RM008 26.3.3, I2C master) */
|
||||
// configure I2C peripheral (see RM008 26.3.3, I2C master)
|
||||
i2c_reset(I2C); // reset configuration
|
||||
i2c_peripheral_disable(I2C); // I2C needs to be disable to be configured
|
||||
i2c_set_clock_frequency(I2C, rcc_apb1_frequency/1E6); // configure the peripheral clock to the APB1 freq (where it is connected to)
|
||||
|
@ -67,20 +56,28 @@ void rtc_setup(void)
|
|||
i2c_set_trise(I2C, rcc_apb1_frequency/1E6); // max rise time for 100 kHz is 1000 ns (~1 MHz)
|
||||
i2c_peripheral_enable(I2C); // enable I2C after configuration completed
|
||||
|
||||
/* setup square wave interrupt input */
|
||||
#if defined(SQUARE_WAVE_RCC) && defined(SQUARE_WAVE_PORT) && defined(SQUARE_WAVE_PIN)
|
||||
rcc_periph_clock_enable(SQUARE_WAVE_RCC); // enable GPIO peripheral
|
||||
gpio_set_mode(SQUARE_WAVE_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, SQUARE_WAVE_PIN); // set pin to input with pull up
|
||||
gpio_set(SQUARE_WAVE_PORT, SQUARE_WAVE_PIN); // pull up since the square wave output is open drain
|
||||
#if defined(SQUARE_WAVE_EXTI) && defined(SQUARE_WAVE_IRQ) && defined(SQUARE_WAVE_ISR)
|
||||
rcc_periph_clock_enable(RCC_AFIO); // enable alternate function clock for external interrupt
|
||||
exti_select_source(SQUARE_WAVE_EXTI, SQUARE_WAVE_PORT); // mask external interrupt of this pin only for this port
|
||||
exti_set_trigger(SQUARE_WAVE_EXTI, EXTI_TRIGGER_FALLING); // trigger on falling
|
||||
exti_enable_request(SQUARE_WAVE_EXTI); // enable external interrupt
|
||||
nvic_enable_irq(SQUARE_WAVE_IRQ); // enable interrupt
|
||||
#if defined(SQUARE_WAVE_TICKS)
|
||||
// setup timer to generate tick from square wave output
|
||||
rcc_periph_clock_enable(SQUARE_WAVE_GPIO_RCC); // enable clock for GPIO peripheral
|
||||
gpio_set_mode(SQUARE_WAVE_GPIO_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, SQUARE_WAVE_GPIO_PIN); // set pin as input
|
||||
gpio_set(SQUARE_WAVE_GPIO_PORT, SQUARE_WAVE_GPIO_PIN); // enable pull-up
|
||||
rcc_periph_clock_enable(SQUARE_WAVE_TIMER_RCC); // enable clock for timer peripheral
|
||||
timer_reset(SQUARE_WAVE_TIMER); // reset timer state
|
||||
timer_ic_set_input(SQUARE_WAVE_TIMER, SQUARE_WAVE_TIMER_IC, SQUARE_WAVE_TIMER_IN); // configure channel as input capture
|
||||
timer_ic_set_filter(SQUARE_WAVE_TIMER, SQUARE_WAVE_TIMER_IC, TIM_IC_OFF); // use no input capture filter
|
||||
timer_ic_set_polarity(SQUARE_WAVE_TIMER, SQUARE_WAVE_TIMER_IC, TIM_IC_FALLING); //capture on falling edge
|
||||
timer_slave_set_trigger(SQUARE_WAVE_TIMER, SQUARE_WAVE_TIMER_TS); // select trigger
|
||||
timer_slave_set_mode(SQUARE_WAVE_TIMER, TIM_SMCR_SMS_ECM1); // select external clock more 1 as input
|
||||
timer_ic_enable(SQUARE_WAVE_TIMER, SQUARE_WAVE_TIMER_IC); // enable input capture
|
||||
timer_set_mode(SQUARE_WAVE_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(SQUARE_WAVE_TIMER, 0); // no need to prescale
|
||||
timer_set_period(SQUARE_WAVE_TIMER, SQUARE_WAVE_TICKS-1); // set the tick period
|
||||
timer_enable_irq(SQUARE_WAVE_TIMER, TIM_DIER_UIE); // enable interrupt for timer
|
||||
nvic_enable_irq(SQUARE_WAVE_TIMER_IRQ); // allow interrupt for timer
|
||||
rtc_tick_flag = false; // reset RTC tick flag
|
||||
timer_enable_counter(SQUARE_WAVE_TIMER); // enable timer to count ticks
|
||||
rtc_write_square_wave(SQUARE_WAVE_FREQUENCY); // set square wave output frequency
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/** @brief read memory from RTC IC
|
||||
|
@ -447,12 +444,14 @@ bool rtc_write_time(uint8_t seconds, uint8_t minutes, uint8_t hours, uint8_t day
|
|||
return rtc_write_memory(0, data, LENGTH(data)); // write time values on RTC
|
||||
}
|
||||
|
||||
#if defined(SQUARE_WAVE_EXTI) && defined(SQUARE_WAVE_IRQ) && defined(SQUARE_WAVE_ISR) && defined(SQUARE_WAVE_HANDLING) && SQUARE_WAVE_HANDLING
|
||||
/** @brief square wave input interrupt */
|
||||
void SQUARE_WAVE_ISR(void)
|
||||
#if defined(SQUARE_WAVE_TICKS)
|
||||
/** @brief timer interrupt service routine called when number of ticks have been received */
|
||||
void SQUARE_WAVE_TIMER_ISR(void)
|
||||
{
|
||||
exti_reset_request(SQUARE_WAVE_EXTI); // reset interrupt
|
||||
square_wave_flag = true; // update flag
|
||||
if (timer_get_flag(SQUARE_WAVE_TIMER, TIM_SR_UIF)) { // overflow even happened
|
||||
timer_clear_flag(SQUARE_WAVE_TIMER, TIM_SR_UIF); // clear flag
|
||||
rtc_tick_flag = true; // update flag
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -17,24 +17,42 @@
|
|||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||
* @date 2016
|
||||
* @note user RAM is not handled
|
||||
* @note peripherals used: I2C @ref rtc_ds1307_i2c, GPIO @ref rtc_ds1307_square_wave
|
||||
* @note peripherals used: I2C @ref rtc_ds1307_i2c, GPIO & timer @ref rtc_ds1307_square_wave_timer
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/** @defgroup rtc_ds1307_square_wave connect Maxim DS1307 square wave output (on PB10)
|
||||
/** @defgroup rtc_ds1307_i2c I2C peripheral used to communication with the DS1307 RTC IC
|
||||
* @{
|
||||
*/
|
||||
#define SQUARE_WAVE_RCC RCC_GPIOB /**< GPIO peripheral clock (port B) */
|
||||
#define SQUARE_WAVE_PORT GPIOB /**< GPIO port (port B) */
|
||||
#define SQUARE_WAVE_PIN GPIO10 /**< GPIO pin (pin PA10) */
|
||||
#define SQUARE_WAVE_EXTI EXTI10 /**< GPIO external interrupt (exti 10 for pin 12) */
|
||||
//#define SQUARE_WAVE_IRQ NVIC_EXTI15_10_IRQ /**< GPIO line interrupt (interrupt for line 15 to 10 for pin 10) */
|
||||
//#define SQUARE_WAVE_ISR exti15_10_isr /**< GPIO line interrupt service routine (isr for line 15 to 10 for pin 10) */
|
||||
//#define SQUARE_WAVE_HANDLING true /**< to to have the library handle the square wave interrupt (setting square_wave_flag) */
|
||||
/** I2C peripheral */
|
||||
#define I2C I2C1 /**< I2C peripheral */
|
||||
#define I2C_RCC RCC_I2C1 /**< I2C peripheral clock */
|
||||
#define I2C_PORT GPIOB /**< I2C peripheral port */
|
||||
#define I2C_PIN_SDA GPIO_I2C1_SDA /**< I2C peripheral data pin (PB7) */
|
||||
#define I2C_PIN_SCL GPIO_I2C1_SCL /**< I2C peripheral clock pin (PB6) */
|
||||
#define I2C_ADDR 0x68 /**< DS1307 I2C address (fixed to 0b1101000) */
|
||||
/** @} */
|
||||
|
||||
#if defined(SQUARE_WAVE_EXTI) && defined(SQUARE_WAVE_IRQ) && defined(SQUARE_WAVE_ISR) && defined(SQUARE_WAVE_HANDLING) && SQUARE_WAVE_HANDLING
|
||||
extern volatile bool square_wave_flag; /**< set on square wave output */
|
||||
/** @defgroup rtc_ds1307_square_wave_timer timer peripheral used to count timer based on RTC IC square wave output
|
||||
* @note comment out SQUARE_WAVE_TICS to not disable feature
|
||||
* @{
|
||||
*/
|
||||
#define SQUARE_WAVE_TICKS SQUARE_WAVE_FREQUENCY/256 /**< number of square wave tics before setting rtc_tic_flag */
|
||||
#define SQUARE_WAVE_FREQUENCY 4096 /**< square wave output frequency from the RTC IC */
|
||||
#define SQUARE_WAVE_TIMER TIM2 /**< timer peripheral */
|
||||
#define SQUARE_WAVE_TIMER_RCC RCC_TIM2 /**< timer peripheral clock */
|
||||
#define SQUARE_WAVE_TIMER_IC TIM_IC1 /**< input capture channel (for TIM2_CH1) */
|
||||
#define SQUARE_WAVE_TIMER_IN TIM_IC_IN_TI1 /**< input capture input source (TIM2_CH1 becomes TI1, then TI1F, then TI1FP1) */
|
||||
#define SQUARE_WAVE_TIMER_TS TIM_SMCR_TS_IT1FP1 /**< input capture trigger (actually TI1FP1) */
|
||||
#define SQUARE_WAVE_TIMER_IRQ NVIC_TIM2_IRQ /**< timer interrupt */
|
||||
#define SQUARE_WAVE_TIMER_ISR tim2_isr /**< timer interrupt service routine */
|
||||
#define SQUARE_WAVE_GPIO_RCC RCC_GPIOA /**< timer port peripheral clock (TIM2_CH1 on PA0)*/
|
||||
#define SQUARE_WAVE_GPIO_PORT GPIOA /**< timer port (TIM2_CH1 on PA0) */
|
||||
#define SQUARE_WAVE_GPIO_PIN GPIO_TIM2_CH1_ETR /**< timer pin input, connect to RTC IC square wave output (TIM2_CH1 on PA0) */
|
||||
/** @} */
|
||||
|
||||
#if defined(SQUARE_WAVE_TICKS)
|
||||
extern volatile bool rtc_tick_flag; /**< set on SQUARE_WAVE_TICS square wave tics */
|
||||
#endif
|
||||
|
||||
/** @brief setup communication with RTC IC
|
||||
|
|
Loading…
Reference in New Issue