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.

MSP430f5336 parity error detection issue

Other Parts Discussed in Thread: MSP430F5336, MSP430F5529

HI

I have setup the UART0 on MSP430f5336 for 1200 baud rate , parity enable,odd parity detection and URXEIE ENABLE. I use assembly language on IAR tool chain for my project .

I need to detect parity error on each byte while receiving a packet , byte framing is one start bit , 8 data bits , one parity bit and one stop bit .

I receive byte through rx interrupt and in the interrupt I store the UCASTAT for current byte received and then the rx buffer . 

If I send one byte with an even parity to create parity error , I am able catch parity error in status for that byte . But if i send two continuous byte, First one with incorrect parity and second with correct parity , I can't see error being flag by the status. 

For a longer packet as well I am unable to catch the correct status fro respective byte

Please let me know if there is a solution available to above stated problem

 

 

  • Hi Vivek!

    Just a quick shot: Do you poll the UCPE error flag in every receive interrupt? If you first send your erroneous one, the flag might get set, but when the correct byte is received after that, the flag might get cleared again. This is just a guess - I cannot look it up at the moment. If I remember correctly, an erroneous received byte is not transferred into the RX buffer if you do not set the UCRXEIE bit in UCAxCTL1. Do you have the erroneous receive interrupt enable (UCRXEIE) set? Otherwise the MSP might discard the byte and the receive interrupt only occurs for an incoming correct byte. And if you then poll the error flag, this flag status is based on the good byte, not the previous bad one.

    Dennis

  • Vivek Kataria said:

    I need to detect parity error on each byte while receiving a packet , ... I receive byte through rx interrupt and in the interrupt I store the UCASTAT for current byte received and then the rx buffer . 

    Did you set the UCRXEIE bit in the UCAxCTL1 register? When there is a parity error, is the byte in RXBUF correct? Wrong? Or, is actually the next correctly transmitted byte.

    Vivek Kataria said:
    If I send one byte with an even parity to create parity error , I am able catch parity error in status for that byte . But if i send two continuous byte, First one with incorrect parity and second with correct parity , I can't see error being flag by the status. 

    What is sending those bytes? Is it from the same UART on the same chip that is receiving them? From a different UART on the same chip? Or from a different chip?

    How did you manage to change parity setting in the middle of "two continuous byte"? Don't you need to stop the UART to change parity? Did you wait until the transmission of the previous byte is completely shifted out of the UART hardware before you stop the UART for parity change? 

    Vivek Kataria said:
    For a longer packet as well I am unable to catch the correct status fro respective byte

    But did you catch the correct number of bytes (given that one or more of them have incorrect value)?

  • HI Dennis 

    The URXEIE is set , so that i can receive all bytes including the erroneous ones . Then on each receive interrupt i move the status first to an array and than Rx buffer to another array , as accessing rx buffer first would clear the status . In rx buffer array should have a corresponding status at same location in status array . But when I am testing it as explained I do not get corresponding parity errors in status array as expected . 

    I am testing it by sending a packet using VB program and change the parity on fly , we wait for buffer to be empty before changing the setting and sending another byte

  • Did you set the UCRXEIE bit in the UCAxCTL1 register? When there is a parity error, is the byte in RXBUF correct? Wrong? Or, is actually the next correctly transmitted byte.

    UCRXEIE bit is set in UCAxCT1 register to receive all bytes including the erroneous ones  . I always receive the correct byte in receive buffer and also in the right order . There are no missing bytes 

    What is sending those bytes? Is it from the same UART on the same chip that is receiving them? From a different UART on the same chip? Or from a different chip?

    How did you manage to change parity setting in the middle of "two continuous byte"? Don't you need to stop the UART to change parity? Did you wait until the transmission of the previous byte is completely shifted out of the UART hardware before you stop the UART for parity change?


    We are testing our unit for hart specification , Hart test system sends the packet with few bytes having parity error . We emulate hart test system ( which is a linux based machine) using a VB program as well since we do not have much control over hart test system . Through Vb when we send the bytes we wait for the transmit buffer to be empty and the change the uart settings and then  transmit he next one

    But did you catch the correct number of bytes (given that one or more of them have incorrect value)?

    We always receive correct number of bytes and correct value as well , just the status is not able to tell that this byte received had wrong parity , which is and important part of detection under hart protocol

     

    Also If you can clarify that when the Uart interrupt is suppose to happen , just when the stop bit edge is detected or after the middle of stop bit as majority vote is taken in the middle of bits  .  

  • It smells like you found a hardware bug in parity detection of your MSP chip. But I cannot rule out the possibility that it is just an illusion created by your VB program on the PC and/or your MSP code.

    I think a Digital Storage Oscilloscope or Logic Analyzer can by very handy in getting to the bottom of this. If you do not have one, may be you could package your VB code and MSP code and send that to someone else willing and capable of testing it for you. (Not me ;)

    You could simplify your VB code to send only 5 bytes. Make those 5 bytes all different, and send the 3rd byte with wrong parity. You could also modify your MSP code to use an otherwise unused GPIO pin to show additional info. (To be displayed by the DSO.) Set up that GPIO as digital output during initialization. Inside your ISR, set that GPIO asap. If you found no parity error, clear that GPIO asap. Also clear it near the end of your ISR (knowing that it might have been cleared earlier).

    On the DSO, show at least the actual TXD signal and the for mentioned GPIO. The leading edge of this GPIO shows the timing of your ISR. The length of it indicates whether parity error is detected.
  • Another suggestion.

    You could work around this problem if you do not use parity of individual byte and rely on CRC or chuck-sum of the entire packet for error detection. In my opinion, CRC of entire packet in combination with packet timing control is a simple and good error detection method.
  • We also initially thought of it as a hardware bug , but it is basic bread and butter stuff of TI ..so we are hunting for possible setup issue ..although cant think of many.

    As you suggested I have already tried with GPIO in ISR and my setup was to set before Mov UCA0STAT,uartStatusBuffer(R14) instruction and then clear . Look at following statements from ISR

    bis.b #BIT2,&P4OUT; test only

    mov.b &UCA0STAT,bUartStatus(R14)

    bic.b #BIT2,&P4OUT; test only

    mov.b &UCA0RXBUF,bMBDataBlock(R14)

    We are not running anything else on Micro and waiting in (JMP to itself )statement for interrupt to happen , micro is also not in any LPM mode as well . Clock speed is around 16 Mhz , so we hope that interrupt happen instantaneously . we are seeing that interrupt is happening sometime after the rising edge of next start bit . I am not sure what would happen to UCA0STAT once the transmission of other byte has started . If interrupt happens at the middle of stop bit then at 1200 baud it has around 400 uS to respond . they way it is behaving it doesn't  look right to me 

    The Vb code we are running is programmable for number of bytes we send and parity user delectable for each byte . We select say three bytes , second one with even parity and rest with odd parity . Uart should flag second byte as parity error as it is configured for odd parity .

    Appreciate your response , any thoughts .. let me know if you want me ti try something .. There is nothing listed in micro errata sheet .. I am note sure where else to check is it is a hardware issue

  • And our overall check sum detection is working ok , but hart spec want each byte to be detected for parity error and respond accordingly depending on which byte of frame had the parity error ..
  • So you do have a DSO and did look at RXD and a GPIO. Did you look for parity bits in RXD? Were they as expected?

    What is the observed bit-rate? (This has to do with the VB code and PC hardware.) Can you measure the MSP programmed bit-rate? (This could be different.)

    I think the ISR should happen after a fixed amount of delay after the leading edge of current Start-bit. This fixed amount is probably 10.5 or 11.0 multiplied by the programmed bit-rate (not necessarily the actual received RXD signal).

    Sounds like you were using assembly code (at least for this test) which removes one of my worries. R14 must have been updated between consecutive ISRs and not modified otherwise.
  • Hi Vivek!

    Vivek Kataria said:
    Clock speed is around 16 Mhz

    Do you have a crystal attached to the MSP? Especially for HART there is very little error tolerance for the UART communication. Don't worry about processing speed - the 1200 / 2200 baud are that slow, I have devices running at 1.8432MHz, handling HART without any problems.

    Dennis

  • I do not have MSP430F5336. But I do have a MSP430F5529 LaunchPad. According to the Data-Sheets, both have the same USCI module. I tried a test very similar to yours. I use UCA1 to send and UCA0 to receive. Here is my code.

    #include "msp430f5529.h"
    
            RSEG    RESET
            DW      main
    
            RSEG    INTVEC
            ORG     USCI_A0_VECTOR
            DW      isr
    
            RSEG    CSTACK
    
            RSEG    DATA16_N
    status: DS      16
    rxbuf:  DS      16
    idx:    DS      1
    char:   DS      1
    
            RSEG    CODE
    isr:    bis.b   #BIT7,&P4OUT
            mov.b   &idx,R14
            mov.b   &UCA0STAT,status(R14)
            mov.b   &UCA0RXBUF,rxbuf(R14)
            inc     R14
            and     #0x000F,R14
            mov.b   R14,&idx
            bic.b   #BIT7,&P4OUT
            reti
    
    main:   mov     #SFE(CSTACK),SP
            mov     #WDTPW|WDTHOLD,&WDTCTL
            bis.b   #BIT0,&P1SEL            ;\_
            bis.b   #BIT0,&P1DIR            ;  P1.0 out to show ACLK 
            bis.b   #BIT7,&P4OUT            ;\_
            bis.b   #BIT7,&P4DIR            ;  P4.7 GP Output to show ISR timing
            bis.b   #BIT4,&P4SEL            ;P4.4 for UCA1TXD \__
            bis.b   #BIT4,&P3SEL            ;P3.4 for UCA0RXD \__ } wired together
    
            bis.b  #UCSWRST,&UCA0CTL1
            mov.b  #UCPEN|UCPAR,&UCA0CTL0
            mov.b  #UCSSEL_1|UCRXEIE|UCSWRST,&UCA0CTL1
            mov.b  #27,&UCA0BR0
            mov.b  #0,&UCA0BR1
            mov.b  #UCBRS_2,&UCA0MCTL
            bic.b  #UCSWRST,&UCA0CTL1
    
            bis.b  #UCSWRST,&UCA1CTL1
            mov.b  #UCPEN|UCPAR,&UCA1CTL0
            mov.b  #UCSSEL_1|UCSWRST,&UCA1CTL1
            mov.b  #27,&UCA1BR0
            mov.b  #0,&UCA1BR1
            mov.b  #UCBRS_2,&UCA1MCTL
            bic.b  #UCSWRST,&UCA1CTL1
    
            mov.b  #0,&idx
            mov.b  #'A',&char
            
            bis.b  #UCRXIE,&UCA0IE
            bis    #GIE,SR
    
    loop:   call   #wait
            call   #check
            mov.b  &char,&UCA1TXBUF
            inc.b  &char
            cmp.b  #'F'+1,&char
            jne    loop
            jmp    $                        ;all done, stalling
    
    check:  cmp.b  #'B',&char
            jeq    to_err
            cmp.b  #'B'+1,&char
            jeq    no_err
            cmp.b  #'E',&char
            jeq    to_err
            cmp.b  #'E'+1,&char
            jeq    no_err
            ret
    
    to_err: bis.b  #UCSWRST,&UCA1CTL1
            mov.b  #UCPEN,&UCA1CTL0
            bic.b  #UCSWRST,&UCA1CTL1
            jmp    wait
    
    no_err: bis.b  #UCSWRST,&UCA1CTL1
            mov.b  #UCPEN | UCPAR,&UCA1CTL0
            bic.b  #UCSWRST,&UCA1CTL1
    
    wait:   bit.b  #UCBUSY,&UCA1STAT
            jnz    wait
            ret
    
            END
    

    And resulting RAM dump is as follows:

    2400: 00 14 00 00 14 00
    2410: 41 42 43 44 45 46
    2420: 06 47

  • Sorry. My previous test was actually for Even Parity error detection. I have edited lines 39. 47, 79 and 84 to test for Odd Parity error detection. Both tests found no problem.

**Attention** This is a public forum