From 80eddb24c761bc9b053a9c012ae1487f9ddd27dd Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Mon, 10 May 2021 06:23:34 +0100 Subject: [PATCH] Updated RV3028 driver to our coding style and included a standalone C example --- drivers/rv3028/CMakeLists.txt | 11 +- drivers/rv3028/rv3028.cmake | 12 +- drivers/rv3028/rv3028.cpp | 739 +++++++++++----------- drivers/rv3028/rv3028.hpp | 255 ++++---- examples/CMakeLists.txt | 1 + examples/breakout_rtc/CMakeLists.txt | 16 + examples/breakout_rtc/demo.cpp | 45 ++ examples/pico_rtc_display/CMakeLists.txt | 8 +- examples/pico_rtc_display/demo.cpp | 111 ++-- libraries/CMakeLists.txt | 1 + libraries/breakout_rtc/CMakeLists.txt | 1 + libraries/breakout_rtc/breakout_rtc.cmake | 11 + libraries/breakout_rtc/breakout_rtc.cpp | 5 + libraries/breakout_rtc/breakout_rtc.hpp | 8 + 14 files changed, 662 insertions(+), 562 deletions(-) create mode 100644 examples/breakout_rtc/CMakeLists.txt create mode 100644 examples/breakout_rtc/demo.cpp create mode 100644 libraries/breakout_rtc/CMakeLists.txt create mode 100644 libraries/breakout_rtc/breakout_rtc.cmake create mode 100644 libraries/breakout_rtc/breakout_rtc.cpp create mode 100644 libraries/breakout_rtc/breakout_rtc.hpp diff --git a/drivers/rv3028/CMakeLists.txt b/drivers/rv3028/CMakeLists.txt index 76f5a419..8184ce44 100644 --- a/drivers/rv3028/CMakeLists.txt +++ b/drivers/rv3028/CMakeLists.txt @@ -1,10 +1 @@ -add_library(rv3028 INTERFACE) - -target_sources(rv3028 INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/rv3028.cpp -) - -target_include_directories(rv3028 INTERFACE ${CMAKE_CURRENT_LIST_DIR}) - -# Pull in pico libraries that we need -target_link_libraries(rv3028 INTERFACE pico_stdlib hardware_i2c) +include(rv3028.cmake) diff --git a/drivers/rv3028/rv3028.cmake b/drivers/rv3028/rv3028.cmake index 586a9354..8a32686c 100644 --- a/drivers/rv3028/rv3028.cmake +++ b/drivers/rv3028/rv3028.cmake @@ -1,10 +1,10 @@ -add_library(rv3028 INTERFACE) +set(DRIVER_NAME rv3028) +add_library(${DRIVER_NAME} INTERFACE) -target_sources(rv3028 INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/rv3028.cpp -) +target_sources(${DRIVER_NAME} INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/${DRIVER_NAME}.cpp) -target_include_directories(rv3028 INTERFACE ${CMAKE_CURRENT_LIST_DIR}) +target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(rv3028 INTERFACE pico_stdlib hardware_i2c) +target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c) diff --git a/drivers/rv3028/rv3028.cpp b/drivers/rv3028/rv3028.cpp index 7ec7db49..3faaf7af 100644 --- a/drivers/rv3028/rv3028.cpp +++ b/drivers/rv3028/rv3028.cpp @@ -60,121 +60,129 @@ BUILD_MONTH_OCT | BUILD_MONTH_NOV | BUILD_MONTH_DEC namespace pimoroni { - void RV3028::init() { + bool RV3028::init() { i2c_init(i2c, 400000); - gpio_set_function(sda, GPIO_FUNC_I2C); gpio_pull_up(sda); - gpio_set_function(scl, GPIO_FUNC_I2C); gpio_pull_up(scl); + gpio_set_function(sda, GPIO_FUNC_I2C); + gpio_pull_up(sda); + gpio_set_function(scl, GPIO_FUNC_I2C); + gpio_pull_up(scl); + + if(interrupt != PIN_UNUSED) { + gpio_set_function(interrupt, GPIO_FUNC_SIO); + gpio_set_dir(interrupt, GPIO_IN); + gpio_pull_up(interrupt); + } + + return true; } - bool RV3028::setup(bool set_24Hour, bool disable_TrickleCharge, bool set_LevelSwitchingMode) - { + bool RV3028::setup(bool set_24Hour, bool disable_TrickleCharge, bool set_LevelSwitchingMode) { sleep_ms(1000); - if (set_24Hour) { set24Hour(); sleep_ms(1000); } - if (disable_TrickleCharge) { disableTrickleCharge(); sleep_ms(1000); } + if(set_24Hour) { + set_24_hour(); + sleep_ms(1000); + } - return((set_LevelSwitchingMode ? setBackupSwitchoverMode(3) : true) && writeRegister(RV3028_STATUS, 0x00)); + if(disable_TrickleCharge) { + disable_trickle_charge(); + sleep_ms(1000); + } + + return ((set_LevelSwitchingMode ? set_backup_switchover_mode(3) : true) && write_register(RV3028_STATUS, 0x00)); } - bool RV3028::setTime(uint8_t sec, uint8_t min, uint8_t hour, uint8_t weekday, uint8_t date, uint8_t month, uint16_t year) - { - _time[TIME_SECONDS] = DECtoBCD(sec); - _time[TIME_MINUTES] = DECtoBCD(min); - _time[TIME_HOURS] = DECtoBCD(hour); - _time[TIME_WEEKDAY] = DECtoBCD(weekday); - _time[TIME_DATE] = DECtoBCD(date); - _time[TIME_MONTH] = DECtoBCD(month); - _time[TIME_YEAR] = DECtoBCD(year - 2000); + bool RV3028::set_time(uint8_t sec, uint8_t min, uint8_t hour, uint8_t weekday, uint8_t date, uint8_t month, uint16_t year) { + times[TIME_SECONDS] = dec_to_bcd(sec); + times[TIME_MINUTES] = dec_to_bcd(min); + times[TIME_HOURS] = dec_to_bcd(hour); + times[TIME_WEEKDAY] = dec_to_bcd(weekday); + times[TIME_DATE] = dec_to_bcd(date); + times[TIME_MONTH] = dec_to_bcd(month); + times[TIME_YEAR] = dec_to_bcd(year - 2000); bool status = false; - if (is12Hour()) { - set24Hour(); - status = setTime(_time, TIME_ARRAY_LENGTH); - set12Hour(); - } else { - status = setTime(_time, TIME_ARRAY_LENGTH); + if(is_12_hour()) { + set_24_hour(); + status = set_time(times, TIME_ARRAY_LENGTH); + set_12_hour(); + } + else { + status = set_time(times, TIME_ARRAY_LENGTH); } return status; } // setTime -- Set time and date/day registers of RV3028 (using data array) - bool RV3028::setTime(uint8_t * time, uint8_t len) - { - if (len != TIME_ARRAY_LENGTH) + bool RV3028::set_time(uint8_t * time, uint8_t len) { + if(len != TIME_ARRAY_LENGTH) return false; - return writeMultipleRegisters(RV3028_SECONDS, time, len); + return write_multiple_registers(RV3028_SECONDS, time, len); } - bool RV3028::setSeconds(uint8_t value) - { - _time[TIME_SECONDS] = DECtoBCD(value); - return setTime(_time, TIME_ARRAY_LENGTH); + bool RV3028::set_seconds(uint8_t value) { + times[TIME_SECONDS] = dec_to_bcd(value); + return set_time(times, TIME_ARRAY_LENGTH); } - bool RV3028::setMinutes(uint8_t value) - { - _time[TIME_MINUTES] = DECtoBCD(value); - return setTime(_time, TIME_ARRAY_LENGTH); + bool RV3028::set_minutes(uint8_t value) { + times[TIME_MINUTES] = dec_to_bcd(value); + return set_time(times, TIME_ARRAY_LENGTH); } - bool RV3028::setHours(uint8_t value) - { - _time[TIME_HOURS] = DECtoBCD(value); - return setTime(_time, TIME_ARRAY_LENGTH); + bool RV3028::set_hours(uint8_t value) { + times[TIME_HOURS] = dec_to_bcd(value); + return set_time(times, TIME_ARRAY_LENGTH); } - bool RV3028::setWeekday(uint8_t value) - { - _time[TIME_WEEKDAY] = DECtoBCD(value); - return setTime(_time, TIME_ARRAY_LENGTH); + bool RV3028::set_weekday(uint8_t value) { + times[TIME_WEEKDAY] = dec_to_bcd(value); + return set_time(times, TIME_ARRAY_LENGTH); } - bool RV3028::setDate(uint8_t value) - { - _time[TIME_DATE] = DECtoBCD(value); - return setTime(_time, TIME_ARRAY_LENGTH); + bool RV3028::set_date(uint8_t value) { + times[TIME_DATE] = dec_to_bcd(value); + return set_time(times, TIME_ARRAY_LENGTH); } - bool RV3028::setMonth(uint8_t value) - { - _time[TIME_MONTH] = DECtoBCD(value); - return setTime(_time, TIME_ARRAY_LENGTH); + bool RV3028::set_month(uint8_t value) { + times[TIME_MONTH] = dec_to_bcd(value); + return set_time(times, TIME_ARRAY_LENGTH); } - bool RV3028::setYear(uint16_t value) - { - _time[TIME_YEAR] = DECtoBCD(value - 2000); - return setTime(_time, TIME_ARRAY_LENGTH); + bool RV3028::set_year(uint16_t value) { + times[TIME_YEAR] = dec_to_bcd(value - 2000); + return set_time(times, TIME_ARRAY_LENGTH); } //Takes the time from the last build and uses it as the current time //Works very well as an arduino sketch - bool RV3028::setToCompilerTime() - { - _time[TIME_SECONDS] = DECtoBCD(BUILD_SECOND); - _time[TIME_MINUTES] = DECtoBCD(BUILD_MINUTE); - _time[TIME_HOURS] = DECtoBCD(BUILD_HOUR); + bool RV3028::set_to_compiler_time() { + times[TIME_SECONDS] = dec_to_bcd(BUILD_SECOND); + times[TIME_MINUTES] = dec_to_bcd(BUILD_MINUTE); + times[TIME_HOURS] = dec_to_bcd(BUILD_HOUR); //Build_Hour is 0-23, convert to 1-12 if needed - if (is12Hour()) { + if(is_12_hour()) { uint8_t hour = BUILD_HOUR; bool pm = false; - if (hour == 0) + if(hour == 0) hour += 12; - else if (hour == 12) + else if(hour == 12) pm = true; - else if (hour > 12) { + else if(hour > 12) { hour -= 12; pm = true; } - _time[TIME_HOURS] = DECtoBCD(hour); //Load the modified hours + times[TIME_HOURS] = dec_to_bcd(hour); //Load the modified hours - if (pm == true) _time[TIME_HOURS] |= (1 << HOURS_AM_PM); //Set AM/PM bit if needed + if(pm == true) + times[TIME_HOURS] |= (1 << HOURS_AM_PM); //Set AM/PM bit if needed } // Calculate weekday (from here: http://stackoverflow.com/a/21235587) @@ -183,217 +191,194 @@ namespace pimoroni { uint16_t m = BUILD_MONTH; uint16_t y = BUILD_YEAR; uint16_t weekday = (d += m < 3 ? y-- : y - 2, 23 * m / 9 + d + 4 + y / 4 - y / 100 + y / 400) % 7 + 1; - _time[TIME_WEEKDAY] = DECtoBCD(weekday); + times[TIME_WEEKDAY] = dec_to_bcd(weekday); - _time[TIME_DATE] = DECtoBCD(BUILD_DATE); - _time[TIME_MONTH] = DECtoBCD(BUILD_MONTH); - _time[TIME_YEAR] = DECtoBCD(BUILD_YEAR - 2000); //! Not Y2K (or Y2.1K)-proof :( + times[TIME_DATE] = dec_to_bcd(BUILD_DATE); + times[TIME_MONTH] = dec_to_bcd(BUILD_MONTH); + times[TIME_YEAR] = dec_to_bcd(BUILD_YEAR - 2000); //! Not Y2K (or Y2.1K)-proof :( - return setTime(_time, TIME_ARRAY_LENGTH); + return set_time(times, TIME_ARRAY_LENGTH); } //Move the hours, mins, sec, etc registers from RV-3028-C7 into the _time array //Needs to be called before printing time or date //We do not protect the GPx registers. They will be overwritten. The user has plenty of RAM if they need it. - bool RV3028::updateTime() - { - if (readMultipleRegisters(RV3028_SECONDS, _time, TIME_ARRAY_LENGTH) == false) - return(false); //Something went wrong + bool RV3028::update_time() { + if(read_multiple_registers(RV3028_SECONDS, times, TIME_ARRAY_LENGTH) == false) + return false; //Something went wrong - if (is12Hour()) _time[TIME_HOURS] &= ~(1 << HOURS_AM_PM); //Remove this bit from value + if(is_12_hour()) + times[TIME_HOURS] &= ~(1 << HOURS_AM_PM); //Remove this bit from value return true; } //Returns a pointer to array of chars that are the date in mm/dd/yyyy format because they're weird - char* RV3028::stringDateUSA() - { + char* RV3028::string_date_usa() { static char date[11]; //Max of mm/dd/yyyy with \0 terminator - sprintf(date, "%02hhu/%02hhu/20%02hhu", BCDtoDEC(_time[TIME_MONTH]), BCDtoDEC(_time[TIME_DATE]), BCDtoDEC(_time[TIME_YEAR])); - return(date); + sprintf(date, "%02hhu/%02hhu/20%02hhu", bcd_to_dec(times[TIME_MONTH]), bcd_to_dec(times[TIME_DATE]), bcd_to_dec(times[TIME_YEAR])); + return date; } //Returns a pointer to array of chars that are the date in dd/mm/yyyy format - char* RV3028::stringDate() - { + char* RV3028::string_date() { static char date[11]; //Max of dd/mm/yyyy with \0 terminator - sprintf(date, "%02hhu/%02hhu/20%02hhu", BCDtoDEC(_time[TIME_DATE]), BCDtoDEC(_time[TIME_MONTH]), BCDtoDEC(_time[TIME_YEAR])); - return(date); + sprintf(date, "%02hhu/%02hhu/20%02hhu", bcd_to_dec(times[TIME_DATE]), bcd_to_dec(times[TIME_MONTH]), bcd_to_dec(times[TIME_YEAR])); + return date; } //Returns a pointer to array of chars that represents the time in hh:mm:ss format //Adds AM/PM if in 12 hour mode - char* RV3028::stringTime() - { + char* RV3028::string_time() { static char time[11]; //Max of hh:mm:ssXM with \0 terminator - if (is12Hour() == true) - { + if(is_12_hour() == true) { char half = 'A'; - if (isPM()) half = 'P'; + if(is_pm()) half = 'P'; - sprintf(time, "%02hhu:%02hhu:%02hhu%cM", BCDtoDEC(_time[TIME_HOURS]), BCDtoDEC(_time[TIME_MINUTES]), BCDtoDEC(_time[TIME_SECONDS]), half); + sprintf(time, "%02hhu:%02hhu:%02hhu%cM", bcd_to_dec(times[TIME_HOURS]), bcd_to_dec(times[TIME_MINUTES]), bcd_to_dec(times[TIME_SECONDS]), half); } else - sprintf(time, "%02hhu:%02hhu:%02hhu", BCDtoDEC(_time[TIME_HOURS]), BCDtoDEC(_time[TIME_MINUTES]), BCDtoDEC(_time[TIME_SECONDS])); + sprintf(time, "%02hhu:%02hhu:%02hhu", bcd_to_dec(times[TIME_HOURS]), bcd_to_dec(times[TIME_MINUTES]), bcd_to_dec(times[TIME_SECONDS])); - return(time); + return time; } - char* RV3028::stringTimeStamp() - { + char* RV3028::string_time_stamp() { static char timeStamp[25]; //Max of yyyy-mm-ddThh:mm:ss.ss with \0 terminator - if (is12Hour() == true) - { + if(is_12_hour() == true) { char half = 'A'; - if (isPM()) half = 'P'; + if(is_pm()) half = 'P'; - sprintf(timeStamp, "20%02hhu-%02hhu-%02hhu %02hhu:%02hhu:%02hhu%cM", BCDtoDEC(_time[TIME_YEAR]), BCDtoDEC(_time[TIME_MONTH]), BCDtoDEC(_time[TIME_DATE]), BCDtoDEC(_time[TIME_HOURS]), BCDtoDEC(_time[TIME_MINUTES]), BCDtoDEC(_time[TIME_SECONDS]), half); + sprintf(timeStamp, "20%02hhu-%02hhu-%02hhu %02hhu:%02hhu:%02hhu%cM", bcd_to_dec(times[TIME_YEAR]), bcd_to_dec(times[TIME_MONTH]), bcd_to_dec(times[TIME_DATE]), bcd_to_dec(times[TIME_HOURS]), bcd_to_dec(times[TIME_MINUTES]), bcd_to_dec(times[TIME_SECONDS]), half); } else - sprintf(timeStamp, "20%02hhu-%02hhu-%02hhu %02hhu:%02hhu:%02hhu", BCDtoDEC(_time[TIME_YEAR]), BCDtoDEC(_time[TIME_MONTH]), BCDtoDEC(_time[TIME_DATE]), BCDtoDEC(_time[TIME_HOURS]), BCDtoDEC(_time[TIME_MINUTES]), BCDtoDEC(_time[TIME_SECONDS])); + sprintf(timeStamp, "20%02hhu-%02hhu-%02hhu %02hhu:%02hhu:%02hhu", bcd_to_dec(times[TIME_YEAR]), bcd_to_dec(times[TIME_MONTH]), bcd_to_dec(times[TIME_DATE]), bcd_to_dec(times[TIME_HOURS]), bcd_to_dec(times[TIME_MINUTES]), bcd_to_dec(times[TIME_SECONDS])); - return(timeStamp); + return timeStamp; } - uint8_t RV3028::getSeconds() - { - return BCDtoDEC(_time[TIME_SECONDS]); + uint8_t RV3028::get_seconds() { + return bcd_to_dec(times[TIME_SECONDS]); } - uint8_t RV3028::getMinutes() - { - return BCDtoDEC(_time[TIME_MINUTES]); + uint8_t RV3028::get_minutes() { + return bcd_to_dec(times[TIME_MINUTES]); } - uint8_t RV3028::getHours() - { - return BCDtoDEC(_time[TIME_HOURS]); + uint8_t RV3028::get_hours() { + return bcd_to_dec(times[TIME_HOURS]); } - uint8_t RV3028::getWeekday() - { - return BCDtoDEC(_time[TIME_WEEKDAY]); + uint8_t RV3028::get_weekday() { + return bcd_to_dec(times[TIME_WEEKDAY]); } - uint8_t RV3028::getDate() - { - return BCDtoDEC(_time[TIME_DATE]); + uint8_t RV3028::get_date() { + return bcd_to_dec(times[TIME_DATE]); } - uint8_t RV3028::getMonth() - { - return BCDtoDEC(_time[TIME_MONTH]); + uint8_t RV3028::get_month() { + return bcd_to_dec(times[TIME_MONTH]); } - uint16_t RV3028::getYear() - { - return BCDtoDEC(_time[TIME_YEAR]) + 2000; + uint16_t RV3028::get_year() { + return bcd_to_dec(times[TIME_YEAR]) + 2000; } //Returns true if RTC has been configured for 12 hour mode - bool RV3028::is12Hour() - { - uint8_t controlRegister2 = readRegister(RV3028_CTRL2); - return(controlRegister2 & (1 << CTRL2_12_24)); + bool RV3028::is_12_hour() { + uint8_t controlRegister2 = read_register(RV3028_CTRL2); + return (controlRegister2 & (1 << CTRL2_12_24)); } //Returns true if RTC has PM bit set and 12Hour bit set - bool RV3028::isPM() - { - uint8_t hourRegister = readRegister(RV3028_HOURS); - if (is12Hour() && (hourRegister & (1 << HOURS_AM_PM))) - return(true); - return(false); + bool RV3028::is_pm() { + uint8_t hourRegister = read_register(RV3028_HOURS); + if(is_12_hour() && (hourRegister & (1 << HOURS_AM_PM))) + return true; + return false; } //Configure RTC to output 1-12 hours //Converts any current hour setting to 12 hour - void RV3028::set12Hour() - { + void RV3028::set_12_hour() { //Do we need to change anything? - if (is12Hour() == false) - { - uint8_t hour = BCDtoDEC(readRegister(RV3028_HOURS)); //Get the current hour in the RTC + if(is_12_hour() == false) { + uint8_t hour = bcd_to_dec(read_register(RV3028_HOURS)); //Get the current hour in the RTC - //Set the 12/24 hour bit - uint8_t setting = readRegister(RV3028_CTRL2); + //Set the 12/24 hour bit + uint8_t setting = read_register(RV3028_CTRL2); setting |= (1 << CTRL2_12_24); - writeRegister(RV3028_CTRL2, setting); + write_register(RV3028_CTRL2, setting); //Take the current hours and convert to 12, complete with AM/PM bit bool pm = false; - if (hour == 0) + if(hour == 0) hour += 12; - else if (hour == 12) + else if(hour == 12) pm = true; - else if (hour > 12) - { + else if(hour > 12) { hour -= 12; pm = true; } - hour = DECtoBCD(hour); //Convert to BCD + hour = dec_to_bcd(hour); //Convert to BCD - if (pm == true) hour |= (1 << HOURS_AM_PM); //Set AM/PM bit if needed + if(pm == true) hour |= (1 << HOURS_AM_PM); //Set AM/PM bit if needed - writeRegister(RV3028_HOURS, hour); //Record this to hours register + write_register(RV3028_HOURS, hour); //Record this to hours register } } //Configure RTC to output 0-23 hours //Converts any current hour setting to 24 hour - void RV3028::set24Hour() - { + void RV3028::set_24_hour() { //Do we need to change anything? - if (is12Hour() == true) - { + if(is_12_hour() == true) { //Not sure what changing the CTRL2 register will do to hour register so let's get a copy - uint8_t hour = readRegister(RV3028_HOURS); //Get the current 12 hour formatted time in BCD + uint8_t hour = read_register(RV3028_HOURS); //Get the current 12 hour formatted time in BCD bool pm = false; - if (hour & (1 << HOURS_AM_PM)) //Is the AM/PM bit set? - { + if(hour & (1 << HOURS_AM_PM)) { //Is the AM/PM bit set? pm = true; hour &= ~(1 << HOURS_AM_PM); //Clear the bit } //Change to 24 hour mode - uint8_t setting = readRegister(RV3028_CTRL2); + uint8_t setting = read_register(RV3028_CTRL2); setting &= ~(1 << CTRL2_12_24); //Clear the 12/24 hr bit - writeRegister(RV3028_CTRL2, setting); + write_register(RV3028_CTRL2, setting); //Given a BCD hour in the 1-12 range, make it 24 - hour = BCDtoDEC(hour); //Convert core of register to DEC + hour = bcd_to_dec(hour); //Convert core of register to DEC - if (pm == true) hour += 12; //2PM becomes 14 - if (hour == 12) hour = 0; //12AM stays 12, but should really be 0 - if (hour == 24) hour = 12; //12PM becomes 24, but should really be 12 + if(pm == true) hour += 12; //2PM becomes 14 + if(hour == 12) hour = 0; //12AM stays 12, but should really be 0 + if(hour == 24) hour = 12; //12PM becomes 24, but should really be 12 - hour = DECtoBCD(hour); //Convert to BCD + hour = dec_to_bcd(hour); //Convert to BCD - writeRegister(RV3028_HOURS, hour); //Record this to hours register + write_register(RV3028_HOURS, hour); //Record this to hours register } } //ATTENTION: Real Time and UNIX Time are INDEPENDENT! - bool RV3028::setUNIX(uint32_t value) - { + bool RV3028::set_unix(uint32_t value) { uint8_t unix_reg[4]; unix_reg[0] = value; unix_reg[1] = value >> 8; unix_reg[2] = value >> 16; unix_reg[3] = value >> 24; - return writeMultipleRegisters(RV3028_UNIX_TIME0, unix_reg, 4); + return write_multiple_registers(RV3028_UNIX_TIME0, unix_reg, 4); } //ATTENTION: Real Time and UNIX Time are INDEPENDENT! - uint32_t RV3028::getUNIX() - { + uint32_t RV3028::get_unix() { uint8_t unix_reg[4]; - readMultipleRegisters(RV3028_UNIX_TIME0, unix_reg, 4); + read_multiple_registers(RV3028_UNIX_TIME0, unix_reg, 4); return ((uint32_t)unix_reg[3] << 24) | ((uint32_t)unix_reg[2] << 16) | ((uint32_t)unix_reg[1] << 8) | unix_reg[0]; } @@ -409,82 +394,78 @@ namespace pimoroni { 7: All disabled � Default value If you want to set a weekday alarm (setWeekdayAlarm_not_Date = true), set 'date_or_weekday' from 0 (Sunday) to 6 (Saturday) ********************************/ - void RV3028::enableAlarmInterrupt(uint8_t min, uint8_t hour, uint8_t date_or_weekday, bool setWeekdayAlarm_not_Date, uint8_t mode, bool enable_clock_output) - { + void RV3028::enable_alarm_interrupt(uint8_t min, uint8_t hour, uint8_t date_or_weekday, bool setWeekdayAlarm_not_Date, uint8_t mode, bool enable_clock_output) { //disable Alarm Interrupt to prevent accidental interrupts during configuration - disableAlarmInterrupt(); - clearAlarmInterruptFlag(); + disable_alarm_interrupt(); + clear_alarm_interrupt_flag(); //ENHANCEMENT: Add Alarm in 12 hour mode - set24Hour(); + set_24_hour(); //Set WADA bit (Weekday/Date Alarm) - if (setWeekdayAlarm_not_Date) - clearBit(RV3028_CTRL1, CTRL1_WADA); + if(setWeekdayAlarm_not_Date) + clear_bit(RV3028_CTRL1, CTRL1_WADA); else - setBit(RV3028_CTRL1, CTRL1_WADA); + set_bit(RV3028_CTRL1, CTRL1_WADA); //Write alarm settings in registers 0x07 to 0x09 uint8_t alarmTime[3]; - alarmTime[0] = DECtoBCD(min); //minutes - alarmTime[1] = DECtoBCD(hour); //hours - alarmTime[2] = DECtoBCD(date_or_weekday); //date or weekday + alarmTime[0] = dec_to_bcd(min); //minutes + alarmTime[1] = dec_to_bcd(hour); //hours + alarmTime[2] = dec_to_bcd(date_or_weekday); //date or weekday //shift alarm enable bits - if (mode > 0b111) mode = 0b111; //0 to 7 is valid - if (mode & 0b001) + if(mode > 0b111) + mode = 0b111; //0 to 7 is valid + + if(mode & 0b001) alarmTime[0] |= 1 << MINUTESALM_AE_M; - if (mode & 0b010) + if(mode & 0b010) alarmTime[1] |= 1 << HOURSALM_AE_H; - if (mode & 0b100) + if(mode & 0b100) alarmTime[2] |= 1 << DATE_AE_WD; //Write registers - writeMultipleRegisters(RV3028_MINUTES_ALM, alarmTime, 3); + write_multiple_registers(RV3028_MINUTES_ALM, alarmTime, 3); //enable Alarm Interrupt - enableAlarmInterrupt(); + enable_alarm_interrupt(); //Clock output? - if (enable_clock_output) - setBit(RV3028_INT_MASK, IMT_MASK_CAIE); + if(enable_clock_output) + set_bit(RV3028_INT_MASK, IMT_MASK_CAIE); else - clearBit(RV3028_INT_MASK, IMT_MASK_CAIE); + clear_bit(RV3028_INT_MASK, IMT_MASK_CAIE); } - void RV3028::enableAlarmInterrupt() - { - setBit(RV3028_CTRL2, CTRL2_AIE); + void RV3028::enable_alarm_interrupt() { + set_bit(RV3028_CTRL2, CTRL2_AIE); } //Only disables the interrupt (not the alarm flag) - void RV3028::disableAlarmInterrupt() - { - clearBit(RV3028_CTRL2, CTRL2_AIE); + void RV3028::disable_alarm_interrupt() { + clear_bit(RV3028_CTRL2, CTRL2_AIE); } - bool RV3028::readAlarmInterruptFlag() - { - return readBit(RV3028_STATUS, STATUS_AF); + bool RV3028::read_alarm_interrupt_flag() { + return read_bit(RV3028_STATUS, STATUS_AF); } - void RV3028::clearAlarmInterruptFlag() - { - clearBit(RV3028_STATUS, STATUS_AF); + void RV3028::clear_alarm_interrupt_flag() { + clear_bit(RV3028_STATUS, STATUS_AF); } /********************************* Countdown Timer Interrupt ********************************/ - void RV3028::setTimer(bool timer_repeat, uint16_t timer_frequency, uint16_t timer_value, bool set_interrupt, bool start_timer, bool enable_clock_output) - { - disableTimer(); - disableTimerInterrupt(); - clearTimerInterruptFlag(); + void RV3028::set_timer(bool timer_repeat, uint16_t timer_frequency, uint16_t timer_value, bool set_interrupt, bool start_timer, bool enable_clock_output) { + disable_timer(); + disable_timer_interrupt(); + clear_timer_interrupt_flag(); - writeRegister(RV3028_TIMERVAL_0, timer_value & 0xff); - writeRegister(RV3028_TIMERVAL_1, timer_value >> 8); + write_register(RV3028_TIMERVAL_0, timer_value & 0xff); + write_register(RV3028_TIMERVAL_1, timer_value >> 8); - uint8_t ctrl1_val = readRegister(RV3028_CTRL1); - if (timer_repeat) { + uint8_t ctrl1_val = read_register(RV3028_CTRL1); + if(timer_repeat) { ctrl1_val |= 1 << CTRL1_TRPT; } else { ctrl1_val &= ~(1 << CTRL1_TRPT); @@ -509,97 +490,84 @@ namespace pimoroni { break; } - if (set_interrupt) { - enableTimerInterrupt(); + if(set_interrupt) { + enable_timer_interrupt(); } - if (start_timer) { + if(start_timer) { ctrl1_val |= (1 << CTRL1_TE); } - writeRegister(RV3028_CTRL1, ctrl1_val); + write_register(RV3028_CTRL1, ctrl1_val); //Clock output? - if (enable_clock_output) - setBit(RV3028_INT_MASK, IMT_MASK_CTIE); + if(enable_clock_output) + set_bit(RV3028_INT_MASK, IMT_MASK_CTIE); else - clearBit(RV3028_INT_MASK, IMT_MASK_CTIE); + clear_bit(RV3028_INT_MASK, IMT_MASK_CTIE); } - uint16_t RV3028::getTimerCount(void) - { + uint16_t RV3028::get_timer_count(void) { // Reads the number of remaining timer ticks - uint8_t r0 =readRegister(RV3028_TIMERSTAT_0); - return(r0 + (readRegister(RV3028_TIMERSTAT_1) << 8)); + uint8_t r0 = read_register(RV3028_TIMERSTAT_0); + return(r0 + (read_register(RV3028_TIMERSTAT_1) << 8)); } - void RV3028::enableTimerInterrupt() - { - setBit(RV3028_CTRL2, CTRL2_TIE); + void RV3028::enable_timer_interrupt() { + set_bit(RV3028_CTRL2, CTRL2_TIE); } - void RV3028::disableTimerInterrupt() - { - clearBit(RV3028_CTRL2, CTRL2_TIE); + void RV3028::disable_timer_interrupt() { + clear_bit(RV3028_CTRL2, CTRL2_TIE); } - bool RV3028::readTimerInterruptFlag() - { - return readBit(RV3028_STATUS, STATUS_TF); + bool RV3028::read_timer_interrupt_flag() { + return read_bit(RV3028_STATUS, STATUS_TF); } - void RV3028::clearTimerInterruptFlag() - { - clearBit(RV3028_STATUS, STATUS_TF); + void RV3028::clear_timer_interrupt_flag() { + clear_bit(RV3028_STATUS, STATUS_TF); } - void RV3028::enableTimer() - { - setBit(RV3028_CTRL1, CTRL1_TE); + void RV3028::enable_timer() { + set_bit(RV3028_CTRL1, CTRL1_TE); } - void RV3028::disableTimer() - { - clearBit(RV3028_CTRL1, CTRL1_TE); + void RV3028::disable_timer() { + clear_bit(RV3028_CTRL1, CTRL1_TE); } /********************************* Periodic Time Update Interrupt ********************************/ - void RV3028::enablePeriodicUpdateInterrupt(bool every_second, bool enable_clock_output) - { - disablePeriodicUpdateInterrupt(); - clearPeriodicUpdateInterruptFlag(); + void RV3028::enable_periodic_update_interrupt(bool every_second, bool enable_clock_output) { + disable_periodic_update_interrupt(); + clear_periodic_update_interrupt_flag(); - if (every_second) - { - clearBit(RV3028_CTRL1, CTRL1_USEL); + if(every_second) { + clear_bit(RV3028_CTRL1, CTRL1_USEL); } - else - { // every minute - setBit(RV3028_CTRL1, CTRL1_USEL); + else { // every minute + set_bit(RV3028_CTRL1, CTRL1_USEL); } - setBit(RV3028_CTRL2, CTRL2_UIE); + set_bit(RV3028_CTRL2, CTRL2_UIE); //Clock output? - if (enable_clock_output) - setBit(RV3028_INT_MASK, IMT_MASK_CUIE); + if(enable_clock_output) + set_bit(RV3028_INT_MASK, IMT_MASK_CUIE); else - clearBit(RV3028_INT_MASK, IMT_MASK_CUIE); + clear_bit(RV3028_INT_MASK, IMT_MASK_CUIE); } - void RV3028::disablePeriodicUpdateInterrupt() - { - clearBit(RV3028_CTRL2, CTRL2_UIE); + void RV3028::disable_periodic_update_interrupt() { + clear_bit(RV3028_CTRL2, CTRL2_UIE); } - bool RV3028::readPeriodicUpdateInterruptFlag() - { - return readBit(RV3028_STATUS, STATUS_UF); + bool RV3028::read_periodic_update_interrupt_flag() { + return read_bit(RV3028_STATUS, STATUS_UF); } - void RV3028::clearPeriodicUpdateInterruptFlag() - { - clearBit(RV3028_STATUS, STATUS_UF); + void RV3028::clear_periodic_update_interrupt_flag() { + clear_bit(RV3028_STATUS, STATUS_UF); } /********************************* @@ -609,29 +577,28 @@ namespace pimoroni { TCR_9K = 9kOhm TCR_15K = 15kOhm *********************************/ - void RV3028::enableTrickleCharge(uint8_t tcr) - { - if (tcr > 3) return; + void RV3028::enable_trickle_charge(uint8_t tcr) { + if(tcr > 3) + return; //Read EEPROM Backup Register (0x37) - uint8_t EEPROMBackup = readConfigEEPROM_RAMmirror(EEPROM_Backup_Register); + uint8_t eeprom_backup = read_config_eeprom_ram_mirror(EEPROM_Backup_Register); //Set TCR Bits (Trickle Charge Resistor) - EEPROMBackup &= EEPROMBackup_TCR_CLEAR; //Clear TCR Bits - EEPROMBackup |= tcr << EEPROMBackup_TCR_SHIFT; //Shift values into EEPROM Backup Register + eeprom_backup &= EEPROMBackup_TCR_CLEAR; //Clear TCR Bits + eeprom_backup |= tcr << EEPROMBackup_TCR_SHIFT; //Shift values into EEPROM Backup Register //Write 1 to TCE Bit - EEPROMBackup |= 1 << EEPROMBackup_TCE_BIT; + eeprom_backup |= 1 << EEPROMBackup_TCE_BIT; //Write EEPROM Backup Register - writeConfigEEPROM_RAMmirror(EEPROM_Backup_Register, EEPROMBackup); + write_config_eeprom_ram_mirror(EEPROM_Backup_Register, eeprom_backup); } - void RV3028::disableTrickleCharge() - { + void RV3028::disable_trickle_charge() { //Read EEPROM Backup Register (0x37) - uint8_t EEPROMBackup = readConfigEEPROM_RAMmirror(EEPROM_Backup_Register); + uint8_t eeprom_backup = read_config_eeprom_ram_mirror(EEPROM_Backup_Register); //Write 0 to TCE Bit - EEPROMBackup &= ~(1 << EEPROMBackup_TCE_BIT); + eeprom_backup &= ~(1 << EEPROMBackup_TCE_BIT); //Write EEPROM Backup Register - writeConfigEEPROM_RAMmirror(EEPROM_Backup_Register, EEPROMBackup); + write_config_eeprom_ram_mirror(EEPROM_Backup_Register, eeprom_backup); } @@ -641,21 +608,27 @@ namespace pimoroni { 2 = Standby Mode 3 = Level Switching Mode *********************************/ - bool RV3028::setBackupSwitchoverMode(uint8_t val) - { - if (val > 3)return false; + bool RV3028::set_backup_switchover_mode(uint8_t val) { + if(val > 3) + return false; + bool success = true; //Read EEPROM Backup Register (0x37) - uint8_t EEPROMBackup = readConfigEEPROM_RAMmirror(EEPROM_Backup_Register); - if (EEPROMBackup == 0xFF) success = false; + uint8_t eeprom_backup = read_config_eeprom_ram_mirror(EEPROM_Backup_Register); + if(eeprom_backup == 0xFF) + success = false; + //Ensure FEDE Bit is set to 1 - EEPROMBackup |= 1 << EEPROMBackup_FEDE_BIT; + eeprom_backup |= 1 << EEPROMBackup_FEDE_BIT; + //Set BSM Bits (Backup Switchover Mode) - EEPROMBackup &= EEPROMBackup_BSM_CLEAR; //Clear BSM Bits of EEPROM Backup Register - EEPROMBackup |= val << EEPROMBackup_BSM_SHIFT; //Shift values into EEPROM Backup Register + eeprom_backup &= EEPROMBackup_BSM_CLEAR; //Clear BSM Bits of EEPROM Backup Register + eeprom_backup |= val << EEPROMBackup_BSM_SHIFT; //Shift values into EEPROM Backup Register + //Write EEPROM Backup Register - if (!writeConfigEEPROM_RAMmirror(EEPROM_Backup_Register, EEPROMBackup)) success = false; + if(!write_config_eeprom_ram_mirror(EEPROM_Backup_Register, eeprom_backup)) + success = false; return success; } @@ -664,66 +637,63 @@ namespace pimoroni { /********************************* Clock Out functions ********************************/ - void RV3028::enableClockOut(uint8_t freq) - { - if (freq > 7) return; // check out of bounds + void RV3028::enable_clock_out(uint8_t freq) { + if(freq > 7) + return; // check out of bounds + //Read EEPROM CLKOUT Register (0x35) - uint8_t EEPROMClkout = readConfigEEPROM_RAMmirror(EEPROM_Clkout_Register); + uint8_t eeprom_clkout = read_config_eeprom_ram_mirror(EEPROM_Clkout_Register); //Ensure CLKOE Bit is set to 1 - EEPROMClkout |= 1 << EEPROMClkout_CLKOE_BIT; + eeprom_clkout |= 1 << EEPROMClkout_CLKOE_BIT; //Shift values into EEPROM Backup Register - EEPROMClkout |= freq << EEPROMClkout_FREQ_SHIFT; + eeprom_clkout |= freq << EEPROMClkout_FREQ_SHIFT; //Write EEPROM Backup Register - writeConfigEEPROM_RAMmirror(EEPROM_Clkout_Register, EEPROMClkout); + write_config_eeprom_ram_mirror(EEPROM_Clkout_Register, eeprom_clkout); } - void RV3028::enableInterruptControlledClockout(uint8_t freq) - { - if (freq > 7) return; // check out of bounds + void RV3028::enable_interrupt_controlled_clockout(uint8_t freq) { + if(freq > 7) + return; // check out of bounds + //Read EEPROM CLKOUT Register (0x35) - uint8_t EEPROMClkout = readConfigEEPROM_RAMmirror(EEPROM_Clkout_Register); + uint8_t eeprom_clkout = read_config_eeprom_ram_mirror(EEPROM_Clkout_Register); //Shift values into EEPROM Backup Register - EEPROMClkout |= freq << EEPROMClkout_FREQ_SHIFT; + eeprom_clkout |= freq << EEPROMClkout_FREQ_SHIFT; //Write EEPROM Backup Register - writeConfigEEPROM_RAMmirror(EEPROM_Clkout_Register, EEPROMClkout); + write_config_eeprom_ram_mirror(EEPROM_Clkout_Register, eeprom_clkout); //Set CLKIE Bit - setBit(RV3028_CTRL2, CTRL2_CLKIE); + set_bit(RV3028_CTRL2, CTRL2_CLKIE); } - void RV3028::disableClockOut() - { + void RV3028::disable_clock_out() { //Read EEPROM CLKOUT Register (0x35) - uint8_t EEPROMClkout = readConfigEEPROM_RAMmirror(EEPROM_Clkout_Register); + uint8_t eeprom_clkout = read_config_eeprom_ram_mirror(EEPROM_Clkout_Register); //Clear CLKOE Bit - EEPROMClkout &= ~(1 << EEPROMClkout_CLKOE_BIT); + eeprom_clkout &= ~(1 << EEPROMClkout_CLKOE_BIT); //Write EEPROM CLKOUT Register - writeConfigEEPROM_RAMmirror(EEPROM_Clkout_Register, EEPROMClkout); + write_config_eeprom_ram_mirror(EEPROM_Clkout_Register, eeprom_clkout); //Clear CLKIE Bit - clearBit(RV3028_CTRL2, CTRL2_CLKIE); + clear_bit(RV3028_CTRL2, CTRL2_CLKIE); } - bool RV3028::readClockOutputInterruptFlag() - { - return readBit(RV3028_STATUS, STATUS_CLKF); + bool RV3028::read_clock_output_interrupt_flag() { + return read_bit(RV3028_STATUS, STATUS_CLKF); } - void RV3028::clearClockOutputInterruptFlag() - { - clearBit(RV3028_STATUS, STATUS_CLKF); + void RV3028::clear_clock_output_interrupt_flag() { + clear_bit(RV3028_STATUS, STATUS_CLKF); } //Returns the status byte - uint8_t RV3028::status(void) - { - return(readRegister(RV3028_STATUS)); + uint8_t RV3028::status(void) { + return(read_register(RV3028_STATUS)); } - void RV3028::clearInterrupts() //Read the status register to clear the current interrupt flags - { - writeRegister(RV3028_STATUS, 0); + void RV3028::clear_interrupts() { //Read the status register to clear the current interrupt flags + write_register(RV3028_STATUS, 0); } @@ -748,144 +718,151 @@ namespace pimoroni { uint8_t RV3028::get_bits(uint8_t reg, uint8_t shift, uint8_t mask) { uint8_t value; - this->read_bytes(reg, &value, 1); + read_bytes(reg, &value, 1); return value & (mask << shift); } void RV3028::set_bits(uint8_t reg, uint8_t shift, uint8_t mask) { uint8_t value; - this->read_bytes(reg, &value, 1); + read_bytes(reg, &value, 1); value |= mask << shift; - this->write_bytes(reg, &value, 1); + write_bytes(reg, &value, 1); } void RV3028::clear_bits(uint8_t reg, uint8_t shift, uint8_t mask) { uint8_t value; - this->read_bytes(reg, &value, 1); + read_bytes(reg, &value, 1); value &= ~(mask << shift); - this->write_bytes(reg, &value, 1); + write_bytes(reg, &value, 1); } /********************************* FOR INTERNAL USE ********************************/ - uint8_t RV3028::BCDtoDEC(uint8_t val) - { + uint8_t RV3028::bcd_to_dec(uint8_t val) { return ((val / 0x10) * 10) + (val % 0x10); } // BCDtoDEC -- convert decimal to binary-coded decimal (BCD) - uint8_t RV3028::DECtoBCD(uint8_t val) - { + uint8_t RV3028::dec_to_bcd(uint8_t val) { return ((val / 10) * 0x10) + (val % 10); } - uint8_t RV3028::readRegister(uint8_t addr) - { + uint8_t RV3028::read_register(uint8_t addr) { uint8_t b1[2]; - if ( 1 == RV3028::read_bytes(addr, b1, 1)) { + if( 1 == RV3028::read_bytes(addr, b1, 1)) return b1[0]; - } else { - return (0xFF); //Error - } + else + return 0xFF; //Error } - bool RV3028::writeRegister(uint8_t addr, uint8_t val) - { + bool RV3028::write_register(uint8_t addr, uint8_t val) { uint8_t b1[2]; b1[0] = val; b1[1] = 0; return(RV3028::write_bytes(addr, b1, 1)); } - bool RV3028::readMultipleRegisters(uint8_t addr, uint8_t * dest, uint8_t len) - { + bool RV3028::read_multiple_registers(uint8_t addr, uint8_t *dest, uint8_t len) { return(RV3028::read_bytes(addr, dest, len)); } - bool RV3028::writeMultipleRegisters(uint8_t addr, uint8_t * values, uint8_t len) - { + bool RV3028::write_multiple_registers(uint8_t addr, uint8_t *values, uint8_t len) { return(RV3028::write_bytes(addr, values, len)); } - bool RV3028::writeConfigEEPROM_RAMmirror(uint8_t eepromaddr, uint8_t val) - { - bool success = waitforEEPROM(); + bool RV3028::write_config_eeprom_ram_mirror(uint8_t eeprom_addr, uint8_t val) { + bool success = wait_for_eeprom(); //Disable auto refresh by writing 1 to EERD control bit in CTRL1 register - uint8_t ctrl1 = readRegister(RV3028_CTRL1); + uint8_t ctrl1 = read_register(RV3028_CTRL1); ctrl1 |= 1 << CTRL1_EERD; - if (!writeRegister(RV3028_CTRL1, ctrl1)) success = false; + + if(!write_register(RV3028_CTRL1, ctrl1)) + success = false; + //Write Configuration RAM Register - writeRegister(eepromaddr, val); + write_register(eeprom_addr, val); + //Update EEPROM (All Configuration RAM -> EEPROM) - writeRegister(RV3028_EEPROM_CMD, EEPROMCMD_First); - writeRegister(RV3028_EEPROM_CMD, EEPROMCMD_Update); - if (!waitforEEPROM()) success = false; + write_register(RV3028_EEPROM_CMD, EEPROMCMD_First); + write_register(RV3028_EEPROM_CMD, EEPROMCMD_Update); + + if(!wait_for_eeprom()) + success = false; + //Reenable auto refresh by writing 0 to EERD control bit in CTRL1 register - ctrl1 = readRegister(RV3028_CTRL1); - if (ctrl1 == 0x00)success = false; + ctrl1 = read_register(RV3028_CTRL1); + if(ctrl1 == 0x00) + success = false; + ctrl1 &= ~(1 << CTRL1_EERD); - writeRegister(RV3028_CTRL1, ctrl1); - if (!waitforEEPROM()) success = false; + write_register(RV3028_CTRL1, ctrl1); + + if(!wait_for_eeprom()) + success = false; return success; } - uint8_t RV3028::readConfigEEPROM_RAMmirror(uint8_t eepromaddr) - { - bool success = waitforEEPROM(); + uint8_t RV3028::read_config_eeprom_ram_mirror(uint8_t eeprom_addr) { + bool success = wait_for_eeprom(); //Disable auto refresh by writing 1 to EERD control bit in CTRL1 register - uint8_t ctrl1 = readRegister(RV3028_CTRL1); + uint8_t ctrl1 = read_register(RV3028_CTRL1); ctrl1 |= 1 << CTRL1_EERD; - if (!writeRegister(RV3028_CTRL1, ctrl1)) success = false; - //Read EEPROM Register - writeRegister(RV3028_EEPROM_ADDR, eepromaddr); - writeRegister(RV3028_EEPROM_CMD, EEPROMCMD_First); - writeRegister(RV3028_EEPROM_CMD, EEPROMCMD_ReadSingle); - if (!waitforEEPROM()) success = false; - uint8_t eepromdata = readRegister(RV3028_EEPROM_DATA); - if (!waitforEEPROM()) success = false; - //Reenable auto refresh by writing 0 to EERD control bit in CTRL1 register - ctrl1 = readRegister(RV3028_CTRL1); - if (ctrl1 == 0x00)success = false; - ctrl1 &= ~(1 << CTRL1_EERD); - writeRegister(RV3028_CTRL1, ctrl1); + if(!write_register(RV3028_CTRL1, ctrl1)) + success = false; - if (!success) return 0xFF; - return eepromdata; + //Read EEPROM Register + write_register(RV3028_EEPROM_ADDR, eeprom_addr); + write_register(RV3028_EEPROM_CMD, EEPROMCMD_First); + write_register(RV3028_EEPROM_CMD, EEPROMCMD_ReadSingle); + + if(!wait_for_eeprom()) + success = false; + + uint8_t eeprom_data = read_register(RV3028_EEPROM_DATA); + if(!wait_for_eeprom()) + success = false; + + //Reenable auto refresh by writing 0 to EERD control bit in CTRL1 register + ctrl1 = read_register(RV3028_CTRL1); + if(ctrl1 == 0x00) + success = false; + + ctrl1 &= ~(1 << CTRL1_EERD); + write_register(RV3028_CTRL1, ctrl1); + + if(!success) + return 0xFF; + + return eeprom_data; } //True if success, false if timeout occured - bool RV3028::waitforEEPROM() - { + bool RV3028::wait_for_eeprom() { // Timeout is number of loops round while - don't have access to millisecond counter unsigned long timeout = 500; - while ((readRegister(RV3028_STATUS) & 1 << STATUS_EEBUSY) && --timeout > 0); + while ((read_register(RV3028_STATUS) & 1 << STATUS_EEBUSY) && --timeout > 0); return timeout > 0; } - void RV3028::reset() - { - setBit(RV3028_CTRL2, CTRL2_RESET); + void RV3028::reset() { + set_bit(RV3028_CTRL2, CTRL2_RESET); } - void RV3028::setBit(uint8_t reg_addr, uint8_t bit_num) - { + void RV3028::set_bit(uint8_t reg_addr, uint8_t bit_num) { RV3028::set_bits(reg_addr, bit_num, 0x01); } - void RV3028::clearBit(uint8_t reg_addr, uint8_t bit_num) - { + void RV3028::clear_bit(uint8_t reg_addr, uint8_t bit_num) { RV3028::clear_bits(reg_addr, bit_num, 0x01); } - bool RV3028::readBit(uint8_t reg_addr, uint8_t bit_num) - { + bool RV3028::read_bit(uint8_t reg_addr, uint8_t bit_num) { uint8_t value = RV3028::get_bits(reg_addr, bit_num, 0x01); return value; } - -} +} \ No newline at end of file diff --git a/drivers/rv3028/rv3028.hpp b/drivers/rv3028/rv3028.hpp index 10c8010c..b8e49cc9 100644 --- a/drivers/rv3028/rv3028.hpp +++ b/drivers/rv3028/rv3028.hpp @@ -179,127 +179,152 @@ Distributed as-is; no warranty is given. namespace pimoroni { enum time_order { - TIME_SECONDS, // 0 - TIME_MINUTES, // 1 - TIME_HOURS, // 2 - TIME_WEEKDAY, // 3 - TIME_DATE, // 4 - TIME_MONTH, // 5 - TIME_YEAR, // 6 + TIME_SECONDS, // 0 + TIME_MINUTES, // 1 + TIME_HOURS, // 2 + TIME_WEEKDAY, // 3 + TIME_DATE, // 4 + TIME_MONTH, // 5 + TIME_YEAR, // 6 }; - class RV3028 - { - i2c_inst_t *i2c = i2c0; - // interface pins with our standard defaults where appropriate - int8_t sda = 20; - int8_t scl = 21; - int8_t interrupt = 22; - public: - RV3028() {} - - RV3028(i2c_inst_t *i2c, uint8_t sda, uint8_t scl, uint8_t interrupt) : - i2c(i2c), sda(sda), scl(scl), interrupt(interrupt) {} - - void init(); - - bool setup(bool set_24Hour = true, bool disable_TrickleCharge = true, bool set_LevelSwitchingMode = true); - bool setTime(uint8_t sec, uint8_t min, uint8_t hour, uint8_t weekday, uint8_t date, uint8_t month, uint16_t year); - bool setTime(uint8_t * time, uint8_t len); - bool setSeconds(uint8_t value); - bool setMinutes(uint8_t value); - bool setHours(uint8_t value); - bool setWeekday(uint8_t value); - bool setDate(uint8_t value); - bool setMonth(uint8_t value); - bool setYear(uint16_t value); - bool setToCompilerTime(); //Uses the hours, mins, etc from compile time to set RTC - - bool updateTime() ; //Update the local array with the RTC registers - - char* stringDateUSA(); //Return date in mm-dd-yyyy - char* stringDate(); //Return date in dd-mm-yyyy - char* stringTime(); //Return time hh:mm:ss with AM/PM if in 12 hour mode - char* stringTimeStamp(); //Return timeStamp in ISO 8601 format yyyy-mm-ddThh:mm:ss - - uint8_t getSeconds(); - uint8_t getMinutes(); - uint8_t getHours(); - uint8_t getWeekday(); - uint8_t getDate(); - uint8_t getMonth(); - uint16_t getYear(); + class RV3028 { + //-------------------------------------------------- + // Constants + //-------------------------------------------------- + public: + static const uint8_t DEFAULT_I2C_ADDRESS = RV3028_ADDR; + static const uint8_t DEFAULT_SDA_PIN = 20; + static const uint8_t DEFAULT_SCL_PIN = 21; + static const uint8_t DEFAULT_INT_PIN = 22; + static const uint8_t PIN_UNUSED = UINT8_MAX; - bool is12Hour(); //Returns true if 12hour bit is set - bool isPM(); //Returns true if is12Hour and PM bit is set - void set12Hour(); - void set24Hour(); - - bool setUNIX(uint32_t value);//Set the UNIX Time (Real Time and UNIX Time are INDEPENDENT!) - uint32_t getUNIX(); - - void enableAlarmInterrupt(uint8_t min, uint8_t hour, uint8_t date_or_weekday, bool setWeekdayAlarm_not_Date, uint8_t mode, bool enable_clock_output = false); - void enableAlarmInterrupt(); - void disableAlarmInterrupt(); - bool readAlarmInterruptFlag(); - void clearAlarmInterruptFlag(); - - void setTimer(bool timer_repeat, uint16_t timer_frequency, uint16_t timer_value, bool setInterrupt, bool start_timer, bool enable_clock_output = false); - uint16_t getTimerCount(void); - void enableTimer(); - void disableTimer(); - void enableTimerInterrupt(); - void disableTimerInterrupt(); - bool readTimerInterruptFlag(); - void clearTimerInterruptFlag(); - - void enablePeriodicUpdateInterrupt(bool every_second, bool enable_clock_output = false); - void disablePeriodicUpdateInterrupt(); - bool readPeriodicUpdateInterruptFlag(); - void clearPeriodicUpdateInterruptFlag(); - - void enableTrickleCharge(uint8_t tcr = TCR_15K); //Trickle Charge Resistor default 15k - void disableTrickleCharge(); - bool setBackupSwitchoverMode(uint8_t val); - - void enableClockOut(uint8_t freq); - void enableInterruptControlledClockout(uint8_t freq); - void disableClockOut(); - bool readClockOutputInterruptFlag(); - void clearClockOutputInterruptFlag(); - - uint8_t status(); //Returns the status byte - void clearInterrupts(); - - //Values in RTC are stored in Binary Coded Decimal. These functions convert to/from Decimal - uint8_t BCDtoDEC(uint8_t val); - uint8_t DECtoBCD(uint8_t val); - - uint8_t readRegister(uint8_t addr); - bool writeRegister(uint8_t addr, uint8_t val); - bool readMultipleRegisters(uint8_t addr, uint8_t * dest, uint8_t len); - bool writeMultipleRegisters(uint8_t addr, uint8_t * values, uint8_t len); - - bool writeConfigEEPROM_RAMmirror(uint8_t eepromaddr, uint8_t val); - uint8_t readConfigEEPROM_RAMmirror(uint8_t eepromaddr); - bool waitforEEPROM(); - void reset(); - - void setBit(uint8_t reg_addr, uint8_t bit_num); - void clearBit(uint8_t reg_addr, uint8_t bit_num); - bool readBit(uint8_t reg_addr, uint8_t bit_num); + //-------------------------------------------------- + // Variables + //-------------------------------------------------- private: - uint8_t _time[TIME_ARRAY_LENGTH]; - i2c_inst_t *_i2cPort; - int8_t address = RV3028_ADDR; + i2c_inst_t *i2c = i2c0; - // From i2cdevice - int write_bytes(uint8_t reg, uint8_t *buf, int len); - int read_bytes(uint8_t reg, uint8_t *buf, int len); - uint8_t get_bits(uint8_t reg, uint8_t shift, uint8_t mask=0b1); - void set_bits(uint8_t reg, uint8_t shift, uint8_t mask=0b1); - void clear_bits(uint8_t reg, uint8_t shift, uint8_t mask=0b1); + // interface pins with our standard defaults where appropriate + int8_t address = DEFAULT_I2C_ADDRESS; + int8_t sda = DEFAULT_SDA_PIN; + int8_t scl = DEFAULT_SCL_PIN; + int8_t interrupt = DEFAULT_INT_PIN; + + uint8_t times[TIME_ARRAY_LENGTH]; + + + //-------------------------------------------------- + // Constructors/Destructor + //-------------------------------------------------- + public: + RV3028() {} + + RV3028(i2c_inst_t *i2c, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED) : + i2c(i2c), sda(sda), scl(scl), interrupt(interrupt) {} + + + //-------------------------------------------------- + // Methods + //-------------------------------------------------- + public: + bool init(); + + bool setup(bool set_24Hour = true, bool disable_TrickleCharge = true, bool set_LevelSwitchingMode = true); + bool set_time(uint8_t sec, uint8_t min, uint8_t hour, uint8_t weekday, uint8_t date, uint8_t month, uint16_t year); + bool set_time(uint8_t *time, uint8_t len); + bool set_seconds(uint8_t value); + bool set_minutes(uint8_t value); + bool set_hours(uint8_t value); + bool set_weekday(uint8_t value); + bool set_date(uint8_t value); + bool set_month(uint8_t value); + bool set_year(uint16_t value); + bool set_to_compiler_time(); //Uses the hours, mins, etc from compile time to set RTC + + bool update_time(); //Update the local array with the RTC registers + + char* string_date_usa(); //Return date in mm-dd-yyyy + char* string_date(); //Return date in dd-mm-yyyy + char* string_time(); //Return time hh:mm:ss with AM/PM if in 12 hour mode + char* string_time_stamp(); //Return timeStamp in ISO 8601 format yyyy-mm-ddThh:mm:ss + + uint8_t get_seconds(); + uint8_t get_minutes(); + uint8_t get_hours(); + uint8_t get_weekday(); + uint8_t get_date(); + uint8_t get_month(); + uint16_t get_year(); + + + bool is_12_hour(); //Returns true if 12hour bit is set + bool is_pm(); //Returns true if is12Hour and PM bit is set + void set_12_hour(); + void set_24_hour(); + + bool set_unix(uint32_t value); //Set the UNIX Time (Real Time and UNIX Time are INDEPENDENT!) + uint32_t get_unix(); + + void enable_alarm_interrupt(uint8_t min, uint8_t hour, uint8_t date_or_weekday, bool setWeekdayAlarm_not_Date, uint8_t mode, bool enable_clock_output = false); + void enable_alarm_interrupt(); + void disable_alarm_interrupt(); + bool read_alarm_interrupt_flag(); + void clear_alarm_interrupt_flag(); + + void set_timer(bool timer_repeat, uint16_t timer_frequency, uint16_t timer_value, bool setInterrupt, bool start_timer, bool enable_clock_output = false); + uint16_t get_timer_count(void); + void enable_timer(); + void disable_timer(); + void enable_timer_interrupt(); + void disable_timer_interrupt(); + bool read_timer_interrupt_flag(); + void clear_timer_interrupt_flag(); + + void enable_periodic_update_interrupt(bool every_second, bool enable_clock_output = false); + void disable_periodic_update_interrupt(); + bool read_periodic_update_interrupt_flag(); + void clear_periodic_update_interrupt_flag(); + + void enable_trickle_charge(uint8_t tcr = TCR_15K); //Trickle Charge Resistor default 15k + void disable_trickle_charge(); + bool set_backup_switchover_mode(uint8_t val); + + void enable_clock_out(uint8_t freq); + void enable_interrupt_controlled_clockout(uint8_t freq); + void disable_clock_out(); + bool read_clock_output_interrupt_flag(); + void clear_clock_output_interrupt_flag(); + + uint8_t status(); //Returns the status byte + void clear_interrupts(); + + //Values in RTC are stored in Binary Coded Decimal. These functions convert to/from Decimal + uint8_t bcd_to_dec(uint8_t val); + uint8_t dec_to_bcd(uint8_t val); + + uint8_t read_register(uint8_t addr); + bool write_register(uint8_t addr, uint8_t val); + bool read_multiple_registers(uint8_t addr, uint8_t *dest, uint8_t len); + bool write_multiple_registers(uint8_t addr, uint8_t *values, uint8_t len); + + bool write_config_eeprom_ram_mirror(uint8_t eepromaddr, uint8_t val); + uint8_t read_config_eeprom_ram_mirror(uint8_t eepromaddr); + bool wait_for_eeprom(); + void reset(); + + void set_bit(uint8_t reg_addr, uint8_t bit_num); + void clear_bit(uint8_t reg_addr, uint8_t bit_num); + bool read_bit(uint8_t reg_addr, uint8_t bit_num); + + private: + // From i2cdevice + int write_bytes(uint8_t reg, uint8_t *buf, int len); + int read_bytes(uint8_t reg, uint8_t *buf, int len); + uint8_t get_bits(uint8_t reg, uint8_t shift, uint8_t mask = 0b1); + void set_bits(uint8_t reg, uint8_t shift, uint8_t mask = 0b1); + void clear_bits(uint8_t reg, uint8_t shift, uint8_t mask = 0b1); }; //POSSIBLE ENHANCEMENTS : diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 18bb4c93..156f45d0 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -8,6 +8,7 @@ add_subdirectory(breakout_rgbmatrix5x5) add_subdirectory(breakout_matrix11x7) add_subdirectory(breakout_mics6814) add_subdirectory(breakout_potentiometer) +add_subdirectory(breakout_rtc) add_subdirectory(breakout_trackball) add_subdirectory(breakout_sgp30) add_subdirectory(breakout_colourlcd240x240) diff --git a/examples/breakout_rtc/CMakeLists.txt b/examples/breakout_rtc/CMakeLists.txt new file mode 100644 index 00000000..70c13b2e --- /dev/null +++ b/examples/breakout_rtc/CMakeLists.txt @@ -0,0 +1,16 @@ +set(OUTPUT_NAME rtc_demo) + +add_executable( + ${OUTPUT_NAME} + demo.cpp +) + +# enable usb output, disable uart output +pico_enable_stdio_usb(${OUTPUT_NAME} 1) +pico_enable_stdio_uart(${OUTPUT_NAME} 0) + +# Pull in pico libraries that we need +target_link_libraries(${OUTPUT_NAME} pico_stdlib breakout_rtc) + +# create map/bin/hex file etc. +pico_add_extra_outputs(${OUTPUT_NAME}) diff --git a/examples/breakout_rtc/demo.cpp b/examples/breakout_rtc/demo.cpp new file mode 100644 index 00000000..f7093133 --- /dev/null +++ b/examples/breakout_rtc/demo.cpp @@ -0,0 +1,45 @@ +#include "pico/stdlib.h" + +#include "breakout_rtc.hpp" + +using namespace pimoroni; + +BreakoutRTC rtc; + +int main() { + stdio_init_all(); + + gpio_init(PICO_DEFAULT_LED_PIN); + gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); + + rtc.init(); + // rtc.setup(false); + + // Uncomment the below line on first run to set the RTC date and time to the program's compiler time + // rtc.set_to_compiler_time(); + + // Make sure we have 24-hour time + if(rtc.is_12_hour()) + rtc.set_24_hour(); + + // Set to update once per second + rtc.enable_periodic_update_interrupt(true); + + while(true) { + //Has a second passed? + if(rtc.read_periodic_update_interrupt_flag()) { + rtc.clear_periodic_update_interrupt_flag(); + + //Update the locally stored time from the RTC + if(rtc.update_time()) { + printf("Date: %s, Time: %s\n", rtc.string_date(), rtc.string_time()); + gpio_put(PICO_DEFAULT_LED_PIN, true); + sleep_ms(100); + gpio_put(PICO_DEFAULT_LED_PIN, false); + } + } + sleep_ms(100); + } + + return 0; +} diff --git a/examples/pico_rtc_display/CMakeLists.txt b/examples/pico_rtc_display/CMakeLists.txt index 50726a17..8f03ce48 100644 --- a/examples/pico_rtc_display/CMakeLists.txt +++ b/examples/pico_rtc_display/CMakeLists.txt @@ -1,10 +1,12 @@ +set(OUTPUT_NAME rtc_display) + add_executable( - rtc_display + ${OUTPUT_NAME} demo.cpp ) # Pull in pico libraries that we need -target_link_libraries(rtc_display pico_stdlib pico_explorer pico_display rv3028) +target_link_libraries(${OUTPUT_NAME} pico_stdlib pico_explorer pico_display breakout_rtc) # create map/bin/hex file etc. -pico_add_extra_outputs(rtc_display) +pico_add_extra_outputs(${OUTPUT_NAME}) diff --git a/examples/pico_rtc_display/demo.cpp b/examples/pico_rtc_display/demo.cpp index d0613d80..266d70b8 100644 --- a/examples/pico_rtc_display/demo.cpp +++ b/examples/pico_rtc_display/demo.cpp @@ -25,7 +25,7 @@ #else #include "pico_display.hpp" #endif -#include "rv3028.hpp" +#include "breakout_rtc.hpp" #define MODE_DISP_CLOCK 0 #define MODE_DISP_TIMER 1 @@ -47,15 +47,17 @@ uint16_t screen_width = PicoDisplay::WIDTH; uint16_t screen_height = PicoDisplay::HEIGHT; #endif -RV3028 rv3028; +BreakoutRTC rtc; #define LOW_COUNT_MOD 40 #define HIGH_COUNT_MOD 20 + bool repeat_count_reached(uint16_t curr_count) { // Check whether the current counter means that a key has repeated - if (curr_count <= 10*LOW_COUNT_MOD) { + if(curr_count <= 10*LOW_COUNT_MOD) { return (0 == (curr_count % LOW_COUNT_MOD)); - } else { + } + else { return (0 == (curr_count % HIGH_COUNT_MOD)); } } @@ -65,10 +67,11 @@ void flash_led(uint32_t curr_count) { // Flash the LED based on the current loop counter // curr_count=0 will turn LED off #ifndef USE_PICO_EXPLORER - if ((curr_count % FLASH_MOD) < (FLASH_MOD / 2)) { + if((curr_count % FLASH_MOD) < (FLASH_MOD / 2)) { // value less than half modded number - LED off pico_display.set_led(0, 0, 0); - } else { + } + else { // value more than half modded number - LED on pico_display.set_led(128, 128, 128); } @@ -78,11 +81,12 @@ void flash_led(uint32_t curr_count) { int main() { pico_display.init(); - rv3028.init(); - // rv3028.setup(false); + rtc.init(); + // rtc.setup(false); - // Make sure we have 24-hour time (smaller dsplay!) - if (rv3028.is12Hour()) rv3028.set24Hour(); + // Make sure we have 24-hour time (smaller display!) + if(rtc.is_12_hour()) + rtc.set_24_hour(); // Use these variables to make the buttons single-shot // Counts number of loops pressed, 0 if not pressed @@ -108,71 +112,80 @@ int main() { while(true) { - if (a_pressed == 0 && pico_display.is_pressed(pico_display.A)) { + if(a_pressed == 0 && pico_display.is_pressed(pico_display.A)) { a_pressed = 1; - if (display_mode == MODE_DISP_CLOCK) { + if(display_mode == MODE_DISP_CLOCK) { // We were displaying clock = set up timer display_mode = MODE_SET_TIMER; - } else if (display_mode == MODE_SET_TIMER) { + } + else if(display_mode == MODE_SET_TIMER) { // We were setting up the timer - run it - rv3028.setTimer(false, 1, timer_count, true, true, false); + rtc.set_timer(false, 1, timer_count, true, true, false); display_mode = MODE_DISP_TIMER; - } else if (display_mode == MODE_DISP_TIMER) { + } + else if(display_mode == MODE_DISP_TIMER) { // We were running the timer - go back to setting up - if (0 == (timer_count = rv3028.getTimerCount())) { + if(0 == (timer_count = rtc.get_timer_count())) { timer_count = DEFAULT_TIMER_COUNT; } - rv3028.disableTimerInterrupt(); - rv3028.disableTimer(); - rv3028.clearTimerInterruptFlag(); + rtc.disable_timer_interrupt(); + rtc.disable_timer(); + rtc.clear_timer_interrupt_flag(); display_mode = MODE_SET_TIMER; } - } else if (a_pressed >= 1 && !pico_display.is_pressed(pico_display.A)) { + } + else if(a_pressed >= 1 && !pico_display.is_pressed(pico_display.A)) { a_pressed = 0; } - if (b_pressed == 0 && pico_display.is_pressed(pico_display.B)) { + if(b_pressed == 0 && pico_display.is_pressed(pico_display.B)) { b_pressed = 1; - if ((display_mode == MODE_DISP_TIMER) + if((display_mode == MODE_DISP_TIMER) || (display_mode == MODE_SET_TIMER)) { // We were setting or displaying timer - revert to clock - rv3028.disableTimerInterrupt(); - rv3028.disableTimer(); - rv3028.clearTimerInterruptFlag(); + rtc.disable_timer_interrupt(); + rtc.disable_timer(); + rtc.clear_timer_interrupt_flag(); display_mode = MODE_DISP_CLOCK; timer_count = DEFAULT_TIMER_COUNT; } - } else if (b_pressed >= 1 && !pico_display.is_pressed(pico_display.B)) { + } + else if(b_pressed >= 1 && !pico_display.is_pressed(pico_display.B)) { b_pressed = 0; } - if (x_pressed == 0 && pico_display.is_pressed(pico_display.X)) { + if(x_pressed == 0 && pico_display.is_pressed(pico_display.X)) { x_pressed = 1; - if (display_mode == MODE_SET_TIMER) { + if(display_mode == MODE_SET_TIMER) { // Setting timer - Increment count timer_count++; } - } else if (x_pressed >= 1 && pico_display.is_pressed(pico_display.X)) { + } + else if(x_pressed >= 1 && pico_display.is_pressed(pico_display.X)) { // Button still pressed - check if has reached repeat count - if (repeat_count_reached(x_pressed++)) { + if(repeat_count_reached(x_pressed++)) { timer_count++; } - } else if (x_pressed >= 1 && !pico_display.is_pressed(pico_display.X)) { + } + else if(x_pressed >= 1 && !pico_display.is_pressed(pico_display.X)) { x_pressed = 0; } - if (y_pressed == 0 && pico_display.is_pressed(pico_display.Y)) { + if(y_pressed == 0 && pico_display.is_pressed(pico_display.Y)) { y_pressed = 1; - if (display_mode == MODE_SET_TIMER) { + if(display_mode == MODE_SET_TIMER) { // Setting timer - Decrement count if (timer_count >= 1) timer_count--; } - } else if (y_pressed >= 1 && pico_display.is_pressed(pico_display.Y)) { + } + else if(y_pressed >= 1 && pico_display.is_pressed(pico_display.Y)) { // Button still pressed - check if has reached repeat count - if (repeat_count_reached(y_pressed++)) { - if (timer_count >= 1) timer_count--; + if(repeat_count_reached(y_pressed++)) { + if(timer_count >= 1) + timer_count--; } - } else if (y_pressed >= 1 && !pico_display.is_pressed(pico_display.Y)) { + } + else if(y_pressed >= 1 && !pico_display.is_pressed(pico_display.Y)) { y_pressed = 0; } @@ -182,32 +195,34 @@ int main() { // text_box.deflate(10); pico_display.set_clip(text_box); pico_display.set_pen(255, 255, 255); - switch (display_mode) { + switch(display_mode) { case MODE_DISP_CLOCK: // Show the clock face flash_led(0); - if (rv3028.updateTime()) { + if(rtc.update_time()) { pico_display.text("Set Timer", Point(text_box.x, text_box.y+2), 230, 1); pico_display.set_pen(0, 255, 0); - pico_display.text(rv3028.stringDate(), + pico_display.text(rtc.string_date(), Point(text_box.x, text_box.y+20), 230, 4); pico_display.set_pen(255, 0, 0); - pico_display.text(rv3028.stringTime(), + pico_display.text(rtc.string_time(), Point(text_box.x, text_box.y+60), 230, 6); pico_display.set_pen(255, 255, 255); pico_display.text("Clock", Point(text_box.x, text_box.y+screen_height-20), 230, 1); - } else { - sprintf(buf, "Time: rv3028.updateTime() ret err"); + } + else { + sprintf(buf, "Time: rtc.updateTime() ret err"); pico_display.text(buf, Point(text_box.x, text_box.y), 30, 2); } break; + case MODE_DISP_TIMER: pico_display.text("Set Timer", Point(text_box.x, text_box.y+2), 230, 1); - if (rv3028.readTimerInterruptFlag()) { + if(rtc.read_timer_interrupt_flag()) { // Go periodic time interupt - say loop ended pico_display.set_pen(255, 0, 0); sprintf(buf, "%s", "Timer complete"); @@ -215,14 +230,16 @@ int main() { Point(text_box.x, text_box.y+30), 230, 4); pico_display.set_pen(255, 255, 255); flash_led(i); - } else { - sprintf(buf, "%s %d", "Timer running", rv3028.getTimerCount()); + } + else { + sprintf(buf, "%s %d", "Timer running", rtc.get_timer_count()); pico_display.text(buf, Point(text_box.x, text_box.y+30), 230, 3); } pico_display.text("Clock", Point(text_box.x, text_box.y+screen_height-20), 230, 1); break; + case MODE_SET_TIMER: flash_led(0); pico_display.text("Run Timer", @@ -248,5 +265,5 @@ int main() { i++; } - return 0; + return 0; } diff --git a/libraries/CMakeLists.txt b/libraries/CMakeLists.txt index 197851e9..ae8ffd38 100644 --- a/libraries/CMakeLists.txt +++ b/libraries/CMakeLists.txt @@ -9,6 +9,7 @@ add_subdirectory(breakout_rgbmatrix5x5) add_subdirectory(breakout_matrix11x7) add_subdirectory(breakout_mics6814) add_subdirectory(breakout_potentiometer) +add_subdirectory(breakout_rtc) add_subdirectory(breakout_trackball) add_subdirectory(breakout_sgp30) add_subdirectory(breakout_as7262) diff --git a/libraries/breakout_rtc/CMakeLists.txt b/libraries/breakout_rtc/CMakeLists.txt new file mode 100644 index 00000000..5fb1ebf4 --- /dev/null +++ b/libraries/breakout_rtc/CMakeLists.txt @@ -0,0 +1 @@ +include(breakout_rtc.cmake) diff --git a/libraries/breakout_rtc/breakout_rtc.cmake b/libraries/breakout_rtc/breakout_rtc.cmake new file mode 100644 index 00000000..3752f421 --- /dev/null +++ b/libraries/breakout_rtc/breakout_rtc.cmake @@ -0,0 +1,11 @@ +set(LIB_NAME breakout_rtc) +add_library(${LIB_NAME} INTERFACE) + +target_sources(${LIB_NAME} INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp +) + +target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) + +# Pull in pico libraries that we need +target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib rv3028) diff --git a/libraries/breakout_rtc/breakout_rtc.cpp b/libraries/breakout_rtc/breakout_rtc.cpp new file mode 100644 index 00000000..a76531b8 --- /dev/null +++ b/libraries/breakout_rtc/breakout_rtc.cpp @@ -0,0 +1,5 @@ +#include "breakout_rtc.hpp" + +namespace pimoroni { + +} diff --git a/libraries/breakout_rtc/breakout_rtc.hpp b/libraries/breakout_rtc/breakout_rtc.hpp new file mode 100644 index 00000000..722db95c --- /dev/null +++ b/libraries/breakout_rtc/breakout_rtc.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include "../../drivers/rv3028/rv3028.hpp" + +namespace pimoroni { + + typedef RV3028 BreakoutRTC; +}