Part Number: MSP432P401R
I'm currently writing a program that uses the MSP432's built-in RTC module to display the date and time on a 16x2 Hitachi HD44780 LCD in 8-bit mode. The program uses the rtc_c_calendar_alarm_interrupt example from the MSP432P4 driverlib.I'm using an external library to handle printing to the LCD. See this link for the library https://e2e.ti.com/support/archive/launchyourdesign/m/msp430microcontrollerprojects/666684.
I am currently able to define an initial value for the Timer/Calendar, (see RTC_C_Calendar currentTime) and am able to write that to the LCD in the correct format. However, I am completely stuck on actually getting the RTC to update and writing the current time to the LCD once per second. I've tried declaring a second RTC_C_Calendar variable called newTime, which is where I would like to store the current date/time. I would then use these values when updating the LCD once/second. Whenever I try to pull hte values from newTime in my while loop when writing to the LCD, it reads all 0's, so my time is 00:00:00 and my date is 0/00/0. My code is pasted below. Would appreciate some guidance and explanation as to what I need to be doing here.
* MSP432 RTC_C - Calendar Mode
*
* Description: This program demonstrates the RTC mode by triggering an
* interrupt every minute. The date is set at the start of execution and an
* additional alarm for a specific time is also set to demonstrate the various
* modes of alarms/events for the RTC_C module.
*
* MSP432P401
* ------------------
* /|\| |
* | | |
* --|RST P1.0 |---> P1.0 LED
* | PJ.0 LFXIN |---------
* | | |
* | | < 32khz xTal >
* | | |
* | PJ.1 LFXOUT |---------
*
******************************************************************************/
/* DriverLib Includes */
#include <stdio.h>
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include "hd44780.h"
/* Statics */
static volatile RTC_C_Calendar newTime;
uint8_t secondFlag = 1;
char timeBuffer[14];
char dateBuffer[11];
char dayBuffer[5];
//![Simple RTC Config]
/* Time is Saturday, November 12th 1955 10:03:00 PM */
RTC_C_Calendar currentTime =
{
0x00, //seconds
0x03, //minutes
0x22, //hours
0x06, //day of week
0x12, //day of month
0x11, //month
0x1955 //year
};
//![Simple RTC Config]
/* Timer_A Up mode Configuration Parameter */
Timer_A_UpModeConfig upConfig =
{
TIMER_A_CLOCKSOURCE_SMCLK, // SMCLK Clock Source (3MHz)
TIMER_A_CLOCKSOURCE_DIVIDER_64, // SMCLK/64 = 46875Hz
50, // 50 tick period for 1 millisecond timer
TIMER_A_TAIE_INTERRUPT_DISABLE, // Disable Timer interrupt
TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE, // **ENABLE** CCR0 interrupt
TIMER_A_DO_CLEAR // Clear value
};
int main(void)
{
/* Halting WDT */
MAP_WDT_A_holdTimer();
P4DIR = 0xFF; // Set P4.0 (D0) to P4.7 (D7) to output (HD44780 data lines)
MAP_GPIO_setAsOutputPin(GPIO_PORT_P5, GPIO_PIN6); // Set P5.6 (E) and P5.7 (RS) to output (HD44780 control lines - R/W is tied to GND)
MAP_GPIO_setAsOutputPin(GPIO_PORT_P5, GPIO_PIN7);
MAP_Timer_A_configureUpMode(TIMER_A1_BASE, &upConfig);
/* Configuring pins for peripheral/crystal usage and LED for output */
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,
GPIO_PIN0 | GPIO_PIN1, GPIO_PRIMARY_MODULE_FUNCTION);
MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
/* Setting the external clock frequency. This API is optional, but will
* come in handy if the user ever wants to use the getMCLK/getACLK/etc
* functions
*/
CS_setExternalClockSourceFrequency(32000,48000000);
/* Starting LFXT in non-bypass mode without a timeout. */
CS_startLFXT(CS_LFXT_DRIVE3);
MAP_CS_initClockSignal(CS_SMCLK,CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_16); //SMCLK = 3MHz
//![Simple RTC Example]
/* Initializing RTC with current time as described in time in
* definitions section */
MAP_RTC_C_initCalendar(¤tTime, RTC_C_FORMAT_BCD);
/* Setup Calendar Alarm for 10:04pm (for the flux capacitor) */
MAP_RTC_C_setCalendarAlarm(0x04, 0x22, RTC_C_ALARMCONDITION_OFF,
RTC_C_ALARMCONDITION_OFF);
/* Specify an interrupt to assert every minute */
MAP_RTC_C_setCalendarEvent(RTC_C_CALENDAREVENT_MINUTECHANGE);
/* Enable interrupt for RTC Ready Status, which asserts when the RTC
* Calendar registers are ready to read.
* Also, enable interrupts for the Calendar alarm and Calendar event. */
MAP_RTC_C_clearInterruptFlag(
RTC_C_CLOCK_READ_READY_INTERRUPT | RTC_C_TIME_EVENT_INTERRUPT
| RTC_C_CLOCK_ALARM_INTERRUPT);
MAP_RTC_C_enableInterrupt(
RTC_C_CLOCK_READ_READY_INTERRUPT | RTC_C_TIME_EVENT_INTERRUPT
| RTC_C_CLOCK_ALARM_INTERRUPT);
//![Simple RTC Example]
/* Enable interrupts and go to sleep. */
MAP_Interrupt_enableInterrupt(INT_RTC_C);
MAP_Interrupt_enableSleepOnIsrExit();
MAP_Interrupt_enableInterrupt(INT_TA1_0);
hd44780_clear_screen();
MAP_Timer_A_startCounter(TIMER_A1_BASE, TIMER_A_UP_MODE);
/* Start RTC Clock */
MAP_RTC_C_startClock();
MAP_Interrupt_enableMaster();
while(1)
{
if(secondFlag == 1) {
/*Writing Time: hh:mm:ss to first row of LCD*/
sprintf(timeBuffer, "Time: %02d:%02d:%02d", RTC_C_convertBCDToBinary(newTime.hours),
RTC_C_convertBCDToBinary(newTime.minutes), RTC_C_convertBCDToBinary(newTime.seconds));
hd44780_write_string(timeBuffer, 1, 1, 1);
/*Writing Day of Week to second row of LCD*/
if(currentTime.dayOfWeek == 0) {
sprintf(dayBuffer, "Sun, ");
}
else if(currentTime.dayOfWeek == 1) {
sprintf(dayBuffer, "Mon, ");
}
else if(currentTime.dayOfWeek == 2) {
sprintf(dayBuffer, "Tue, ");
}
else if(currentTime.dayOfWeek == 3) {
sprintf(dayBuffer, "Wed, ");
}
else if(currentTime.dayOfWeek == 4) {
sprintf(dayBuffer, "Thu, ");
}
else if(currentTime.dayOfWeek == 5) {
sprintf(dayBuffer, "Fri, ");
}
else {
sprintf(dayBuffer, "Sat, ");
}
hd44780_write_string(dayBuffer, 2, 1, 1);
/*Writing Date mm/dd/yyyy to bottom row of LCD after day of the week*/
sprintf(dateBuffer, "%d/%02d/%d", RTC_C_convertBCDToBinary(newTime.month),
RTC_C_convertBCDToBinary(newTime.dayOfmonth), RTC_C_convertBCDToBinary(newTime.year));
hd44780_write_string(dateBuffer, 2, 6, 1);
/*Resetting secondFlag to 0*/
secondFlag = 0;
}
MAP_PCM_gotoLPM0();
}
}
/* RTC ISR */
void RTC_C_IRQHandler(void)
{
uint32_t status;
status = MAP_RTC_C_getEnabledInterruptStatus();
MAP_RTC_C_clearInterruptFlag(status);
if (status & RTC_C_CLOCK_READ_READY_INTERRUPT)
{
MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
// newTime = MAP_RTC_C_getCalendarTime();
secondFlag = 1; //happens once/sec, so using flag to update LCD once/sec in while loop
}
if (status & RTC_C_TIME_EVENT_INTERRUPT)
{
/* Interrupts every minute - Set breakpoint here */
__no_operation();
newTime = MAP_RTC_C_getCalendarTime();
}
if (status & RTC_C_CLOCK_ALARM_INTERRUPT)
{
/* Interrupts at 10:04pm */
__no_operation();
}
}
/* Timer A1.0 ISR */
void TA1_0_IRQHandler(void) {
hd44780_timer_isr();
MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE, //clear interrupt flag
TIMER_A_CAPTURECOMPARE_REGISTER_0);
}