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.

UART example with BREAK input?



Can someone help me with a working example of c code to recognize a UART BREAK on the MSP432?

Thanks, JimS

  • 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