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.

MSP430G2453 Reset Upon UART Write

Other Parts Discussed in Thread: MSP430G2453

I am using a MSP430G2453. The device resets (on the first write) when I write to the TX register on the comm port. The port is configured as a UART.

I am using this device on a number of products in development and this shows up intermittently. However, there is one board that this occurs every time on the first byte write to the port.

Appreciate any ideas.

  • This could happen if UART TX interrupt is enabled but there is no ISR function. Easiest way to test this: add TX ISR function code with some debug LED blink trap in it.
  • The first byte is transmitted out of the port. The microcontroller gets rest after that.

  • Is TX interupt enabled though you don't have a ISR for it?

    is RX interrupt enabled though you don't use RX, but the pin is floating and random bytes comes in triggering a RX interrupt.

    PCB design don't have enough capacitors to protect against brownout?
    PCB design don't have 47K pull-up and 1nF cap on reset line?
    UART connects with wires and cables that are bad and shorting out the board.

  • Hi Tony,

    I have ISR for both TX and RX and each line is connected with traces on the PCB.
    I have increased the filter cap values on the input and output of the regulator and the reset circuitry is pretty much as you have described.

    I have a string of 27 bytes that I am trying to send out the port. The microcontroller resets after the first byte is transmitted.
  • >The microcontroller resets after the first byte is transmitted.
    Did you try to debug TX ISR routine by putting breakpoint here? It could be some software bug which causes endless loop. Could you share code of TX ISR?
  • Here is the function the ISR calls.
    I have set a break point at the "++commTXBuffPtr;" statement. I have a string of 27 bytes to transmit. if I run the program to the break point the byte is output to the port. Restart it and run to the break point again and the next byte is transmitted.

    The device resets when running real time and only the first byte is transmitted.

    // Serial data transmit
    void SUREProCordSerialTX()
    {
    int i;

    while( commCTS == FALSE) // Wait for XBee CTS to clear
    {
    }
    if((commTXBuff[commTXBuffPtr] != 0x00 && commATISet == TRUE) ||
    (commTXBuff[0] == 0x7E && commTXBuffPtr != commMaxTXBufferNum + 1))
    {
    UCA0TXBUF = commTXBuff[commTXBuffPtr];
    ++commTXBuffPtr;
    }

    if(commTXBuffPtr == commMaxTXBufferNum + 1)
    {
    for(i = 0; i <XBEE_MAX_TX_BUFF_BYTES; ++i)
    {
    commTXBuff[i] = 0; // Clear the TX buffer
    }
    IFG2 &= ~(UCA0TXIFG); // Clear the interrupt flag
    commTXBuffEmpty = TRUE; // Set the TX buffer empty flag
    commTXBuffPtr = 0; // Reset the buffer pointer
    commMaxTXBufferNum = 0; // Reset the buffer number
    timerXBeeSleepCtr = TIMER_FACTOR_600MSEC;
    commXBeeInit = FALSE;
    }
    }
  • Never put a while{} inside a ISR, you're blocking all other ISR while it's stuck in the while-loop.
    Though it may be a short pause, It's never a good practice to use while (rely on external forces) {}
    as if a bug happens it's a fatal crash to the system.

    A TX-ISR only job is to move next byte to the UART hardware buffer, subtract a counter and stop sending bytes if limit reached.
    When done sending all bytes it could set a flag and wake up main.c, so the "state-machine" running in main knows who woke it up.

  • Tony Philipsson said:
    Never put a while{} inside a ISR

    Right. Stuck CPU waiting for connected serial device to release CTS is worst thing you can do in ISR. You are advised to comment out this CTS-checking loop for debug purposes, especially while you are not sure that UART communications work at all.

    p.s. I am not sure that you are showing TX ISR!

    It shall look like:

    // USCI A0/B0 Transmit ISR
    #pragma vector=USCIAB0TX_VECTOR
    __interrupt void USCI0TX_ISR(void)
    {
      // ISR code here
    }

  • I sent the function the ISR called. Here is the ISR

    // UART interrupt service routine
    #pragma vector=USCIAB0TX_VECTOR
    __interrupt void USCI0TX_ISR(void)
    {
    IFG2 &= ~(UCA0TXIFG); // Clear the interrupt flag
    SUREProCordSerialTX(); // Send the byte
    }
  • Should not be using function-calls inside ISR's, as ISR need to be short and you don't want to loose track how big it's getting by jumping.
    And you don't want to waste cycles by putting more stuff on the stack that these calls create.

    Though a compiler in optimize: high would probably inline this function anyway.

    You don't have to clear the IFG flag, a new write to the txbuff will clear it.
    If it's the last byte to send, you could disable TXIE so it will not return and the IFG flag will be on hold.
    And when a new string is ready to be sent, reset the pointers and length and enable TXIE to start it off again.

  • I placed the function that was called from the ISR into the ISR. No change. The device still outputs on character then resets.

  • How do you know it resets, did you put a breakpoint at the second line in main.c?
    and after the initial hit do you see a hit again?

    Do you use a while(1) that is surrounding your main code that follows the regular initiation routine?
    C doesn't take for granted that you want to run your code forever.

    There is no hardware bug, it's your code.
  • Yes to both the break point and while(1) questions.
    The problem with my code is what I am trying to determine. The same code works on a MSPF5510 device.

**Attention** This is a public forum