Part Number: MSP432P401R
Hi
I am trying to operate the RTC without success. I can read RTCTIM0 and RTCTIM1 register stuck with initial value and the HOLD bit on RTCCTL1 stuck at '1'.
I put a breakpoint just after writing to the HOLD bid and verify that the SW didn't reset the bit.
I don't have a clue why i cant get the calendar to start working by resetting the HOLD bit.
Please help - attached my code.
/* --COPYRIGHT--,BSD
* Copyright (c) 2017, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --/COPYRIGHT--*/
/******************************************************************************
* MSP432 Empty Project
*
* Description: An empty project that uses DriverLib
*
* MSP432P401
* ------------------
* /|\| |
* | | |
* --|RST |
* | |
* | |
* | |
* | |
* | |
* Author:
*******************************************************************************/
// ****************************************************************************
// ____________________________
// | |
// | |
// EUSCI_B1_I2C_Mstr_SCL|P6.5 (SCL) P3.2 (RxD)|EUSCI_A2_RS232_Rx |
// EUSCI_B1_I2C_Mstr_SDA|P6.4 (SDA) P3.3 (TxD)|EUSCI_A2_RS232_Tx
// | |
// I2C_Slv_SCL|P10.3 (SCL) P1.2 (RxD)|EUSCI_A0_RS232_Rx
// I2C_Slv_SDA|P10.2 (SDA) P1.3 (TxD)|EUSCI_A0_RS232_Tx
// | |
// EUSCI_B0_SPI_STE|P1.4 (STE) P9.4 (STE)|UCB3_SPI_STE
// EUSCI_B0_SPI_CLK|P1.5 (CLK) P9.5 (CLK)|UCB3_SPI_CLK
// EUSCI_B0_SPI_SIMO|P1.6 (SIMO) P9.6 (SOMI)|UCB3_SPI_SOMI
// EUSCI_B0_SPI_SOMI|P1.7 (SOMI) P9.7 (SIMO)|UCB3_SPI_SIMO
// | |
//
//**************************************************************************************
/* DriverLib Includes */
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include <ti/devices/msp432p4xx/driverlib/rtc_c.h>
#include <ti/devices/msp432p4xx/driverlib/interrupt.h>
#include <ti/devices/msp432p4xx/driverlib/debug.h>
#include <ti/devices/msp432p4xx/driverlib/cs.h>
#include <ti/devices/msp432p4xx/driverlib/pcm.h>
#include <ti/devices/msp432p4xx/driverlib/flash.h>
/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>
//===== for uart ================
#define A0_UART_Tx_BUF_size 64 // must be 2^n
#define A0_UART_Rx_BUF_size 64 // must be 2^n
extern unsigned char RXData=0;
extern unsigned char DataRX=0; // temporary hold current investigated RX data
extern unsigned char UartTxBuf[A0_UART_Tx_BUF_size]={0};
extern unsigned char UartRxBuf[A0_UART_Rx_BUF_size]={0};
extern unsigned char RXindexin=0;
extern unsigned char RXindexout=0;
extern unsigned char TXindexout=0;
extern unsigned char TXindexin=0;
//===============================
int main(void)
{
/* Stop Watchdog */
MAP_WDT_A_holdTimer();
//====== set system operation for Mclk=48Mhz, SMclk=24Mhz, Aclk=Bclk=REFO=32Khz.================
CS_setReferenceOscillatorFrequency(CS_REFO_32KHZ); // use REFO=32Khz, other option: CS_REFO_128KHZ for REFO=128Khz
/* Set System to be ready to run at Mclk>24Mhz */
PCM_setPowerMode(PCM_DCDC_MODE); // Switch from LDO to DC-DC to enable high frequencies
/* Set the core voltage level to VCORE1 */
PCM_setCoreVoltageLevel(PCM_VCORE1);
/* Set 1 flash wait states for Flash bank 0 and 1*/
FlashCtl_setWaitState(FLASH_BANK0, 1);
FlashCtl_setWaitState(FLASH_BANK1, 1);
CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48); // Switch DCO to operate at 48Mhz
// Configure DCO to 48MHz, ensure MCLK uses DCO as source
CS->KEY = CS_KEY_VAL ; // Unlock CS module for register access
CS->CTL0 = 0; // Reset tuning parameters
CS->CTL0 = CS_CTL0_DCORSEL_5; // Set DCO to 48MHz
CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK |
CS_CTL1_SELS_MASK | CS_CTL1_DIVS_MASK | CS_CTL1_SELA_MASK)) |
CS_CTL1_SELM_3 | // Select MCLK = DCO, no divider
CS_CTL1_SELS_3 | // Select SMCLK = DCO
CS_CTL1_DIVS__2 | // with a divider of 2
CS_CTL1_SELA_2 | // Select REFO as source for ACLK
CS_CTL1_SELB; // Select REFO as source for BCLK
CS->KEY = 0; // Lock CS module from unintended accesses
//===========================================================================================
//========== Terminate all remaining pins on the device ====
P1->DIR |= 0xff; P1->OUT = 0;
P2->DIR |= 0xFF; P2->OUT = 0;
P3->DIR |= 0xFF; P3->OUT = 0;
P4->DIR |= 0xFF; P4->OUT = 0;
P5->DIR |= 0xFF; P5->OUT = 0;
P6->DIR |= 0xFF; P6->OUT = 0;
P7->DIR |= 0xFF; P7->OUT = 0;
P8->DIR |= 0xFF; P8->OUT = 0;
P9->DIR |= 0xFF; P9->OUT = 0;
P10->DIR |= 0xFF; P10->OUT = 0;
PJ->DIR |= 0xFF; PJ->OUT = 0;
// ==========================================================
// ==========init EUSCI_A0 for 115200,8,N,1 on P1.2 and P1.3==============
// Configure UART pins
P1->SEL0 |= BIT2 | BIT3; // set 2-UART pin as secondary function
// Configure UART
EUSCI_A0->CTLW0 = EUSCI_A_CTLW0_SWRST | // Remain eUSCI in reset
EUSCI_B_CTLW0_SSEL__SMCLK; // Configure eUSCI clock source for SMCLK
EUSCI_A0->BRW = 13; // 24000000/16/115200
EUSCI_A0->MCTLW = (0 << EUSCI_A_MCTLW_BRF_OFS) | EUSCI_A_MCTLW_OS16; // set UCBRFx=0 and Over sampling mode enabled
EUSCI_A0->IFG = 0x0; // Clear all interrupt flags
// EUSCI_A0->IFG &= ~EUSCI_A_IFG_RXIFG; // Clear eUSCI RX interrupt flag
EUSCI_A0->CTLW0 &= ~EUSCI_A_CTLW0_SWRST; // Initialize eUSCI by release reset
EUSCI_A0->IE |= (EUSCI_A_IE_RXIE | EUSCI_A_IFG_TXCPTIFG); // Enable USCI_A0 RX interrupt
// Enable global interrupt
__enable_irq();
// Enable eUSCIA0 interrupt in NVIC module
NVIC->ISER[0] = 1 << ((EUSCIA0_IRQn) & 31);
//========================================================================
// ==============Set RTC for 8mS interrupt and 500mS interrupt==================
// Unlock RTC key protected registers
RTC_C->CTL0 = RTC_C_KEY;
// Configure RTC
RTC_C->CTL13 = RTC_C_CTL13_HOLD | // Hold the RTC to enable register update
RTC_C_CTL13_MODE | // Set the RTC to calendar mode
RTC_C_CTL13_BCD; // BCD mode
//========= set calendar date/hour ==========
RTC_C->YEAR = 0x2021; // Year = 0x2021
RTC_C->DATE = (0x10 << RTC_C_DATE_MON_OFS) |// Month = 0x10 = October
(0x07 | RTC_C_DATE_DAY_OFS); // Day = 0x07 = 7th
RTC_C->TIM1 = (0x05 << RTC_C_TIM1_DOW_OFS) |// Day of week = 0x05 = Friday
(0x11 << RTC_C_TIM1_HOUR_OFS); // Hour = 0x11
RTC_C->TIM0 = (0x59 << RTC_C_TIM0_MIN_OFS) |// Minute = 0x59
(0x45 << RTC_C_TIM0_SEC_OFS); // Seconds = 0x45
//===========================================
// ============ SET RTC interrupts ===============
RTC_C->PS1CTL = RTC_C_PS0CTL_RT0IP_3 | // set divider to 64 (125mS)
RTC_C_PS1CTL_RT1PSIE; // Enable prescaler interrupt enable
RTC_C->PS0CTL = RTC_C_PS0CTL_RT0IP_7 | RTC_C_PS0CTL_RT0PSIE; // Pre-scaler-div256 (7.8125mS), Enable prescaler interrupt.
// ===============================================
// if needed clock time event interrupt:
RTC_C->CTL13 &= ~RTC_C_CTL13_TEV_MASK; // clear CTL13_TEV bits
RTC_C->CTL13 |= RTC_C_CTL13_TEV_0; // on minute change=RTC_C_CTL13_TEV_0, on hour change=RTC_C_CTL13_TEV_1, every day at midnight=RTC_C_CTL13_TEV_2, everyday at noon=RTC_C_CTL13_TEV_3
RTC_C->CTL0 |= RTC_C_CTL0_TEVIE; // enable real time clock time event interrupt
// Start RTC calendar mode
RTC_C->CTL13 &= ~(RTC_C_CTL13_HOLD); // Start RTC calendar mode
// Start RTC calendar mode
RTC_C->CTL13 = RTC_C->CTL13 & ~(RTC_C_CTL13_HOLD);
// Lock the RTC registers
RTC_C->CTL0 &= ~(RTC_C_CTL0_KEY_MASK); // Lock the RTC registers
// Enable global interrupt
__enable_irq();
// Enable the RTC_C in the NVIC module
NVIC->ISER[0] = 1 << ((RTC_C_IRQn) & 31);
//=============================================================================
while(1)
{
P1->OUT = 0x0; // LED for debug
}
}
// UART interrupt service routine
void EUSCIA0_IRQHandler(void)
{
// switch(EUSCI_A0->IFG & (EUSCI_A_IFG_RXIFG | EUSCI_A_IFG_TXIFG | EUSCI_A_IFG_TXCPTIFG | EUSCI_A_IFG_STTIFG))
if (EUSCI_A0->IFG & EUSCI_A_IFG_RXIFG) // if new Rx interrupt
{
UartRxBuf[RXindexin] = EUSCI_A0->RXBUF; // insert arrived character into receive buffer
RXindexin = (RXindexin + 1) & A0_UART_Rx_BUF_size; // increment input pointer with wrap around.
EUSCI_A0->IFG &= ~(EUSCI_A_IFG_RXIFG | EUSCI_A_IFG_STTIFG); // Clear eUSCI RX interrupt flag
// ============ echo Rx to Tx for debug ===============================
// Check if the TX buffer is empty first
if ((EUSCI_A0->IFG & EUSCI_A_IFG_TXIFG) != 0) // check if "Tx buffer empty" interrupt
{
EUSCI_A0->TXBUF = EUSCI_A0->RXBUF; // Echo the received character back
}
// ============== end of debug ========================================
}
else if (EUSCI_A0->IFG & EUSCI_A_IFG_TXCPTIFG) // if Transmit complete interrupt. This flag is set, after the
// complete UART byte in the internal shift register including STOP bit got shifted out and UCAxTXBUF is empty.
{
EUSCI_A0->IFG &= ~(EUSCI_A_IFG_TXCPTIFG); // Clear eUSCI Transmit complete interrupt flag
// check if Tx buf not empty and continue sending buffer until it is empty. then disable interrupt to avoid further checking.
if (!(TXindexin == TXindexout)) // check if something to print. i.e. Tx buffer not empty
{
EUSCI_A0->TXBUF = UartTxBuf[TXindexout]; // print next byte.
TXindexout = (TXindexout + 1) & A0_UART_Tx_BUF_size; // increment the index pointer to next cell with wrap around at 64.
}
}
}
// RTC interrupt service routine
void RTC_C_IRQHandler(void)
{
P1->OUT ^= BIT0; // LED for debug
if (RTC_C->PS0CTL & RTC_C_PS0CTL_RT0PSIFG) // if <pre>scale 0 interrupt occur (8mS)
{
// RTC_C->CTL0 = RTC_C_KEY_VAL; // Unlock RTC key protected registers
RTC_C->PS0CTL &= ~RTC_C_PS0CTL_RT0PSIFG; // Clear the pre-scale 0 timer interrupt flag
// RTC_C->CTL0 = 0; // lock RTC registers
}
if (RTC_C->PS1CTL & RTC_C_PS1CTL_RT1PSIFG) // if <pre>scale 1 interrupt occur (125mS)
{
RTC_C->PS1CTL &= ~(RTC_C_PS1CTL_RT1PSIFG); // Clear the pre-scale 1 timer interrupt flag
// ======== check if RS232 Tx buf not empty and start sending buffer (sending will continue during Tx complete interrupt until it is empty.) =====
if (!(TXindexin == TXindexout)) // check if something to print. i.e. Tx buffer not empty
{
if ((EUSCI_A0->IFG & EUSCI_A_IFG_TXIFG) != 0) // check if "Tx buffer empty" interrupt
{
EUSCI_A0->TXBUF = UartTxBuf[TXindexout]; // print next byte.
TXindexout = (TXindexout + 1) & A0_UART_Tx_BUF_size; // increment the index pointer to next cell with wrap around at Tx_BUF_size.
}
}
}
if (RTC_C->CTL0 & RTC_C_CTL0_TEVIFG) // if real time clock event interrupt (1sec)
{
// Unlock the RTC module and clear time event interrupt flag
RTC_C->CTL0 = (RTC_C->CTL0 & ~(RTC_C_CTL0_KEY_MASK | RTC_C_CTL0_TEVIFG)) | RTC_C_KEY;
// Re-lock the RTC
RTC_C->CTL0 = RTC_C->CTL0 & ~(RTC_C_CTL0_KEY_MASK);
}
}