diff --git a/lib/rtc_ds1307.c b/lib/rtc_ds1307.c new file mode 100644 index 0000000..ce4c7c6 --- /dev/null +++ b/lib/rtc_ds1307.c @@ -0,0 +1,104 @@ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +/* Copyright (c) 2016 King Kévin */ +/* this library handles communication with the I2C RTC IC Maxim DS1307 */ +/* peripherals used: I2C (check source for details) */ + +/* standard libraries */ +#include // standard integer types +#include // standard I/O facilities +#include // general utilities + +/* STM32 (including CM3) libraries */ +#include // real-time control clock library +#include // general purpose input output library +#include // I2C library +#include // interrupt handler +#include // Cortex M3 utilities + +#include "rtc_ds1307.h" // RTC header and definitions + +/* which I2C to use */ +#define I2C I2C1 +#define I2C_RCC RCC_I2C1 +#define I2C_IRQ NVIC_I2C1_IRQ +#define I2C_PORT GPIOB +#define I2C_PIN_SDA GPIO_I2C1_SDA // on PB7 +#define I2C_PIN_SCL GPIO_I2C1_SCL // on PB6 +#define I2C_ADDR 0b1101000 // DS1307 fixed slave address + +/* setup communication with RTC IC */ +void rtc_setup(void) +{ + /* 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) */ + 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) + i2c_set_standard_mode(I2C); // the DS1307 has a maximum I2C SCL freq if 100 kHz (corresponding to the standard mode) + i2c_set_ccr(I2C, rcc_apb1_frequency/(100E3*2)); // set Thigh/Tlow to generate frequency of 100 kHz + 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 +} + +/* read memory from RTC IC + * read data into + * return if read succeeded */ +static bool rtc_read_memory(uint8_t* data, size_t len) +{ + bool to_return = false; // return if read succeeded + if (data==NULL || len==0) { // verify there it data to be read + goto error; + } + i2c_send_start(I2C); // send start condition to start transaction + while (!(I2C_SR1(I2C) & I2C_SR1_SB)); // wait until start bit is transmitted + if (!(I2C_SR2(I2C) & I2C_SR2_MSL)) { // verify if in master mode + goto error; + } + i2c_send_7bit_address(I2C, I2C_ADDR, I2C_READ); // transmit address + while (!(I2C_SR1(I2C) & I2C_SR1_ADDR)); // wait until address is transmitted + if (I2C_SR2(I2C) & I2C_SR2_TRA) { // verify we are in receive mode (and read SR2 to clear ADDR) + goto error; + } + for (size_t i=0; i. + * + */ +/* Copyright (c) 2016 King Kévin */ +/* this library handles communication with the I2C RTC IC Maxim DS1307 */ +/* peripherals used: I2C (check source for details) */ +#pragma once + +/* setup communication with RTC IC */ +void rtc_setup(void); +/* read seconds (0-59) from RTC IC */ +uint8_t rtc_read_seconds(void);