update library to use I2C macros

This commit is contained in:
King Kévin 2017-02-08 13:58:11 +01:00
parent 27c202a1a0
commit 4c9f28f69f
2 changed files with 73 additions and 76 deletions

View File

@ -36,6 +36,32 @@
#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 RTC_DS1307_I2C 2 /**< I2C peripheral */
#define RTC_DS1307_I2C_ADDR 0x68 /**< DS1307 I2C address (fixed to 0b1101000) */
/** @} */
/** @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 RTC_DS1307_SQUARE_WAVE_TICKS (RTC_DS1307_SQUARE_WAVE_FREQUENCY/256) /**< number of square wave tics before setting rtc_ds1307_tic_flag */
#define RTC_DS1307_SQUARE_WAVE_FREQUENCY 4096 /**< square wave output frequency from the RTC IC */
#define RTC_DS1307_SQUARE_WAVE_TIMER TIM2 /**< timer peripheral */
#define RTC_DS1307_SQUARE_WAVE_TIMER_RCC RCC_TIM2 /**< timer peripheral clock */
#define RTC_DS1307_SQUARE_WAVE_TIMER_IC TIM_IC1 /**< input capture channel (for TIM2_CH1) */
#define RTC_DS1307_SQUARE_WAVE_TIMER_IN TIM_IC_IN_TI1 /**< input capture input source (TIM2_CH1 becomes TI1, then TI1F, then TI1FP1) */
#define RTC_DS1307_SQUARE_WAVE_TIMER_TS TIM_SMCR_TS_IT1FP1 /**< input capture trigger (actually TI1FP1) */
#define RTC_DS1307_SQUARE_WAVE_TIMER_IRQ NVIC_TIM2_IRQ /**< timer interrupt */
#define RTC_DS1307_SQUARE_WAVE_TIMER_ISR tim2_isr /**< timer interrupt service routine */
#define RTC_DS1307_SQUARE_WAVE_GPIO_RCC RCC_GPIOA /**< timer port peripheral clock (TIM2_CH1 on PA0)*/
#define RTC_DS1307_SQUARE_WAVE_GPIO_PORT GPIOA /**< timer port (TIM2_CH1 on PA0) */
#define RTC_DS1307_SQUARE_WAVE_GPIO_PIN GPIO_TIM2_CH1_ETR /**< timer pin input, connect to RTC IC square wave output (TIM2_CH1 on PA0) */
/** @} */
#if defined(RTC_DS1307_SQUARE_WAVE_TICKS)
volatile uint32_t rtc_ds1307_ticks = 0;
volatile bool rtc_ds1307_tick_flag = false;
@ -43,18 +69,20 @@ volatile bool rtc_ds1307_tick_flag = false;
void rtc_ds1307_setup(void)
{
// configure I2C peripheral (see RM008 26.3.3, I2C master)
rcc_periph_clock_enable(RTC_DS1307_I2C_PORT_RCC); // enable clock for I2C I/O peripheral
gpio_set_mode(RTC_DS1307_I2C_PORT, GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, RTC_DS1307_I2C_PIN_SDA | RTC_DS1307_I2C_PIN_SCL); // setup I2C I/O pins
// configure I2C peripheral
rcc_periph_clock_enable(RCC_I2C_SCL_PORT(RTC_DS1307_I2C)); // enable clock for I2C I/O peripheral
gpio_set_mode(I2C_SCL_PORT(RTC_DS1307_I2C), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, I2C_SCL_PIN(RTC_DS1307_I2C)); // setup I2C I/O pins
rcc_periph_clock_enable(RCC_I2C_SCL_PORT(RTC_DS1307_I2C)); // enable clock for I2C I/O peripheral
gpio_set_mode(I2C_SDA_PORT(RTC_DS1307_I2C), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, I2C_SDA_PIN(RTC_DS1307_I2C)); // setup I2C I/O pins
rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternate function
rcc_periph_clock_enable(RTC_DS1307_I2C_RCC); // enable clock for I2C peripheral
i2c_reset(RTC_DS1307_I2C); // reset configuration
i2c_peripheral_disable(RTC_DS1307_I2C); // I2C needs to be disable to be configured
i2c_set_clock_frequency(RTC_DS1307_I2C, rcc_apb1_frequency/1E6); // configure the peripheral clock to the APB1 freq (where it is connected to)
i2c_set_standard_mode(RTC_DS1307_I2C); // the DS1307 has a maximum I2C SCL freq if 100 kHz (corresponding to the standard mode)
i2c_set_ccr(RTC_DS1307_I2C, rcc_apb1_frequency/(100E3*2)); // set Thigh/Tlow to generate frequency of 100 kHz
i2c_set_trise(RTC_DS1307_I2C, rcc_apb1_frequency/1E6); // max rise time for 100 kHz is 1000 ns (~1 MHz)
i2c_peripheral_enable(RTC_DS1307_I2C); // enable I2C after configuration completed
rcc_periph_clock_enable(RCC_I2C(RTC_DS1307_I2C)); // enable clock for I2C peripheral
i2c_reset(I2C(RTC_DS1307_I2C)); // reset configuration
i2c_peripheral_disable(I2C(RTC_DS1307_I2C)); // I2C needs to be disable to be configured
i2c_set_clock_frequency(I2C(RTC_DS1307_I2C), rcc_apb1_frequency/1000000); // configure the peripheral clock to the APB1 freq (where it is connected to)
i2c_set_standard_mode(I2C(RTC_DS1307_I2C)); // the DS1307 has a maximum I2C SCL freq if 100 kHz (corresponding to the standard mode)
i2c_set_ccr(I2C(RTC_DS1307_I2C), rcc_apb1_frequency/(100000*2)); // set Thigh/Tlow to generate frequency of 100 kHz
i2c_set_trise(I2C(RTC_DS1307_I2C), rcc_apb1_frequency/1000000); // max rise time for 100 kHz is 1000 ns (~1 MHz)
i2c_peripheral_enable(I2C(RTC_DS1307_I2C)); // enable I2C after configuration completed
#if defined(RTC_DS1307_SQUARE_WAVE_TICKS)
// setup timer to generate tick from square wave output
@ -92,41 +120,41 @@ static bool rtc_ds1307_read_memory(uint8_t addr, uint8_t* data, size_t len)
if (data==NULL || len==0) { // verify there it data to be read
goto error;
}
i2c_send_start(RTC_DS1307_I2C); // send start condition to start transaction
while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_SB)); // wait until start condition is transmitted
if (!(I2C_SR2(RTC_DS1307_I2C) & I2C_SR2_MSL)) { // verify if in master mode
i2c_send_start(I2C(RTC_DS1307_I2C)); // send start condition to start transaction
while (!(I2C_SR1(I2C(RTC_DS1307_I2C)) & I2C_SR1_SB)); // wait until start condition is transmitted
if (!(I2C_SR2(I2C(RTC_DS1307_I2C)) & I2C_SR2_MSL)) { // verify if in master mode
goto error;
}
i2c_send_7bit_address(RTC_DS1307_I2C, RTC_DS1307_I2C_ADDR, I2C_WRITE); // select slave
while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_ADDR)); // wait until address is transmitted
if (!((I2C_SR2(RTC_DS1307_I2C) & I2C_SR2_TRA))) { // verify we are in transmit mode (and read SR2 to clear ADDR)
i2c_send_7bit_address(I2C(RTC_DS1307_I2C), RTC_DS1307_I2C_ADDR, I2C_WRITE); // select slave
while (!(I2C_SR1(I2C(RTC_DS1307_I2C)) & I2C_SR1_ADDR)); // wait until address is transmitted
if (!((I2C_SR2(I2C(RTC_DS1307_I2C)) & I2C_SR2_TRA))) { // verify we are in transmit mode (and read SR2 to clear ADDR)
goto error;
}
i2c_send_data(RTC_DS1307_I2C, addr); // send memory address we want to read
while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_TxE)); // wait until byte has been transmitted
i2c_send_start(RTC_DS1307_I2C); // send restart condition to switch from write to read mode
while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_SB)); // wait until start condition is transmitted
i2c_send_7bit_address(RTC_DS1307_I2C, RTC_DS1307_I2C_ADDR, I2C_READ); // select slave
while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_ADDR)); // wait until address is transmitted
if ((I2C_SR2(RTC_DS1307_I2C) & I2C_SR2_TRA)) { // verify we are in read mode (and read SR2 to clear ADDR)
i2c_send_data(I2C(RTC_DS1307_I2C), addr); // send memory address we want to read
while (!(I2C_SR1(I2C(RTC_DS1307_I2C)) & I2C_SR1_TxE)); // wait until byte has been transmitted
i2c_send_start(I2C(RTC_DS1307_I2C)); // send restart condition to switch from write to read mode
while (!(I2C_SR1(I2C(RTC_DS1307_I2C)) & I2C_SR1_SB)); // wait until start condition is transmitted
i2c_send_7bit_address(I2C(RTC_DS1307_I2C), RTC_DS1307_I2C_ADDR, I2C_READ); // select slave
while (!(I2C_SR1(I2C(RTC_DS1307_I2C)) & I2C_SR1_ADDR)); // wait until address is transmitted
if ((I2C_SR2(I2C(RTC_DS1307_I2C)) & I2C_SR2_TRA)) { // verify we are in read mode (and read SR2 to clear ADDR)
goto error;
}
for (size_t i=0; i<len; i++) { // read bytes
if (i==len-1) { // prepare to sent NACK for last byte
i2c_disable_ack(RTC_DS1307_I2C); // NACK received to stop slave transmission
i2c_send_stop(RTC_DS1307_I2C); // send STOP after receiving byte
i2c_disable_ack(I2C(RTC_DS1307_I2C)); // NACK received to stop slave transmission
i2c_send_stop(I2C(RTC_DS1307_I2C)); // send STOP after receiving byte
} else {
i2c_enable_ack(RTC_DS1307_I2C); // ACK received byte to continue slave transmission
i2c_enable_ack(I2C(RTC_DS1307_I2C)); // ACK received byte to continue slave transmission
}
while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_RxNE)); // wait until byte has been received
data[i] = i2c_get_data(RTC_DS1307_I2C); // read received byte
while (!(I2C_SR1(I2C(RTC_DS1307_I2C)) & I2C_SR1_RxNE)); // wait until byte has been received
data[i] = i2c_get_data(I2C(RTC_DS1307_I2C)); // read received byte
}
to_return = true;
error:
if (I2C_SR2(RTC_DS1307_I2C) & I2C_SR2_BUSY) { // release bus if busy
i2c_send_stop(RTC_DS1307_I2C); // send stop to release bus
if (I2C_SR2(I2C(RTC_DS1307_I2C)) & I2C_SR2_BUSY) { // release bus if busy
i2c_send_stop(I2C(RTC_DS1307_I2C)); // send stop to release bus
}
while (I2C_SR2(RTC_DS1307_I2C) & I2C_SR2_MSL); // wait until bus released (non master mode)
while (I2C_SR2(I2C(RTC_DS1307_I2C)) & I2C_SR2_MSL); // wait until bus released (non master mode)
return to_return;
}
@ -257,28 +285,28 @@ static bool rtc_ds1307_write_memory(uint8_t addr, uint8_t* data, size_t len)
if (data==NULL || len==0) { // verify there it data to be read
goto error;
}
i2c_send_start(RTC_DS1307_I2C); // send start condition to start transaction
while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_SB)); // wait until start condition is transmitted
if (!(I2C_SR2(RTC_DS1307_I2C) & I2C_SR2_MSL)) { // verify if in master mode
i2c_send_start(I2C(RTC_DS1307_I2C)); // send start condition to start transaction
while (!(I2C_SR1(I2C(RTC_DS1307_I2C)) & I2C_SR1_SB)); // wait until start condition is transmitted
if (!(I2C_SR2(I2C(RTC_DS1307_I2C)) & I2C_SR2_MSL)) { // verify if in master mode
goto error;
}
i2c_send_7bit_address(RTC_DS1307_I2C, RTC_DS1307_I2C_ADDR, I2C_WRITE); // select slave
while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_ADDR)); // wait until address is transmitted
if (!((I2C_SR2(RTC_DS1307_I2C) & I2C_SR2_TRA))) { // verify we are in transmit mode (and read SR2 to clear ADDR)
i2c_send_7bit_address(I2C(RTC_DS1307_I2C), RTC_DS1307_I2C_ADDR, I2C_WRITE); // select slave
while (!(I2C_SR1(I2C(RTC_DS1307_I2C)) & I2C_SR1_ADDR)); // wait until address is transmitted
if (!((I2C_SR2(I2C(RTC_DS1307_I2C)) & I2C_SR2_TRA))) { // verify we are in transmit mode (and read SR2 to clear ADDR)
goto error;
}
i2c_send_data(RTC_DS1307_I2C, addr); // send memory address we want to read
while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_TxE)); // wait until byte has been transmitted
i2c_send_data(I2C(RTC_DS1307_I2C), addr); // send memory address we want to read
while (!(I2C_SR1(I2C(RTC_DS1307_I2C)) & I2C_SR1_TxE)); // wait until byte has been transmitted
for (size_t i=0; i<len; i++) { // write bytes
i2c_send_data(RTC_DS1307_I2C, data[i]); // send byte to be written in memory
while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_TxE)); // wait until byte has been transmitted
i2c_send_data(I2C(RTC_DS1307_I2C), data[i]); // send byte to be written in memory
while (!(I2C_SR1(I2C(RTC_DS1307_I2C)) & I2C_SR1_TxE)); // wait until byte has been transmitted
}
to_return = true;
error:
if (I2C_SR2(RTC_DS1307_I2C) & I2C_SR2_BUSY) { // release bus if busy
i2c_send_stop(RTC_DS1307_I2C); // send stop to release bus
if (I2C_SR2(I2C(RTC_DS1307_I2C)) & I2C_SR2_BUSY) { // release bus if busy
i2c_send_stop(I2C(RTC_DS1307_I2C)); // send stop to release bus
}
while (I2C_SR2(RTC_DS1307_I2C) & I2C_SR2_MSL); // wait until bus released (non master mode)
while (I2C_SR2(I2C(RTC_DS1307_I2C)) & I2C_SR2_MSL); // wait until bus released (non master mode)
return to_return;
}

View File

@ -21,37 +21,6 @@
*/
#pragma once
/** @defgroup rtc_ds1307_i2c I2C peripheral used to communication with the DS1307 RTC IC
* @{
*/
/** I2C peripheral */
#define RTC_DS1307_I2C I2C1 /**< I2C peripheral */
#define RTC_DS1307_I2C_RCC RCC_I2C1 /**< I2C peripheral clock */
#define RTC_DS1307_I2C_PORT_RCC RCC_GPIOB /**< I2C I/O peripheral clock */
#define RTC_DS1307_I2C_PORT GPIOB /**< I2C I/O peripheral port */
#define RTC_DS1307_I2C_PIN_SDA GPIO_I2C1_SDA /**< I2C peripheral data pin (PB7) */
#define RTC_DS1307_I2C_PIN_SCL GPIO_I2C1_SCL /**< I2C peripheral clock pin (PB6) */
#define RTC_DS1307_I2C_ADDR 0x68 /**< DS1307 I2C address (fixed to 0b1101000) */
/** @} */
/** @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 RTC_DS1307_SQUARE_WAVE_TICKS (RTC_DS1307_SQUARE_WAVE_FREQUENCY/256) /**< number of square wave tics before setting rtc_ds1307_tic_flag */
#define RTC_DS1307_SQUARE_WAVE_FREQUENCY 4096 /**< square wave output frequency from the RTC IC */
#define RTC_DS1307_SQUARE_WAVE_TIMER TIM2 /**< timer peripheral */
#define RTC_DS1307_SQUARE_WAVE_TIMER_RCC RCC_TIM2 /**< timer peripheral clock */
#define RTC_DS1307_SQUARE_WAVE_TIMER_IC TIM_IC1 /**< input capture channel (for TIM2_CH1) */
#define RTC_DS1307_SQUARE_WAVE_TIMER_IN TIM_IC_IN_TI1 /**< input capture input source (TIM2_CH1 becomes TI1, then TI1F, then TI1FP1) */
#define RTC_DS1307_SQUARE_WAVE_TIMER_TS TIM_SMCR_TS_IT1FP1 /**< input capture trigger (actually TI1FP1) */
#define RTC_DS1307_SQUARE_WAVE_TIMER_IRQ NVIC_TIM2_IRQ /**< timer interrupt */
#define RTC_DS1307_SQUARE_WAVE_TIMER_ISR tim2_isr /**< timer interrupt service routine */
#define RTC_DS1307_SQUARE_WAVE_GPIO_RCC RCC_GPIOA /**< timer port peripheral clock (TIM2_CH1 on PA0)*/
#define RTC_DS1307_SQUARE_WAVE_GPIO_PORT GPIOA /**< timer port (TIM2_CH1 on PA0) */
#define RTC_DS1307_SQUARE_WAVE_GPIO_PIN GPIO_TIM2_CH1_ETR /**< timer pin input, connect to RTC IC square wave output (TIM2_CH1 on PA0) */
/** @} */
#if defined(RTC_DS1307_SQUARE_WAVE_TICKS)
extern volatile uint32_t rtc_ds1307_ticks; /**< increment on SQUARE_WAVE_TICS square wave ticks */
extern volatile bool rtc_ds1307_tick_flag; /**< set on SQUARE_WAVE_TICS square wave ticks */