diff --git a/libraries/RTC/examples/Example1_getTime/Example1_getTime.ino b/libraries/RTC/examples/Example1_getTime/Example1_getTime.ino new file mode 100644 index 0000000..766daaa --- /dev/null +++ b/libraries/RTC/examples/Example1_getTime/Example1_getTime.ino @@ -0,0 +1,46 @@ +/* Author: Nathan Seidle + Created: Septempter 27th, 2019 + License: MIT. See SparkFun Arduino Apollo3 Project for more information + + This example demonstrates how to initialize and read from the on board RTC. + Most SparkFun Artemis boards have the necessary external 32kHz crystal to + enable the RTC. If you are using the Artemis module bare you will either + need an external 32kHz xtal or use the internal LFRC. Read the datasheet + section 12.1 for more information. + + This example is based on the Ambiq SDK EVB2 RTC example. +*/ + +#include "RTC.h" //Include RTC library included with the Aruino_Apollo3 core +APM3_RTC myRTC; //Create instance of RTC class + +void setup() +{ + Serial.begin(115200); + Serial.println("SparkFun RTC Example"); + + myRTC.setToCompilerTime(); //Easily set RTC using the system __DATE__ and __TIME__ macros from compiler + //myRTC.setTime(7, 28, 51, 0, 21, 10, 15); //Manually set RTC back to the future: Oct 21st, 2015 at 7:28.51 AM +} + +void loop() +{ + myRTC.getTime(); + + Serial.printf("It is now "); + Serial.printf("%d:", myRTC.hour); + Serial.printf("%02d:", myRTC.minute); + Serial.printf("%02d.", myRTC.seconds); + Serial.printf("%02d", myRTC.hundredths); + + Serial.printf(" %02d/", myRTC.month); + Serial.printf("%02d/", myRTC.dayOfMonth); + Serial.printf("%02d", myRTC.year); + + Serial.printf(" Day of week: %d =", myRTC.weekday); + Serial.printf(" %s", myRTC.textWeekday); + + Serial.println(); + + delay(1000); +} diff --git a/libraries/RTC/examples/Example2_RTCwithSleep/Example2_RTCwithSleep.ino b/libraries/RTC/examples/Example2_RTCwithSleep/Example2_RTCwithSleep.ino new file mode 100644 index 0000000..0103a64 --- /dev/null +++ b/libraries/RTC/examples/Example2_RTCwithSleep/Example2_RTCwithSleep.ino @@ -0,0 +1,81 @@ +/* Author: Nathan Seidle + Created: Septempter 27th, 2019 + License: MIT. See SparkFun Arduino Apollo3 Project for more information + + This example demonstrates how to put the core to sleep for a number of + milliseconds before waking and printing the current time/date. This + is helpful for checking power consumption of the core while RTC+CT6 are running. +*/ + +#include "RTC.h" //Include RTC library included with the Aruino_Apollo3 core +APM3_RTC myRTC; //Create instance of RTC class + +uint32_t msToSleep = 2000; //This is the user editable number of ms to sleep between RTC checks +#define TIMER_FREQ 3000000L //Counter/Timer 6 will use the HFRC oscillator of 3MHz +uint32_t sysTicksToSleep = msToSleep * (TIMER_FREQ / 1000); + +void setup() +{ + Serial.begin(115200); + Serial.println("SparkFun RTC Example"); + + myRTC.setToCompilerTime(); //Easily set RTC using the system __DATE__ and __TIME__ macros from compiler + //myRTC.setTime(7, 28, 51, 0, 21, 10, 15); //Manually set RTC back to the future: Oct 21st, 2015 at 7:28.51 AM + + setupWakeTimer(); +} + +void loop() +{ + myRTC.getTime(); + + Serial.printf("It is now "); + Serial.printf("%d:", myRTC.hour); + Serial.printf("%02d:", myRTC.minute); + Serial.printf("%02d.", myRTC.seconds); + Serial.printf("%02d", myRTC.hundredths); + + Serial.printf(" %02d/", myRTC.month); + Serial.printf("%02d/", myRTC.dayOfMonth); + Serial.printf("%02d", myRTC.year); + + Serial.printf(" Day of week: %d =", myRTC.weekday); + Serial.printf(" %s", myRTC.textWeekday); + + Serial.println(); + + am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); //Sleepy time +} + +//We use counter/timer 6 for this example but 0 to 7 are available +//CT 7 is used for Software Serial. All CTs are used for Servo. +void setupWakeTimer() +{ + //Clear compare interrupt + am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG); //Use CT6 + + am_hal_stimer_int_enable(AM_HAL_STIMER_INT_COMPAREG); // Enable C/T G=6 + + //Don't change from 3MHz system timer, but enable G timer + am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE); + am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ | AM_HAL_STIMER_CFG_COMPARE_G_ENABLE); + + //Setup ISR to trigger when the number of ms have elapsed + am_hal_stimer_compare_delta_set(6, sysTicksToSleep); + + //Enable the timer interrupt in the NVIC. + NVIC_EnableIRQ(STIMER_CMPR6_IRQn); +} + +//Called once number of milliseconds has passed +extern "C" void am_stimer_cmpr6_isr(void) +{ + uint32_t ui32Status = am_hal_stimer_int_status_get(false); + if (ui32Status & AM_HAL_STIMER_INT_COMPAREG) + { + am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG); + + //Reset compare value. ISR will trigger when the number of ms have elapsed + am_hal_stimer_compare_delta_set(6, sysTicksToSleep); + } +} diff --git a/libraries/RTC/keywords.txt b/libraries/RTC/keywords.txt new file mode 100644 index 0000000..dd949ba --- /dev/null +++ b/libraries/RTC/keywords.txt @@ -0,0 +1,21 @@ +####################################### +# Syntax Coloring Map +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +RTC KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +getTime KEYWORD2 +setTime KEYWORD2 +setTimeToCompiler KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libraries/RTC/library.properties b/libraries/RTC/library.properties new file mode 100644 index 0000000..0d9e581 --- /dev/null +++ b/libraries/RTC/library.properties @@ -0,0 +1,9 @@ +name=RTC +version=1.0 +author=SparkFun Electronics +maintainer=SparkFun Electronics +sentence=Real Time Clock (RTC)) library for the SparkFun Artemis +paragraph=Enables the setting and reading of the RTC hardware built into Apollo based modules like the Artemis. Many SparkFun Artemis carrier boards have a built in 32kHz crystals. This library enables the reading of the current date and time. +category=Timing +url= +architectures=apollo3 diff --git a/libraries/RTC/src/RTC.cpp b/libraries/RTC/src/RTC.cpp new file mode 100644 index 0000000..02946e9 --- /dev/null +++ b/libraries/RTC/src/RTC.cpp @@ -0,0 +1,124 @@ +/* + This example is based on the Ambiq SDK EVB2 RTC example. +*/ + +#include "RTC.h" + +am_hal_rtc_time_t hal_time; + +// String arrays to index Days and Months with the values returned by the RTC. +char const *pcWeekday[] = + { + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Invalid day"}; + +char const *pcMonth[] = + { + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", + "Invalid month"}; + +//Constructor +APM3_RTC::APM3_RTC() +{ + // Enable the XT for the RTC. + am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_XTAL_START, 0); + + // Select XT for RTC clock source + am_hal_rtc_osc_select(AM_HAL_RTC_OSC_XT); + + // Enable the RTC. + am_hal_rtc_osc_enable(); +} + +void APM3_RTC::setTime(uint8_t hour, uint8_t min, uint8_t sec, uint8_t hund, uint8_t dayOfMonth, uint8_t month, uint16_t year) +{ + hal_time.ui32Hour = hour; + hal_time.ui32Minute = min; + hal_time.ui32Second = sec; + hal_time.ui32Hundredths = hund; + + hal_time.ui32DayOfMonth = dayOfMonth; + hal_time.ui32Month = month - 1; //HAL is expecting 0 to 11 months + hal_time.ui32Year = year; + hal_time.ui32Century = 0; + + hal_time.ui32Weekday = am_util_time_computeDayofWeek(2000 + year, month + 1, dayOfMonth); + + am_hal_rtc_time_set(&hal_time); //Initialize the RTC with this date/time +} + +//Takes the time from the last build and uses it as the current time +//Works well as an arduino sketch +void APM3_RTC::setToCompilerTime() +{ + //Get the current date/time from the compiler + //Alternatively, you can set these values manually + hal_time.ui32Hour = toVal(&__TIME__[0]); + hal_time.ui32Minute = toVal(&__TIME__[3]); + hal_time.ui32Second = toVal(&__TIME__[6]); + hal_time.ui32Hundredths = 00; + hal_time.ui32Weekday = am_util_time_computeDayofWeek(2000 + toVal(&__DATE__[9]), mthToIndex(&__DATE__[0]) + 1, toVal(&__DATE__[4])); + hal_time.ui32DayOfMonth = toVal(&__DATE__[4]); + hal_time.ui32Month = mthToIndex(&__DATE__[0]); + hal_time.ui32Year = toVal(&__DATE__[9]); + hal_time.ui32Century = 0; + + am_hal_rtc_time_set(&hal_time); //Initialize the RTC with this date/time +} + +void APM3_RTC::getTime() +{ + am_hal_rtc_time_get(&hal_time); + + hour = hal_time.ui32Hour; + minute = hal_time.ui32Minute; + seconds = hal_time.ui32Second; + hundredths = hal_time.ui32Hundredths; + + month = hal_time.ui32Month + 1; //Convert from 0-11 to 1-12 + dayOfMonth = hal_time.ui32DayOfMonth; + year = hal_time.ui32Year; + + weekday = hal_time.ui32Weekday; + textWeekday = pcWeekday[hal_time.ui32Weekday]; //Given a number (day of week) return the string that represents the name +} + +// mthToIndex() converts a string indicating a month to an index value. +// The return value is a value 0-12, with 0-11 indicating the month given +// by the string, and 12 indicating that the string is not a month. +int APM3_RTC::mthToIndex(char const *pcMon) +{ + int idx; + for (idx = 0; idx < 12; idx++) + { + if (am_util_string_strnicmp(pcMonth[idx], pcMon, 3) == 0) + return idx; + } + return 12; //Error +} + +// toVal() converts a string to an ASCII value. +int APM3_RTC::toVal(char const *pcAsciiStr) +{ + int iRetVal = 0; + iRetVal += pcAsciiStr[1] - '0'; + iRetVal += pcAsciiStr[0] == ' ' ? 0 : (pcAsciiStr[0] - '0') * 10; + return iRetVal; +} diff --git a/libraries/RTC/src/RTC.h b/libraries/RTC/src/RTC.h new file mode 100644 index 0000000..a4262bc --- /dev/null +++ b/libraries/RTC/src/RTC.h @@ -0,0 +1,34 @@ +#ifndef RTC_H +#define RTC_H + +#include + +class APM3_RTC +{ +public: + APM3_RTC(); + + void getTime(); //Query the RTC for the current time/date. Loads .seconds, .minute, etc. + void setTime(uint8_t hour, uint8_t min, uint8_t sec, uint8_t hund, + uint8_t dayOfMonth, uint8_t month, uint16_t year); //Set current time to provided hundredths/seconds/etc + void setToCompilerTime(); //Set to time when sketch was compiled + + uint32_t hour; + uint32_t minute; + uint32_t seconds; + uint32_t hundredths; + + uint32_t dayOfMonth; + uint32_t month; + uint32_t year; + uint32_t century; + + uint32_t weekday; //0 to 6 representing the day of the week + const char *textWeekday; + +private: + //Helper functions to convert compiler date/time to ints + int toVal(char const *pcAsciiStr); + int mthToIndex(char const *pcMon); +}; +#endif //RTC_H