USART Initialisation Failure

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

He guys, when I initialise a USART to receive incoming GPS NMEA characters it freazes the system SOMETIMES.  The Initalisation is as follows:

Maybe it is receiving a character during initialisation?

usart_options_t USART_OPTIONS =
 {
 .baudrate     = GPS_USART_BAUDRATE,
 .charlength   = 8,
 .paritytype   = USART_NO_PARITY,
 .stopbits     = USART_1_STOPBIT,
 .channelmode  = USART_NORMAL_CHMODE
 };
 
 
 enter_critical_section();
 
 usart_spi_unselectChip(GPS_MAP);
 
 // Assign GPIO to USART.
 gpio_enable_module(GPS_MAP, sizeof(GPS_MAP) / sizeof(GPS_MAP[0]));
 
 // Enable USART Rx interrupt.
 INTC_register_interrupt(&usart_int_handler, GPS_USART_IRQ, AVR32_INTC_INT0);

 // Initialize USART in RS232 mode.
 usart_init_rs232(GPS_USART, &USART_OPTIONS, 66000000);
 
 GPS_USART->ier = AVR32_USART_IER_RXRDY_MASK;
 
 leave_critical_section();
 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Serial receive "freezing" is rarely initialization but often in the parsing. The receive interrupt service is probably more useful.

 

One situation where initialization might be significant is if the baud rate is marginal, so that a character gets scrambled, and thus fails the receive rules. 

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Fri. Jun 23, 2017 - 03:11 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the Parser works, the only thing I can think is that it is receiving characters during initialisation.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you have the UART receive enable as the very last thing? I also try to insure that the interrupt enable is on before I turn on the UART. If there is a global enable AND a receive enable (don't know UC3s), make sure that both are on before you enable the UART. I tend to clear the receive buffer while the enable is off as the next to last thing, clear any pending interrupts that might have happened but not serviced, then immediately enable the UART receiver.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My guess is that you've enabled more than just the IER interrupt and your USART interrupt-handler is not clearing errors such as FRAME and/or OVRE.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi mikeck, have a look at my interrupt handler and see if you can see where I am going wrong?

 

static void usart_int_handler(void){
 
 #define DropCharacters 9
 static volatile unsigned char state_machine = DropCharacters;
 
 static int crc_offset = 0, rx_char = 0; int usart_error = 0;
 
 static unsigned int headerDecoder = 0;
 
 
 if (usart_test_hit(GPS_USART) == true)
 { 
  usart_error = usart_read_char(GPS_USART, &rx_char);
   
  
  // Read character received here now in case it is overwritten later when parsing
  // Note, this is a heuristic error, probably due to the slow baud rate of the gps
  // No attempt to reset the baud rate has been made. 
  if((usart_error == USART_RX_ERROR) || (usart_error == USART_RX_EMPTY)){
   state_machine = DropCharacters;
  }
  else
  {
   
   // Process NMEA Packet Position using start character $ and end character *
   switch (rx_char){
    case '$': buffer_flush8(working_buffer);
       state_machine = 1;
    break;
    
    case '*': if(state_machine == 1) { state_machine = 2; crc_offset = 0; }
    break;
    
    default:
    break;
   }
    

   // Obtain NMEA packet - state machine
   switch(state_machine){
    
    case 1: post_to_buffer8_irq(working_buffer, (unsigned char)rx_char);
    break;
    
    case 2: 
      post_to_buffer8_irq(working_buffer, (unsigned char)rx_char);
    
      if(++crc_offset == 3){
       invoke_lsr(NMEA_Bridge, (int)working_buffer); working_buffer = alloc_buffer(NMEA_Buffers); state_machine = DropCharacters;
      }
    break;
    
    default: state_machine = DropCharacters;
    break;
   }
   
   
  }
 }
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just checked, I am testing for Framing errors

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

usart_read_char() returns USART_RX_ERROR if a framing, parity or overrun error has occurred, but reading the CSR (a byproduct of usart_test_hit() ) does not clear any of those fault indicators. (see RSTSTA in the CR)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Mikech, should I just try and clear the csr?  How would you do it?

 

Sh#t, csr is readonly

Last Edited: Fri. Jun 23, 2017 - 07:43 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To clear USART framing/parity/overrun error(s) you need to set the RSTSTA bit in the CR (not the CSR)
Something like GPS_USART->cr = AVR32_USART_CR_RSTSTA_MASK; (untested)


The ASF USART driver has a blunt hammer usart_reset() that will clear the error-indicators and also reset the USART

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is it me or does that look like too much processing in an ISR? Why aren't you simply using a ring buffer and doing the data processing later? Sure it's a UC3 but the fundamentals still apply, don't waste the resources just because it's a fast CPU.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When magic numbers die, they end up in that code. It seems to piss about alot.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Mikech, perfect, it works now.