diff --git a/CMakeLists.txt b/CMakeLists.txt index ddc5b6f..06671f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ pico_sdk_init() add_executable(zavlaha src/main.c src/lcd.c + src/ds_rtc.c ) # Add pico_stdlib library which aggregates commonly used features diff --git a/src/ds_rtc.c b/src/ds_rtc.c new file mode 100644 index 0000000..9a7f56f --- /dev/null +++ b/src/ds_rtc.c @@ -0,0 +1,67 @@ +/** + * TODO file description + */ + +#include +#include +#include +#include + +#include "ds_rtc.h" +#include "pinout.h" + +#define I2C_ADDR_RTC 0b1101000 +#define TIMEOUT_US 10000 + +#define TRY(what) do { \ + rv = (what); \ + if (rv < 0) { return rv; } \ +} while (0) + + +static int rtc_read(uint8_t start, uint8_t *dest, size_t len) { + int rv; + TRY(i2c_write_timeout_us(i2c0, I2C_ADDR_RTC, &start, 1, true, TIMEOUT_US)); + TRY(i2c_read_timeout_us(i2c0, I2C_ADDR_RTC, dest, len, false, TIMEOUT_US)); + return 0; +} + +static int rtc_write(uint8_t start, const uint8_t *data, size_t len) { + int rv; + if (len > 19) return -1; + uint8_t scratch[20]; + scratch[0] = start; + memcpy(&scratch[1], data, len); + TRY(i2c_write_timeout_us(i2c0, I2C_ADDR_RTC, scratch, len + 1, true, TIMEOUT_US)); + return 0; +} + +int rtc_get_time(struct rtc_time *dest) { + int rv; + uint8_t buf[3]; + TRY(rtc_read(0x00, buf, 3)); + + dest->second = (buf[0] & 15) + (buf[0] >> 4) * 10; + dest->minute = (buf[1] & 15) + (buf[1] >> 4) * 10; + + if (buf[2] & 0x40) { + // 12h time? + dest->hour = (buf[2] & 15) + ((buf[2] & 0x20) != 0) * 12 + ((buf[2] & 0x10) != 0) * 10; + } else { + dest->hour = (buf[2] & 15) + ((buf[2] >> 4) & 3) * 10; + } + + return 0; +} + +int rtc_set_time(const struct rtc_time *time) { + int rv; + uint8_t buf[3]; + + buf[0] = (time->second % 10) + ((time->second / 10) << 4); + buf[1] = (time->minute % 10) + ((time->minute / 10) << 4); + buf[2] = (time->hour % 10) + ((time->hour / 10) << 4); + + TRY(rtc_write(0x00, buf, 3)); + return 0; +} diff --git a/src/ds_rtc.h b/src/ds_rtc.h new file mode 100644 index 0000000..18eb5b9 --- /dev/null +++ b/src/ds_rtc.h @@ -0,0 +1,18 @@ +/** + * TODO file description + */ + +#ifndef ZAVLAHA_DS_RTC_H +#define ZAVLAHA_DS_RTC_H + + +struct rtc_time { + uint8_t hour; + uint8_t minute; + uint8_t second; +}; + +int rtc_get_time(struct rtc_time *dest); +int rtc_set_time(const struct rtc_time *time); + +#endif //ZAVLAHA_DS_RTC_H diff --git a/src/main.c b/src/main.c index ecd06e2..1fced6c 100644 --- a/src/main.c +++ b/src/main.c @@ -6,6 +6,7 @@ #include #include "pinout.h" #include "lcd.h" +#include "ds_rtc.h" /* @@ -132,12 +133,24 @@ int main() lcd_init(); lcd_puts("HELLO WORLD!"); + uint cnt = 0; char buf[16]; while (1) { lcd_clear(); lcd_puts("HELLO WORLD!"); + // Try to read RTC + struct rtc_time time; + if (0 == rtc_get_time(&time)) { + sprintf(buf, "%02d:%02d:%02d", time.hour, time.minute, time.second); + lcd_xy(0, 2); + lcd_puts(buf); + } else { + lcd_xy(0, 2); + lcd_puts("RTC err!"); + } + gpio_put(PIN_LED, 1); // LED on uint16_t moisture = moisture_read(); diff --git a/src/pinout.h b/src/pinout.h index 6730df2..a970cd7 100644 --- a/src/pinout.h +++ b/src/pinout.h @@ -24,6 +24,5 @@ // must be shifted left before adding the RW bit! #define I2C_ADDR_EEPROM 0b1010000 -#define I2C_ADDR_RTC 0b1101000 #endif //ZAVLAHA_PINOUT_H