This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
I am trying to run the MSP430FR2433 MCU in LPM3.5 and wake it up using RTC every 1s. It is waking up properly, but whenever it wakes up I am trying to do some calculation and send that char data of 19 length using UART. I am able to get char data of max around 17 length. After that data is not received and next packet starts coming in the next RTC interrupt wakeup.
I am not able to understand why this is happening, can anyone help me to understand this and help me to fix this?
RTC clock source: XT1CLK
I am also attaching full code for reference.
Thanks
Jeevant Sah
#include <msp430.h> #include <stdint.h> #include "RTC_Calendar.h" /** * main.c */ #define SMCLK_115200 0 #define SMCLK_9600 1 #define UART_MODE SMCLK_115200//SMCLK_9600// uint16_t mid_second,mid_minute,mid_hour,mid_day,mid_month,mid_year; void print(char *text) { unsigned int i = 0; while(text[i] != '\0') { while(!(UCA0IFG&UCTXIFG)); // Check if TX is ongoing UCA0TXBUF = text[i]; // TX -> Received Char + 1 i++; } } void printNumber(unsigned int num) { char buf[6]; char *str = &buf[5]; *str = '\0'; do { unsigned long m = num; num /= 10; char c = (m - 10 * num) + '0'; *--str = c; } while(num); print(str); } void initUART() { // Configure USCI_A0 for UART mode UCA0CTLW0 |= UCSWRST; // Put eUSCI in reset #if UART_MODE == SMCLK_115200 UCA0CTLW0 |= UCSSEL__SMCLK; // CLK = SMCLK // Baud Rate Setting // Use Table 21-5 UCA0BRW = 8; UCA0MCTLW |= UCOS16 | UCBRF_10 | 0xF700; //0xF700 is UCBRSx = 0xF7 #elif UART_MODE == SMCLK_9600 UCA0CTLW0 |= UCSSEL__SMCLK; // CLK = SMCLK // Baud Rate Setting // Use Table 21-5 UCA0BRW = 104; UCA0MCTLW |= UCOS16 | UCBRF_2 | 0xD600; //0xD600 is UCBRSx = 0xD6 #else # error "Please specify baud rate to 115200 or 9600" #endif UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI //UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt } void initClockTo16MHz() { // Configure one FRAM waitstate as required by the device datasheet for MCLK // operation beyond 8MHz _before_ configuring the clock system. FRCTL0 = FRCTLPW | NWAITS_1; __bis_SR_register(SCG0); // disable FLL CSCTL3 |= SELREF__XT1CLK; // Set REFO as FLL reference source CSCTL0 = 0; // clear DCO and MOD registers CSCTL1 &= ~(DCORSEL_7); // Clear DCO frequency select bits first CSCTL1 |= DCORSEL_5; // Set DCO = 16MHz CSCTL2 = FLLD_0 + 487; // set to fDCOCLKDIV = (FLLN + 1)*(fFLLREFCLK/n) // = (487 + 1)*(32.768 kHz/1) // = 16 MHz __delay_cycles(3); __bic_SR_register(SCG0); // enable FLL while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // FLL locked CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; } void initGpio() { P1DIR = 0xFF; P2DIR = 0xFF; P3DIR = 0xFF; P1REN = 0xFF; P2REN = 0xFF; P3REN = 0xFF; P1OUT = 0x00; P2OUT = 0x00; P3OUT = 0x00; // Disable the GPIO power-on default high-impedance mode // to activate previously configured port settings // Configure GPIO P1SEL1 &= ~(BIT4 | BIT5); // USCI_A0 UART operation P1SEL0 |= BIT4 | BIT5; P2SEL0 |= BIT0 | BIT1; // set XT1 pin as second function PM5CTL0 &= ~LOCKLPM5; } void delay_ms(unsigned int ms) { while (ms) { __delay_cycles(16000); ms--; } } int main(void) { WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer initGpio(); // Initialize XT1 32kHz crystal do { CSCTL7 &= ~(XT1OFFG | DCOFFG); // Clear XT1 and DCO fault flag SFRIFG1 &= ~OFIFG; } while (SFRIFG1 & OFIFG); // Test oscillator fault flag initClockTo16MHz(); initUART(); // First determine whether we are coming out of an LPMx.5 or a regular RESET. if (SYSRSTIV == SYSRSTIV_LPM5WU) // When woken up from LPM3.5, reinit { // If MCU wakes up from LPM3.5, re-init and then return to LPM3.5 again. // Restore P1OUT value from backup RAM memory, keep P1OUT after LPMx.5 reset //P1OUT = *(unsigned int *)BKMEM_BASE; P1OUT &= BIT0; __enable_interrupt(); // The RTC interrupt should trigger now... } else { // Device powered up from a cold start. // It configures the device and puts the device into LPM3.5 // Configure backup memory *(unsigned int *)BKMEM_BASE = 0; // Initialize RTC // Interrupt and reset happen every 1024/32768 * 32 = 1 sec. RTCMOD = 32-1; RTCCTL = RTCSS__XT1CLK | RTCSR | RTCPS__1024 | RTCIE; setDate(2022,7,8); setTime(0x01, 0x53, 0x00, 0x1); // Store P1OUT value in backup memory register before enter LPM3.5 *(unsigned int *)BKMEM_BASE = P1OUT; } // Enter LPM3.5 mode with interrupts enabled. Note that this operation does // not return. The LPM3.5 will exit through a RESET event, resulting in a // re-start of the code. PMMCTL0_H = PMMPW_H; // Open PMM Registers for write PMMCTL0_L |= PMMREGOFF; // and set PMMREGOFF __bis_SR_register(LPM3_bits | GIE); __no_operation(); return 0; } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = RTC_VECTOR __interrupt void RTC_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(RTC_VECTOR))) RTC_ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(RTCIV, RTCIV_RTCIF)) { case RTCIV_NONE : break; // No interrupt pending case RTCIV_RTCIF: // RTC Overflow // Toggle LED on P1.0 //P1OUT ^= BIT0; //print("00:00:01-01/01/2022"); incrementSeconds(); mid_second=(TI_second) / 16*10+(TI_second) % 16; mid_minute=(TI_minute) / 16*10+(TI_minute) % 16; mid_hour=(TI_hour) / 16*10+(TI_hour) % 16; mid_day=(TI_day) / 16*10+(TI_day) % 16; mid_month=(TI_month) / 16*10+(TI_month) % 16+1; mid_year=(TI_year)/4096*1000+(TI_year)/256%16*100+(TI_year)/16%16*10+(TI_year) % 16; //print("00:00:01-01/01/2022"); printNumber(mid_hour); print(":"); printNumber(mid_minute); print(":"); printNumber(mid_second); print("-"); printNumber(mid_day); print("/"); printNumber(mid_month); print("/"); printNumber(mid_year); print("\n"); P1OUT |= BIT0; // Store P1OUT value in backup memory register //*(unsigned int *)BKMEM_BASE = P1OUT; break; default: break; } }
Problem solved, before writing to the uart tx register I was not checking the tx status buffer properly and was not waiting enough before writing another byte of data.
It worked after updating print function like this:
void print(char *text) { unsigned int i = 0; while(text[i] != '\0') { while (UCA0STATW & UCBUSY) ; while (!(UCA0IFG & UCTXIFG)) ; UCA0TXBUF = text[i]; // TX -> Received Char + 1 while (UCA0STATW & UCBUSY) ; i++; } }
it usually suffices to wait (spin) for UCBUSY once, after you exit the while() loop. This will assure the UART internal buffers are clear before you go back to sleep (which turns off the UART clock).
**Attention** This is a public forum