Hello forum,
My project consists of having a number of robots communicating among each other and saving the received data on to an SD Card. The robot needs to keep its "ears open" meaning, I need to allow interrupts on one of the UART's RX while at same time keeping count of my "clock" through a Timer_A interrupt. The Timer_A interrupt simply increases a variable every second using a 37, 628Hz crystal as my ACLK source. After receiving data, the robot saves the it on to the SD card via the second UART of the MSP430FR5739. The problem I have is that if I ran the Timer_A interrupt, the UART's RX almost never receives data even though I know I'm sending data.
How can I allow the "interbot" driven UART's RX continuously listen to other robots and at the same time keep my time?
Below part of the code I'm working on.
/*
* main.c
*/
#include "msp430fr5739.h"
#include "common_functions.h"
#include "common_variables.h"
#include <stdio.h>
#include <stdlib.h>
void genPacket(void);
void txPacket(char *buffer);
void parsePacket(void);
void broadCast(void);
void savingToSdCard(void);
int sec = 0;
int min = 0;
int hrs = 0;
int initCorrect = 0;
char buff[28] = "@@@@@@@@@@@@@@@@@@@@@@@@@@@@";
int keepCounting = 1;
void main(void) {
initClocks();
initUARTSdCard();
initUARTBot();
initLEDs();
initLEDWait(); // Sleep for 5 sec: 5*8MHz.
initUartBuffer();
_EINT();
initCorrect = 1;
setupTimer();
OperationMode = Counting;
while(initCorrect){
switch (OperationMode) {
case Broadcasting:
broadCast();
break;
case Saving:
savingToSdCard();
break;
case Counting:
keepCounting = 1; // Allow timer interruption.
__bis_SR_register(LPM3_bits + GIE);
break;
default:
OperationMode = Counting;
break;
}
}
}
void genPacket(void)
{
// generates the packet to be sent
}
void txPacket(char *buffer)
{
//Sends packet through dedicated "inter-bot" UART
}
void parsePacket(void)
{
// Parses received packet through dedicated "inter-bot" UART
}
void broadCast(void)
{
genPacket();
txPacket(buff);
OperationMode = Counting;
}
void savingToSdCard(void) // Saves received data on to SD card and operates on the packet
{
turnSdCard(ON);
writeDataToSDFile("append myData.txt", uartBuffer, 1);
turnSdCard(OFF);
parsePacket();
OperationMode = Counting;
}
// Receives data from other robots
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
switch(__even_in_range(UCA0IV,0x08)) // Tells the compiler that UCAxIV can take only even values up to 0x08 to make a more efficient jump table
{
case 0:break; // Vector 0 - no interrupt
case 2: // Vector 2 - RXIFG
keepCounting = 0;
if (!pcktStartFlagBot && UCA0RXBUF == START_BYTE) {
pcktStartFlagBot = 1;
dataLength = 0;
}
else if (pcktStartFlagBot && UCA0RXBUF != END_BYTE) {
uartBuffer[dataLength] = UCA0RXBUF;
dataLength++;
}
else if (pcktStartFlagBot && UCA0RXBUF == END_BYTE) {
pcktStartFlagBot = 0; //Reset framing
OperationMode = Saving; //Set flag to operate on received data package
}
break;
case 4:break; // Vector 4 - TXIFG
default: break;
}
//__bic_SR_register_on_exit(LPM3_bits+GIE); // Restores active mode on return
}
// Receives data from the SD card
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
{
switch(__even_in_range(UCA1IV,0x08))
{
case 0:break; // Vector 0 - no interrupt
case 2: // Vector 2 - RXIFG
byteRX_SD = UCA1RXBUF; // Store RXed character
if (!pcktStartFlagSD && byteRX_SD == START_BYTE) {
pcktStartFlagSD = 1;
dataLength = 0;
}
else if (pcktStartFlagSD && byteRX_SD != END_BYTE) {
uartBuffer[dataLength] = byteRX_SD;
dataLength++;
}
else if (pcktStartFlagSD && byteRX_SD == END_BYTE) {
pcktStartFlagSD = 0;
}
break;
case 4:break; // Vector 4 - TXIFG
default: break;
}
//__bic_SR_register_on_exit(LPM3_bits+GIE); // Restores active mode on return
}
// After 37628 ticks, it increases the second counter
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0(void)
{
if (keepCounting) {
sec++;
if (sec == 59) { sec = 0; min ++; }
if ((sec % 10) == 0) {
OperationMode = Broadcasting; // Set flag to operate on received data package
}
if (min == 59) { min = 0; hrs++; }
if (hrs == 23) { hrs = 0; }
blinkLED4(1);
}
__bic_SR_register_on_exit(LPM3_bits+GIE); // Restores active mode on return
}
///>>>Included in common_functions.h<<<<//
void initClocks(void)
{
WDTCTL = WDTPW + WDTHOLD; // stop watchdog
// XT1 Setup
PJSEL0 |= BIT4 + BIT5;
CSCTL0_H = 0xA5;
CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting: 8MHz, DCOSEL = 0 if 1, then DCO = 24MHz
CSCTL2 = SELA_0 + SELS_3 + SELM_3; // set ACLK = XT1; MCLK = DCO
CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // set all dividers
CSCTL4 |= XT1DRIVE_0;
CSCTL4 &= ~XT1OFF;
do
{
CSCTL5 &= ~XT1OFFG;
// Clear XT1 fault flag
SFRIFG1 &= ~OFIFG;
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
}
void initUARTBot(void)
{
// Configure UART 0
UCA0CTL1 |= UCSWRST;
UCA0CTL1 = UCSSEL_2; // Set SMCLK = 8MHz as UCBRCLK
UCA0BR0 = 52; // (8000000Hz / 9600bps) / 16 = 52.083
UCA0BR1 = 0;
// OS16 enabled because we are using SMCLK @ 8MHz High Freq.
// 52.083-52 = 0.083 *16 = 1.33
// UCBRSx value 0.3335= 0x42 (See UG)
UCA0MCTLW = 0x4911 ; // UCBRFx = 1, UCBRSx = 0x49, UCOS16 = 1 (Refer User Guide)
UCA0CTL1 &= ~UCSWRST; // Release from reset
// Configure UART pins
P2SEL1 |= UART_RXBot + UART_TXBot;
P2SEL0 &= ~(UART_RXBot + UART_TXBot);
UCA0IE |= UCRXIE; // Enable RX interrupt
}
void initUARTSdCard(void)
{
// Configure UART 1
UCA1CTL1 |= UCSWRST;
UCA1CTL1 = UCSSEL_2; // Set SMCLK = 8MHz as UCBRCLK
UCA1BR0 = 52; // (8000000Hz / 9600bps) / 16 = 52.083
UCA1BR1 = 0;
// OS16 enabled because we are using SMCLK @ 8MHz High Freq.
// 52.083-52 = 0.083 *16 = 1.33
// UCBRSx value 0.3335= 0x42 (See UG)
UCA1MCTLW = 0x4911 ; // UCBRFx = 1, UCBRSx = 0x49, UCOS16 = 1 (Refer User Guide)
UCA1CTL1 &= ~UCSWRST; // Release from reset
// Configure UART pins
P2SEL1 |= UART_RXSd + UART_TXSd;
P2SEL0 &= ~(UART_RXSd + UART_TXSd);
UCA1IE |= UCRXIE; // Enable RX interrupt
}
void setupTimer(void)
{
TA0CCTL0 = CCIE; // Enable clock interrupt
TA0CCR0 = 32768-1; // Count from 0-32767
TA0CTL = TASSEL_1 + MC_1 + TACLR; // + TAIE; // Start Timer from ACLK(XTAL@32.768kHZ), Up Mode, clear
}