Hello all,
I am experimenting with sending data between two MSP_EXP432 Launchpads using EUSCI A0 as a 2MBaud UART and I'm finding that characters are being missed (Rx interrupt does not fire).
EDIT: I specifically have trouble with SMCLK of 12MHz and a data rate of around 2MBaud. Problem goes away if SMCLK is upped to 24MHz.
I am aware of this forum post but I don't think the issues there apply to my case - I am certain my ISR is fast enough for this job and I'm not seeing any UART error (overflows etc). There are a few other factors that make me wonder if the MSP432 struggles to keep sync in particular configurations.
At this point I am working with an interrupt based implementation. I know a DMA based implementation is better at these rates (indeed I can see that it would be very difficult to get any other work done while dealing with the interrupts), but my understanding is that DMA relies on the interrupt flags so I want to ensure that I understand that foundation before moving on.
[DMA UART Rx also raises a number of other questions - in particular, given that DMAs are of fixed size, how to implement in a way robust to missed/errored characters, but that is for another post].
Here is a CRO capture to illustrate my problem.
The top trace shows the runtime envelope for my EUSCI receive ISR. It runs in just over 3uSec. This is more than fast enough to keep up with 2MBaud (where one char is 5uSec). This runtime can be further reduced with optimization but I choose not since it's not necessary at this point (and it gets in the way of debugging).
The middle trace is the Rx pin of the MSP432. The signal here is nice and square with minimal overshoot etc. I don't think a signal integrity problem is at play here. You can see I'm transmitting a string of 0x00 here. There number of missed characters seems to depend on the data. 0x00 is missed more often than something with more transitions like 0xAA.
The bottom trace shows that my scope is successfully able to decode the data - further evidence that the signal itself isn't too bad.
This next picture is just a close up just to prove the time in ISR is less than the character time.
The problem here is in the top trace. I've sent 32 chars, but the EUSCI interrupt has only fired 7 times (this is an extreme example - most bursts 32chars are received correctly. Sometimes, one or two chars are missed. Occasionally, lots are missed).
There are no UART errors happening here (RxError, Overflow etc). Character are just missed.
[That said, my college did some similar work and he always saw a missed character followed by an overflow error, so characters we always missed in pairs. We can't work out why my result is different to his. Code is very similar. Maybe it is something to do with the MSP432 devices themselves??????]
Now, I've found that I only get missed characters with particular configurations.
Using a 12MHz SMCLK to drive the EUSCI module Baud rate setting between about 1.75MBaud to 2.05MBaud have lots of missed characters. Outside this range the missed character rate falls away.
If I set SMCLK to 24MHz, I never see any missed characters when operating around the 2MBaud mark.
I guess I have given a workaround to my own problem here.
But (a) maybe this will help someone else in a similar situation in the future, (b) perhaps there is a real problem here that TI can take a look at??? and (b) this would have been difficult to debug if I had gone straight for DMA!
For reference, I attach a photo of my physical setup, and the code I used in trying to understand this issue.
//***************************************************************************** // Test and understand high speed (2MBaud) UART operation // Tested with two MSP-EXP432P401R Launchpads (XMS432 RevB silicon) // // Project created using the "Empty Project with DriverLib" template. // Don't forget to put set ISR_EUSCI as the EUSCI_A0 ISR in system_msp432_p401r_ccs.c // DEBUG build with optimization off // Same code can go in both Launchpads provided hardware is setup correctly. See below. // // At 2MBaud, I understand DMA is a better implementation approach! // But DMA still relies on interrupts (interrupt flags). // I want to understand interrupt operation and would appreciate if the // following issues could be explained. // // ISSUE // Top level - At 2MBaud, I find the MSP432 ocassionally fails to receive chars. // More detail - With 12MHz SMCLK, with baud rates around 2MBaud, the MSP432 occasionally fails // to fire the EUSCI ISR for the EUSCI port in use. // The number of failures seems to depend on the data being send with somthing like // "0x00" (few transitions) giving more missed ISRs than something like "0xAA" // (lost of transitions) // Specifically I find baud rates between 1.75MBaud and 2.05MBaud tend to // miss their interrupts regularly. Outside this range, errors are rare. // I notice that if I set SMCLK to 24MHz, then the problem goes away. // // NOTE: In the work I've done here, I've never seen a UART error (no RxError, // Overflow etc). The ISR doesn't fire, then the next char received // is received without problem. // However a collegue doing similar work as seen a pattern of missed // ISR followed by an overflow error. // // ISSUE // I notice that the latest datasheed (SLA826D) ups the maximum fBITCLK value from 3MHz to 7MHz for VCORE1 // Does that perhaps mean this issue might not occur in RevC silicon? // // ISSUE // Ref // It is not clear from the datasheet (SLA826B/D) if there is a relationship between feUSCI(MAX) and fBITCLK(MAX) // If I have VCORE=1 (1.4V) do I need to set SMCLK to 24MHz to be able to acheive the maximum fBITCLK? // // INTERCONNECTION // // LaunchPadA (Rx) LaunchPadB (Tx) // ------------------------- ----------------------- // | | // (Rx - P1.2) JP4.3 |<------------------| JP4.4 (Tx - P1.3) [DATA TRANSFER] // | | // | | // (P3.4) JP4.2 |<------------------| JP4.1 (P3.1) [SYNC] // | | // | | // P6.4 |--| | // Link pins to indicate RX | | | // P5.5 |<-| | // | | // LED1 = UARTErr [RED] | | // LED2 = CountErr [GREEN] | | // P3.6 |-> RxISR [DBG] | // P5.0 |-> UARTErr [DBG] | // P1.7 |-> CountErr [ DBG] | // | | // ------------------------- ----------------------- // // Every CYCLES_BEFORE_TX_STARTS "counts", the Tx end (LaunchPadB) does a "sync" // (toggles P3.1 high for a bit), then bursts out NUM_CHARS_PER_BLOCK characters // (contents of g_tx_data_u8_arr) on the UART Tx. // // - The Tx end is very simple and I don't care much about it's optimization // - The Tx end appears to keep up at 2MBaud without problem. My scope shows that // the Tx output is clean, and the scope is able to decode the Tx data without // problem. // - Load on the processor could be reduced by using DMA. I understand // DMA implementation for UART Tx. // // The Rx end polls its P3.4 (sync) and, if it detects a falling edge it // resets it characters received count in preparation for the next burst. // If a UART error occurs (overflow, Rx Err) the RED LED1 is flashed. // If the number of characters received does does not match the expected, the GREEN LED2 is flashed. // // Debug pins. // P3.6 - Frames the time the ISR is running to receive a character // P5.0 - UART error flag occurred when receiving a character [=LED1] // P1.7 - Did not receive expected number of chars during burst [=LED2 GREEN] // // Note: I use direct register operations rather than driverlib calls in the Rx ISR // because I find that even with optimization very high, driverlib calls are // just too slow to keep up at 2MBaud //**************************************************************************** #include <driverlib.h> #include <stdio.h> #include <string.h> #include <stdbool.h> #include <stdint.h> // software-dl.ti.com/.../index.html //---------------------------------------------------------------------------------------------- // SMCLK 24MHz - 2,100,000Baud - No error //#define SMCLK_DIVIDER CS_CLOCK_DIVIDER_2 // SMCLK = 24MHz //#define CLKPRESCALER 11 //#define FIRSTMODREG 0 //#define SECONDMODREG 4 //#define OVERSAMPLING EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION ////#define OVERSAMPLING EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION // SMCLK 24MHz - 2,000,000Baud - No error //#define SMCLK_DIVIDER CS_CLOCK_DIVIDER_2 // SMCLK = 24MHz //#define CLKPRESCALER 12 //#define FIRSTMODREG 0 //#define SECONDMODREG 0 //#define OVERSAMPLING EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION ////#define OVERSAMPLING EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION // SMCLK 24MHz - 1,800,000Baud - No error //#define SMCLK_DIVIDER CS_CLOCK_DIVIDER_2 // SMCLK = 24MHz //#define CLKPRESCALER 13 //#define FIRSTMODREG 0 //#define SECONDMODREG 2 //#define OVERSAMPLING EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION ////#define OVERSAMPLING EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION //---------------------------------------------------------------------------------------------- // SMCLK 12MHz - 2,050,000Baud - No errs //#define SMCLK_DIVIDER CS_CLOCK_DIVIDER_4 // SMCLK = 12MHz //#define CLKPRESCALER 5 //#define FIRSTMODREG 0 //#define SECONDMODREG 7 //#define OVERSAMPLING EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION ////#define OVERSAMPLING EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION // SMCLK 12MHz - 2,000,000Baud - Errs #define SMCLK_DIVIDER CS_CLOCK_DIVIDER_4 // SMCLK = 12MHz #define CLKPRESCALER 6 #define FIRSTMODREG 0 #define SECONDMODREG 0 #define OVERSAMPLING EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION //#define OVERSAMPLING EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION // SMCLK 12MHz - 1,950,000Baud - Errs //#define SMCLK_DIVIDER CS_CLOCK_DIVIDER_4 // SMCLK = 12MHz //#define CLKPRESCALER 6 //#define FIRSTMODREG 0 //#define SECONDMODREG 1 //#define OVERSAMPLING EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION ////#define OVERSAMPLING EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION // SMCLK 12MHz - 1,900,000Baud - Errs //#define SMCLK_DIVIDER CS_CLOCK_DIVIDER_4 // SMCLK = 12MHz //#define CLKPRESCALER 6 //#define FIRSTMODREG 0 //#define SECONDMODREG 2 //#define OVERSAMPLING EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION ////#define OVERSAMPLING EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION // SMCLK 12MHz - 1,800,000Baud - Errs //#define SMCLK_DIVIDER CS_CLOCK_DIVIDER_4 // SMCLK = 12MHz //#define CLKPRESCALER 6 //#define FIRSTMODREG 0 //#define SECONDMODREG 6 //#define OVERSAMPLING EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION ////#define OVERSAMPLING EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION // SMCLK 12MHz - 1,750,000Baud - Errs //#define SMCLK_DIVIDER CS_CLOCK_DIVIDER_4 // SMCLK = 12MHz //#define CLKPRESCALER 6 //#define FIRSTMODREG 0 //#define SECONDMODREG 7 //#define OVERSAMPLING EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION ////#define OVERSAMPLING EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION // SMCLK 12MHz - 1,700,000Baud - No errs //#define SMCLK_DIVIDER CS_CLOCK_DIVIDER_4 // SMCLK = 12MHz //#define CLKPRESCALER 7 //#define FIRSTMODREG 0 //#define SECONDMODREG 0 //#define OVERSAMPLING EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION ////#define OVERSAMPLING EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION // If you move to a different port, adjust startup_msp432p401r_ccs.c accordingly #define EUSCI_MODULE EUSCI_A0_BASE // All in the following group are set appropriately given EUSCI_MODULE #define EUSCI_INT INT_EUSCIA0 #define EUSCI_TX_PORT GPIO_PORT_P1 #define EUSCI_TX_PIN GPIO_PIN3 #define EUSCI_RX_PORT GPIO_PORT_P1 #define EUSCI_RX_PIN GPIO_PIN2 #define NUM_CHARS_PER_BLOCK 32 // Number of chars to transmit for each Tx block #define CYCLES_BEFORE_TX_STARTS 100000 // Number of times through the main loop before the next Tx block begin. #define CHAR_TO_SEND 0x00 // We use direct reg operations in ISR to speed things up compared to MSPWare calls. #define EUSCI_REG EUSCI_A_CMSIS(EUSCI_MODULE) #define P3_6_HIGH() P3->OUT |= BIT6 #define P5_0_HIGH() P5->OUT |= BIT0 #define P1_7_HIGH() P1->OUT |= BIT7 #define LED1_ON() P1->OUT |= BIT0 #define LED2_RED_ON() P2->OUT |= BIT0 #define LED2_GREEN_ON() P2->OUT |= BIT1 #define LED2_BLUE_ON() P2->OUT |= BIT2 #define P3_6_LOW() P3->OUT &= ~BIT6 #define P5_0_LOW() P5->OUT &= ~BIT0 #define P1_7_LOW() P1->OUT &= ~BIT7 #define LED1_OFF() P1->OUT &= ~BIT0 #define LED2_RED_OFF() P2->OUT &= ~BIT0 #define LED2_GREEN_OFF() P2->OUT &= ~BIT1 #define LED2_BLUE_OFF() P2->OUT &= ~BIT2 volatile uint32_t g_time_count_u32 = 0; const uint8_t g_err_mask_u8 = EUSCI_A_UART_FRAMING_ERROR + EUSCI_A_UART_OVERRUN_ERROR + EUSCI_A_UART_PARITY_ERROR + EUSCI_A_UART_BREAK_DETECT + EUSCI_A_UART_RECEIVE_ERROR; //uint8_t g_tx_data_u8_arr[NUM_CHARS_PER_BLOCK] = "TestingTestingTestingTesting1234"; uint8_t g_tx_data_u8_arr[NUM_CHARS_PER_BLOCK] = {0}; volatile uint8_t g_tx_ind_u8 = 0; volatile uint8_t g_rx_ind_u8 = 0; volatile bool g_I_am_the_rx_board_b = false; //-------------------------------------------------------------- //-------------------------------------------------------------- void ISR_EUSCI(void) { uint8_t flags_u8; uint8_t rx_char_u8; if (g_I_am_the_rx_board_b) { P3_6_HIGH(); // With direct register access, this ISR runs in about 3uSec with all optimization off. // I worry about turning on optimization - I do not want the RXBUF read below to be optimized // away!!! if (EUSCI_REG->IFG & EUSCI_A_UART_RECEIVE_INTERRUPT) { EUSCI_REG->IFG &= ~(EUSCI_A_UART_RECEIVE_INTERRUPT); // Clear Rx interrupt flag flags_u8 = EUSCI_REG->STATW & g_err_mask_u8; rx_char_u8 = EUSCI_REG->RXBUF; if (flags_u8) { P5_0_HIGH(); LED1_ON(); } g_rx_ind_u8++; // datasheet says its possible to get an overrun as we are reading rx register, so read the flags again and clear if required // see 22.3.6 - Automatic Error Detection in eUSCI_A_Operation - Uart Mode flags_u8 = EUSCI_REG->STATW & g_err_mask_u8; if (flags_u8) { P5_0_HIGH(); LED1_ON(); rx_char_u8 = EUSCI_REG->RXBUF; } P5_0_LOW(); } P3_6_LOW(); } else { // Check for Tx interrupt if (MAP_UART_getEnabledInterruptStatus(EUSCI_MODULE) & EUSCI_A_UART_TRANSMIT_INTERRUPT) { // Don't need to clear the Tx flag! That happens on MAP_UART_transmitData(); if (g_tx_ind_u8 < NUM_CHARS_PER_BLOCK-1) { g_tx_ind_u8++; MAP_UART_transmitData(EUSCI_MODULE, g_tx_data_u8_arr[g_tx_ind_u8]); } else { // Done g_time_count_u32 = 0; MAP_UART_disableInterrupt(EUSCI_MODULE, EUSCI_A_UART_TRANSMIT_INTERRUPT); } } } } //-------------------------------------------------------------- //-------------------------------------------------------------- void main(void) { eUSCI_UART_Config uart_config_st; bool current_rts_b = false; bool last_rts_b = false; MAP_WDT_A_holdTimer(); //-------------------------------------------------------------------- // Platofrm specific setup // I_AM_RX_Sense MAP_GPIO_setAsInputPinWithPullDownResistor(GPIO_PORT_P6, GPIO_PIN4); // I_AM_RX_Set MAP_GPIO_setDriveStrengthLow(GPIO_PORT_P5, GPIO_PIN5); MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P5, GPIO_PIN5); MAP_GPIO_setAsOutputPin(GPIO_PORT_P5, GPIO_PIN5); //TP1 MAP_GPIO_setDriveStrengthLow(GPIO_PORT_P3, GPIO_PIN6); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN6); MAP_GPIO_setAsOutputPin(GPIO_PORT_P3, GPIO_PIN6); //TP2 MAP_GPIO_setDriveStrengthLow(GPIO_PORT_P5, GPIO_PIN2); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P5, GPIO_PIN2); MAP_GPIO_setAsOutputPin(GPIO_PORT_P5, GPIO_PIN2); //TP3 MAP_GPIO_setDriveStrengthLow(GPIO_PORT_P5, GPIO_PIN0); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P5, GPIO_PIN0); MAP_GPIO_setAsOutputPin(GPIO_PORT_P5, GPIO_PIN0); //TP4 MAP_GPIO_setDriveStrengthLow(GPIO_PORT_P1, GPIO_PIN7); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN7); MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN7); //LED1 MAP_GPIO_setDriveStrengthLow(GPIO_PORT_P1, GPIO_PIN0); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0); MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0); //LED2RED MAP_GPIO_setDriveStrengthLow(GPIO_PORT_P2, GPIO_PIN0); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN0); MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN0); //LED2GREEN MAP_GPIO_setDriveStrengthLow(GPIO_PORT_P2, GPIO_PIN1); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN1); MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN1); //LED2BLUE MAP_GPIO_setDriveStrengthLow(GPIO_PORT_P2, GPIO_PIN2); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN2); MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN2); // RTS Output MAP_GPIO_setDriveStrengthLow(GPIO_PORT_P3, GPIO_PIN1); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN1); MAP_GPIO_setAsOutputPin(GPIO_PORT_P3, GPIO_PIN1); // CTS Input MAP_GPIO_setAsInputPin(GPIO_PORT_P3, GPIO_PIN4); //-------------------------------------------------------------------- // Clock setup MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_PJ, GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION); // HFXIn MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ, GPIO_PIN2, GPIO_PRIMARY_MODULE_FUNCTION); // HFXOut MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_PJ, GPIO_PIN0, GPIO_PRIMARY_MODULE_FUNCTION); // LFXIn MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ, GPIO_PIN1, GPIO_PRIMARY_MODULE_FUNCTION); // LFXOut MAP_CS_setExternalClockSourceFrequency(32768, 48000000); // Start up the oscillators MAP_CS_startHFXT(false); MAP_CS_startLFXT(false); // Clock source settings MAP_CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1); // 48MHz MAP_CS_initClockSignal(CS_HSMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_2); // 24MHz MAP_CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, SMCLK_DIVIDER); MAP_CS_initClockSignal(CS_ACLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1); // 32768Hz MAP_CS_initClockSignal(CS_BCLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1); // 32768Hz - Divider setting is ignored for BCLK //-------------------------------------------------------------------- // Power setup MAP_PCM_setPowerMode(PCM_DCDC_MODE); MAP_PCM_setCoreVoltageLevel(PCM_VCORE1); // Vcore must be 1.4V to operate at over 1MBaud (up to 3MBaud) MAP_FlashCtl_setWaitState(FLASH_BANK0, 2); MAP_FlashCtl_setWaitState(FLASH_BANK1, 2); //-------------------------------------------------------------------- // Data and direction setup g_I_am_the_rx_board_b = MAP_GPIO_getInputPinValue(GPIO_PORT_P6, GPIO_PIN4); memset(g_tx_data_u8_arr, CHAR_TO_SEND, NUM_CHARS_PER_BLOCK); //-------------------------------------------------------------------- // UART Setup MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(EUSCI_TX_PORT, EUSCI_TX_PIN, GPIO_PRIMARY_MODULE_FUNCTION); MAP_GPIO_setAsPeripheralModuleFunctionInputPin(EUSCI_RX_PORT, EUSCI_RX_PIN, GPIO_PRIMARY_MODULE_FUNCTION); uart_config_st.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK, uart_config_st.clockPrescalar = CLKPRESCALER, // =BRDIV uart_config_st.firstModReg = FIRSTMODREG, // =UCxBFR uart_config_st.secondModReg = SECONDMODREG, // =UCxBRS uart_config_st.parity = EUSCI_A_UART_NO_PARITY, uart_config_st.msborLsbFirst = EUSCI_A_UART_LSB_FIRST, uart_config_st.numberofStopBits = EUSCI_A_UART_ONE_STOP_BIT, uart_config_st.uartMode = EUSCI_A_UART_MODE, uart_config_st.overSampling = OVERSAMPLING, MAP_UART_initModule(EUSCI_MODULE, &uart_config_st); MAP_UART_enableModule(EUSCI_MODULE); // Ensure Tx reg is available while(!MAP_UART_getInterruptStatus(EUSCI_MODULE, EUSCI_A_UART_TRANSMIT_INTERRUPT)) {}; // Enable interrupts MAP_Interrupt_setPriority(EUSCI_INT, (1 & 0x7) << 5); if (g_I_am_the_rx_board_b) { // Rx interrupt always runs on the Rx board, never on the Tx board MAP_UART_enableInterrupt(EUSCI_MODULE, EUSCI_A_UART_RECEIVE_INTERRUPT); } MAP_Interrupt_enableInterrupt(EUSCI_INT); if (g_I_am_the_rx_board_b) { printf("Starting - Rx module\n"); } else { printf("Starting - Tx module\n"); } //-------------------------------------------------------------------- while(1) { g_time_count_u32++; if (g_I_am_the_rx_board_b) { // Rx board // Watch for falling edge of RTS to clear stats // All receive action happens in the ISR if (g_time_count_u32 % 10 == 0) { last_rts_b = current_rts_b; current_rts_b = MAP_GPIO_getInputPinValue(GPIO_PORT_P3, GPIO_PIN4); if (last_rts_b & !current_rts_b) { LED1_OFF(); LED2_GREEN_OFF(); // Last char count did not match the block size. if (g_rx_ind_u8 != NUM_CHARS_PER_BLOCK) { P1_7_HIGH(); LED2_GREEN_ON(); } // Now setup for the next block g_rx_ind_u8 = 0; } P1_7_LOW(); } } else { // Tx board if (g_time_count_u32 == CYCLES_BEFORE_TX_STARTS) { MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN1); } else if (g_time_count_u32 == CYCLES_BEFORE_TX_STARTS+50) { MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN1); } else if (g_time_count_u32 == CYCLES_BEFORE_TX_STARTS+70) { // Kick off the transmission by sending first char. ISR will take care of the rest g_tx_ind_u8 = 0; MAP_UART_clearInterruptFlag(EUSCI_MODULE, EUSCI_A_UART_TRANSMIT_INTERRUPT); MAP_UART_enableInterrupt(EUSCI_MODULE, EUSCI_A_UART_TRANSMIT_INTERRUPT); MAP_UART_transmitData(EUSCI_MODULE, g_tx_data_u8_arr[0]); } } } }