anyone
anyone

Reputation: 157

Uart receives correct Bytes but in chaotic order

Using Atmel studio 7, with STK600 and 32UC3C MCU

I'm pulling my hair over this. I'm sending strings of a variable size over UART once every 5 seconds. The String consists of one letter as opcode, then two chars are following that tell the lenght of the following datastring (without the zero, there is never a zero at the end of any of those strings). In most cases the string will be 3 chars in size, because it has no data ("p00").

After investigation I found out that what supposed to be "p00" was in fact "0p0" or "00p" or (only at first try after restarting the micro "p00"). I looked it up in the memory view of the debugger. Then I started hTerm and confirmed that the data was in fact "p00". So after a while hTerm showed me "p00p00p00p00p00p00p00..." while the memory of my circular uart buffer reads "p000p000p0p000p0p000p0p0..."

edit: Actually "0p0" and "00p" are alternating.

The baud rate is 9600. In the past I was only sending single letters. So everything was running well.

This is the code of the Receiver Interrupt: I tried different variations in code that were all doing the same in a different way. But all of them showed the exact same behavior.

lastWebCMDWritePtr is a uint8_t* type and so is lastWebCMDRingstartPtr. lastWebCMDRingRXLen is a uint8_t type.

__attribute__((__interrupt__))
void UartISR_forWebserver()
{
    *(lastWebCMDWritePtr++) = (uint8_t)((&AVR32_USART0)->rhr & 0x1ff);
    lastWebCMDRingRXLen++;
    if(lastWebCMDWritePtr - lastWebCMDRingstartPtr > lastWebCMDRingBufferSIZE)
    {
        lastWebCMDWritePtr = lastWebCMDRingstartPtr;
    }
// Variation 2:
//  advanceFifo((uint8_t)((&AVR32_USART0)->rhr & 0x1ff));

// Variation 3:
//  if(usart_read_char(&AVR32_USART0, getReadPointer()) == USART_RX_ERROR)
//  {
//      usart_reset_status(&AVR32_USART0);
//  }
//      

};

I welcome any of your ideas and advices.

Regarts Someo

P.S. I put the Atmel studio tag in case this has something to do with the myriad of debugger bugs of AS.

Upvotes: 0

Views: 285

Answers (1)

grenix
grenix

Reputation: 743

For a complete picture you would have to show where and how lastWebCMDWritePtr, lastWebCMDRingRXLen, lastWebCMDRingstartPtr and lastWebCMDRingBufferSIZE are used elsewhere (on the consuming side)

Also I would first try a simpler ISR with no dependencies to other software modules to exclude a hardware resp. register handling problem.

Approach:

#define USART_DEBUG
#define DEBUG_BUF_SIZE 30

__attribute__((__interrupt__))
void UartISR_forWebserver()
{ 
  uint8_t rec_byte;
#ifdef USART_DEBUG  
  static volatile uint8_t usart_debug_buf[DEBUG_BUF_SIZE]; //circular buffer for debugging
  static volatile int usart_debug_buf_index = 0;
#endif      

  rec_byte = (uint8_t)((&AVR32_USART0)->rhr & 0x1ff);

#ifdef USART_DEBUG  
  usart_debug_buf_index = usart_debug_buf_index % DEBUG_BUF_SIZE; 
  usart_debug_buf[usart_debug_buf_index] = rec_byte;
  usart_debug_buf_index++

  if (!(usart_debug_buf_index < DEBUG_BUF_SIZE)) {
    usart_debug_buf_index = 0; //candidate for a breakpoint to see what happened in the past
  }
#endif
  //uart_recfifo_enqueue(rec_byte);

};

Upvotes: 0

Related Questions