Skip to content

Add RTC library and examples #68

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions libraries/RTC/examples/Example1_getTime/Example1_getTime.ino
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
21 changes: 21 additions & 0 deletions libraries/RTC/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#######################################
# Syntax Coloring Map
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

RTC KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

getTime KEYWORD2
setTime KEYWORD2
setTimeToCompiler KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################
9 changes: 9 additions & 0 deletions libraries/RTC/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=RTC
version=1.0
author=SparkFun Electronics
maintainer=SparkFun Electronics <sparkfun.com>
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
124 changes: 124 additions & 0 deletions libraries/RTC/src/RTC.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
34 changes: 34 additions & 0 deletions libraries/RTC/src/RTC.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef RTC_H
#define RTC_H

#include <Arduino.h>

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