implement rtc

master
Ondřej Hruška 1 year ago
parent 89c1857d57
commit 5927d24bc2
  1. 1
      CMakeLists.txt
  2. 67
      src/ds_rtc.c
  3. 18
      src/ds_rtc.h
  4. 13
      src/main.c
  5. 1
      src/pinout.h

@ -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

@ -0,0 +1,67 @@
/**
* TODO file description
*/
#include <pico/stdlib.h>
#include <stdint.h>
#include <hardware/i2c.h>
#include <string.h>
#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;
}

@ -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

@ -6,6 +6,7 @@
#include <hardware/irq.h>
#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();

@ -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

Loading…
Cancel
Save