Can someone help me with a working example of c code to recognize a UART BREAK on the MSP432?
Thanks, JimS
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.
The TRM says:
When UCBRKIE = 1, a break condition sets the UCBRK bit and the UCRXIFG flag.
So set the IE bit, and check for the break when receiving a character:
EUSCI_A0->CTLW0 |= EUSCI_A_CTLW0_BRKIE;
...
void usci_a_interrupt(void)
{
switch (EUSCI_A0->IV) {
...
case 2: // RXIFG
if (EUSCI_A0->STATW & EUSCI_A_STATW_BRK) {
received = EUSCI_A0->RXBUF; // always zero
// handle break
} else {
received = EUSCI_A0->RXBUF;
// handle received byte
}
break;
...
}
}Clemens,
Thanks for your quick response. I was already doing as you suggested, but I had not enabled the break interrupt. It didn't make any difference, however. When I issue a BREAK from TeraTerm, (with or without the break interrupt enabled, nothing happens until I send another char from TeraTerm. Remember, this is for the MSP432. Here's my UART ISR code (I haven't been able to make it come our with the line-numbered, syntax highlighting like your code snippit);:
void EUSCIA0_IRQHandler(void) { uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE); MAP_UART_clearInterruptFlag(EUSCI_A0_BASE, status); //----- UART0 RX interrupt service routine ------------------------------------ if(status & EUSCI_A_UART_RECEIVE_INTERRUPT) { // Check for BREAK here? if(EUSCI_A0->STATW & EUSCI_A_STATW_BRK) { temp = MAP_UART_receiveData(EUSCI_A0_BASE); __no_operation(); // for debugger // handle break flags |= (BRK_flag); } else { temp = MAP_UART_receiveData(EUSCI_A0_BASE); // handle received byte if((temp == 'u') && (i_nxtfree == nxt_cmd)){ // if 'u' is first char flags |= (Hello_flag); // flag to print "Hello..." } else if((temp == 'h') && (i_nxtfree == nxt_cmd)){ // if 'h' is first char flags |= (Help_flag); // flag to print signon msg } else if(temp == 0x1B){ // ESC received? flags |= (ESC_flag); } else if(temp == 0x0D){ // Carriage Return? flags |= (CR_flag); } else if(temp == '!'){ // End-of-command input ('!')? flags |= (CMD_flag); } } } if(flags){ // comes here if any of the flags are set by the received char cur_cmd = nxt_cmd; // cur_cmd is start of completed CMD inbuf[i_nxtfree] = NULL; // ..and put a NULL in start of nxt_cmd __no_operation(); // for debugger nxt_cmd = i_nxtfree; // nxt_cmd start of next (uncompleted) command __low_power_mode_off_on_exit(); }else if((temp > 0x1F) && (temp < 0x7F)){ // if received printable char inbuf[i_nxtfree++] = temp; // put received char into inbuf i_nxtfree &= (INBUFSIZ - 1); // wrap i_nxtfree if necessary inbuf[i_nxtfree] = '\0'; // Mark end of current command uart_putc(temp); // echo the input char // if we overrun inbuf, increment the nxt_cmd index if(i_nxtfree == nxt_cmd) nxt_cmd = (++nxt_cmd & (INBUFSIZ-1)); } // end of if(temp is printable_char) } // End EUSCIA0_IRQHandler
In theory, UCBRK should not be reset until RXBUF is actually read. Your code already does what is recommended in section 22.3.6 of the TRM:
After a character is received and UCAxRXIFG is set, first read UCAxSTATW to check the error flags including the overflow flag UCOE. Read UCAxRXBUF next. This clears all error flags except UCOE […]
But why are you explicitly clearing the interrupt flags?
Clemens Ladisch said:But why are you explicitly clearing the interrupt flags?
I used a TI example for the MSP432: uart_pc_echo_12mhz_brclk.
If anyone is interested in what I did to get BREAK recognition working on the MSP432, here is the body of that referenced file (above) with my changes:
/* DriverLib Includes */ #include "driverlib.h" /* Standard Includes */ #include <stdint.h> #include <stdbool.h> /* forward referencce */ void uart_putc( uint8_t c ); void uart_puts( const char *s ); /* Globals */ bool BRK_flag = false; /* UART Configuration Parameter. These are the configuration parameters to * make the eUSCI A UART module to operate with a 9600 baud rate. These * values were calculated using the online calculator that TI provides * at: *software-dl.ti.com/.../index.html */ const eUSCI_UART_Config uartConfig = { EUSCI_A_UART_CLOCKSOURCE_SMCLK, // SMCLK Clock Source 78, // BRDIV = 78 2, // UCxBRF = 2 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_OVERSAMPLING_BAUDRATE_GENERATION // Oversampling }; int main(void) { /* Halting WDT */ MAP_WDT_A_holdTimer(); /* Selecting P1.2 and P1.3 in UART mode */ MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN1 | GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION); /* Setting DCO to 12MHz */ CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12); /* Configuring UART Module */ MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig); /* Enable UART module */ MAP_UART_enableModule(EUSCI_A0_BASE); /* Enabling interrupts */ MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT | EUSCI_A_UART_BREAKCHAR_INTERRUPT); MAP_Interrupt_enableInterrupt(INT_EUSCIA0); MAP_Interrupt_enableSleepOnIsrExit(); MAP_Interrupt_enableMaster(); while(1) { if(BRK_flag) { BRK_flag = 0; uart_puts("\r\n<BRK>\r\n"); } MAP_Interrupt_enableSleepOnIsrExit(); MAP_PCM_gotoLPM0(); } } /* EUSCI A0 UART ISR - Echoes data back to PC host */ void EUSCIA0_IRQHandler(void) { uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE); MAP_UART_clearInterruptFlag(EUSCI_A0_BASE, status); if(status & EUSCI_A_UART_RECEIVE_INTERRUPT) { if(EUSCI_A0->STATW & EUSCI_A_STATW_BRK) { // handle BRK BRK_flag = true; MAP_UART_receiveData(EUSCI_A0_BASE); // read and discard the rcv'd char MAP_Interrupt_disableSleepOnIsrExit(); // allow main() to handle BRK return; } MAP_UART_transmitData(EUSCI_A0_BASE, MAP_UART_receiveData(EUSCI_A0_BASE)); } } //----- UART_PUTC ------------------------------------------------------------- void uart_putc( uint8_t c ) { while(!MAP_UART_getInterruptStatus(EUSCI_A0_BASE, EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG)); // Wait for xmit buffer ready UART_transmitData(EUSCI_A0_BASE, c); // Transmit the byte } // End UART_PUTC //----- UART_PUTS ------------------------------------------------------------- void uart_puts( const char *s ) { while ( *s != '\0') { uart_putc( (uint8_t)*(s++) ); } } // End UART_PUTS /*****************************************************************************/
**Attention** This is a public forum