diff --git a/lib/rtc_ds1307.c b/lib/rtc_ds1307.c index 3672f65..fb27bbc 100644 --- a/lib/rtc_ds1307.c +++ b/lib/rtc_ds1307.c @@ -120,11 +120,18 @@ error: return to_return; } +bool rtc_oscillator_disabled(void) +{ + uint8_t data[1] = {0}; // to read data from I2C + rtc_read_memory(0, data, LENGTH(data)); // read a single byte containing CH value + return data[0]&0x80; // return CH bit value to indicate if oscillator is disabled +} + uint8_t rtc_read_seconds(void) { uint8_t to_return = 0; // seconds to return uint8_t data[1] = {0}; // to read data from I2C - rtc_read_memory(0, data, LENGTH(data)); // read a single byte to test + rtc_read_memory(0, data, LENGTH(data)); // read a single byte containing seconds value to_return = ((data[0]&0x70)>>4)*10+(data[0]&0x0f); // convert BCD coding into seconds return to_return; } @@ -133,7 +140,7 @@ uint8_t rtc_read_minutes(void) { uint8_t to_return = 0; // minutes to return uint8_t data[1] = {0}; // to read data from I2C - rtc_read_memory(1, data, LENGTH(data)); // read a single byte to test + rtc_read_memory(1, data, LENGTH(data)); // read a single byte containing minutes value to_return = (data[0]>>4)*10+(data[0]&0x0f); // convert BCD coding into minutes return to_return; } @@ -142,7 +149,7 @@ uint8_t rtc_read_hours(void) { uint8_t to_return = 0; // hours to return uint8_t data[1] = {0}; // to read data from I2C - rtc_read_memory(2, data, LENGTH(data)); // read a single byte to test + rtc_read_memory(2, data, LENGTH(data)); // read a single byte containing hours value if (data[0]&0x40) { // 12 hour mode if (data[0]&0x02) { // PM to_return += 12; // add the 12 hours @@ -159,7 +166,7 @@ uint8_t rtc_read_day(void) { uint8_t to_return = 0; // day to return uint8_t data[1] = {0}; // to read data from I2C - rtc_read_memory(3, data, LENGTH(data)); // read a single byte to test + rtc_read_memory(3, data, LENGTH(data)); // read a single byte containing day value to_return = (data[0]&0x07); // convert BCD coding into days return to_return; } @@ -168,7 +175,7 @@ uint8_t rtc_read_date(void) { uint8_t to_return = 0; // date to return uint8_t data[1] = {0}; // to read data from I2C - rtc_read_memory(4, data, LENGTH(data)); // read a single byte to test + rtc_read_memory(4, data, LENGTH(data)); // read a single byte containing date value to_return = ((data[0]&0x30)>>4)*10+(data[0]&0x0f); // convert BCD coding into date return to_return; } @@ -177,7 +184,7 @@ uint8_t rtc_read_month(void) { uint8_t to_return = 0; // month to return uint8_t data[1] = {0}; // to read data from I2C - rtc_read_memory(5, data, LENGTH(data)); // read a single byte to test + rtc_read_memory(5, data, LENGTH(data)); // read a single byte containing month value to_return = ((data[0]&0x10)>>4)*10+(data[0]&0x0f); // convert BCD coding into month return to_return; } @@ -186,7 +193,7 @@ uint16_t rtc_read_year(void) { uint16_t to_return = 2000; // year to return uint8_t data[1] = {0}; // to read data from I2C - rtc_read_memory(6, data, LENGTH(data)); // read a single byte to test + rtc_read_memory(6, data, LENGTH(data)); // read a single byte containing year value to_return += ((data[0]&0xf0)>>4)*10+(data[0]&0x0f); // convert BCD coding into year return to_return; } @@ -215,3 +222,64 @@ uint16_t* rtc_read_time(void) return time; } +/** @brief write memory into RTC IC + * @param[in] addr start address for memory to be written + * @param[in] data buffer to for memory to be written + * @param[in] len number of byte to write into the memory + * @return if write succeeded + */ +static bool rtc_write_memory(uint8_t addr, 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 condition is transmitted + if (!(I2C_SR2(I2C) & I2C_SR2_MSL)) { // verify if in master mode + goto error; + } + i2c_send_7bit_address(I2C, I2C_ADDR, I2C_WRITE); // select slave + while (!(I2C_SR1(I2C) & I2C_SR1_ADDR)); // wait until address is transmitted + if (!((I2C_SR2(I2C) & I2C_SR2_TRA))) { // verify we are in transmit mode (and read SR2 to clear ADDR) + goto error; + } + i2c_send_data(I2C, addr); // send memory address we want to read + while (!(I2C_SR1(I2C) & I2C_SR1_TxE)); // wait until byte has been transmitted + for (size_t i=0; i