Hello,
I am experiencing problems with the data transfer between host PC and MSP432 launchpad (MSP-EXP432P401R).
On the launchpad I have configured UART port on "EUSCI_A0_MODULE" module. The launchpad runs the program which receives a 16-bytes of data over the UART port from the host PC. The UART data reception is handled in an ISR function associated with EUSCI_A_UART_RECEIVE_INTERRUPT. The data is saved in a 16-byte long buffer. When the buffer is full, the data is sent to the host over the UART. This cycle is repeated over and over again. The program on the host PC (running Ubuntu 14.10) sends 16-byte long data block over "Application/User UART COM port" of the launchpad, and then waits until the 16-byte block is received back from the launchpad.
Here is the program that I run on the launchpad, where UART baudrate is :
const eUSCI_UART_Config uartConfig = { EUSCI_A_UART_CLOCKSOURCE_SMCLK, // SMCLK Clock Source 12, // BRDIV = 12 0, // UCxBRF = 0 0, // UCxBRS = 0 EUSCI_A_UART_NO_PARITY, // No Parity EUSCI_A_UART_LSB_FIRST, // LSB First EUSCI_A_UART_ONE_STOP_BIT, // One stop bit EUSCI_A_UART_MODE, // UART mode EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION // No-Oversampling }; #define BUFF_SIZE 16 static volatile uint8_t buff[BUFF_SIZE]; static volatile uint32_t buff_indx_filling = 0; static volatile uint32_t buff_indx_emptying = 0; static volatile bool buff_is_empty = true; // true: empty, false: full static volatile uint32_t timerPeriod; void ConfigSTimer(void); int main(void) { /* Halting WDT */ MAP_WDT_A_holdTimer(); /* Selecting P1.2 and P1.3 in UART mode and P1.0 as output (LED) */ MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION); MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0); MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN0); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN0); MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN1); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN1); /* Setting DCO to 48MHz (upping Vcore) */ MAP_PCM_setCoreVoltageLevel(PCM_VCORE1); CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48); /* Configuring UART Module */ MAP_UART_initModule(EUSCI_A0_MODULE, &uartConfig); /* Enable UART module */ MAP_UART_enableModule(EUSCI_A0_MODULE); /* Enabling interrupts */ MAP_UART_enableInterrupt(EUSCI_A0_MODULE, EUSCI_A_UART_RECEIVE_INTERRUPT); MAP_Interrupt_enableInterrupt(INT_EUSCIA0); /*configure timer*/ ConfigSTimer(); MAP_Interrupt_enableSleepOnIsrExit(); MAP_PCM_gotoLPM0(); __no_operation(); } /* EUSCI A0 UART ISR - received data from PC host */ void euscia0_isr(void) { uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_MODULE); MAP_UART_clearInterruptFlag(EUSCI_A0_MODULE, status); if(status & EUSCI_A_UART_RECEIVE_INTERRUPT) { if (buff_is_empty == true) { buff[buff_indx_filling++] = MAP_UART_receiveData(EUSCI_A0_MODULE); if (buff_indx_filling == BUFF_SIZE) { buff_is_empty = false; buff_indx_filling = 0; MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0); MAP_Timer32_enableInterrupt(TIMER32_0_MODULE); MAP_Timer32_setCount(TIMER32_0_MODULE, timerPeriod); MAP_Timer32_startTimer(TIMER32_0_MODULE, false); } } } } /* TIMER32_0 ISR - echoes data back to PC host */ void timer0_isr(void) { MAP_Timer32_clearInterruptFlag(TIMER32_0_MODULE); if (buff_is_empty == false) { MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P2, GPIO_PIN0); while (buff_indx_emptying<BUFF_SIZE) { MAP_UART_transmitData(EUSCI_A0_MODULE, buff[buff_indx_emptying++]); } buff_is_empty = true; buff_indx_emptying = 0; MAP_Timer32_haltTimer(TIMER32_0_MODULE); MAP_Timer32_disableInterrupt(TIMER32_0_MODULE); } } void ConfigSTimer(void) { MAP_Timer32_initModule(TIMER32_0_MODULE, TIMER32_PRESCALER_1, TIMER32_32BIT, TIMER32_PERIODIC_MODE); MAP_Interrupt_setPriority(INT_T32_INT1, zINT_PRIORITY_LEVEL_0); MAP_Interrupt_enableInterrupt(INT_T32_INT1); timerPeriod = (uint32_t)(0.01*((double)MAP_CS_getMCLK())); }
The data transfer works fine as long as the UART port baudrate is <=1500000. For each transmission cycle, the host successfully transmits 16-byte long data block, and receives back the same block. However, when I set the baudrate to 2000000 or 4000000, the uC seems to miss some of the bytes from the data block transmitted from the host. In this case, the host does not receive any data from the uC, since the 'buff' does not fill up. When the baudrate is 4000000, I have to transmit 20-bytes from the host, then the uC receives only 16-bytes that fills the 'buff', and the uC echoes back the 'buff' to the host. So in this case, it appears that uC does not receive 4 bytes out of 16 bytes.
While transmitting the 16-byte data block from the host, if I observer the signal on uC 'RXD' pin of the UART port as shown here
it appears all 16-bytes are passed from the launchpad emulator section to the uC UART, as shown in the following oscilloscope screen shot:
Can someone explain why the uC does not receive all 16-bytes. The missing of data bytes is observed at lower baudrates if I add additional instructions within the ISR routine associated with the UART port and the echo-back function. Similarly, for a given baudrate, e.g., 4000000, more bytes are missed if more instructions are added in these functions.