Part Number:MSP432P401R
Every once in a great while, my code will get stuck when trying to transmit data over UART on A0 (hooked into my SIMCOM 868 GPS module).
It gets stuck on the while loop in the driverlib function. I am not entirely sure why it gets stuck or what the while loop is looking for.
What does this code do? How can I gracefully recover from this fault, without using a watchdog timer? Can I re-write this code to use my own timeout function?
The driverlib function looks like this:
void UART_transmitData(uint32_t moduleInstance, uint_fast8_t transmitData)
{
/* If interrupts are not used, poll for flags */
if (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->rIE.r, UCTXIE_OFS))
while (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->rIFG.r, UCTXIFG_OFS))
;
EUSCI_A_CMSIS(moduleInstance)->rTXBUF.r = transmitData;
}
I am communicating with the GPS that sends out a transmission every 0.1 seconds. It sends them out at 115200bps, With about 100-200 characters per transmission.
My code attempts to send the GPS a control command. It normally works but about 1% of the time it gets hung up, for no reason that I can reasonably discern.
UPDATE:
Here is the code to setup the UART:
void UART_Init(int module){
SetupTimers();
if(module == EUSCI_A0_BASE){
// Setup UART A0
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN2 |
GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig0); //Add config to UART Module
MAP_UART_enableModule(EUSCI_A0_BASE); //Enable the UART Module
MAP_Interrupt_enableInterrupt(INT_EUSCIA0); //enable the interrupt
MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
}
}
The UART configuration:
const eUSCI_UART_Config uartConfig0 =
{
EUSCI_A_UART_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
4,//52, // BRDIV
5,//1, // UCxBRF
0x55,//0x49, // UCxBRS
EUSCI_A_UART_NO_PARITY, // No Parity
EUSCI_A_UART_LSB_FIRST, // MSB First
EUSCI_A_UART_ONE_STOP_BIT, // One stop bit
EUSCI_A_UART_MODE, // UART mode
EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION // Oversampling
};
And, the configuration of the system clocks:
// Configure clocks
/* Configuring pins for peripheral/crystal usage and LED for output */
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,
GPIO_PIN0 | GPIO_PIN1, GPIO_PRIMARY_MODULE_FUNCTION);
/* 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(32768, 25000000);
/* Starting LFXT in non-bypass mode without a timeout. */
CS_startLFXT(CS_LFXT_DRIVE3);
MAP_CS_setDCOFrequency(CLK_FQ); // Setting DCO (clock) to the specified clock speed
MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1); // Tie SMCLK to DCO
MAP_CS_initClockSignal (CS_ACLK, CS_VLOCLK_SELECT, CS_CLOCK_DIVIDER_1); // Tie ACLK to VLO