UC3A1 USART Timeout blues

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

Hi guys (and gals)  I am working on trying to use PDCA to receive data from a USART on a couple of projects.  Both have periods of no data that I would like to use to trigger an USART Timeout to indicate that a data cycle is one and the PDCA needs to switch input buffers.  I put a test toggle output in mi USART Timeout interrupt ISR to see how often it triggers.  Baud is 9600, trigger rate for Timeout is 4us, regardless of what value I load RTOR with!  Below is my code for the USART - I hope someone can point out the errors of my ways - this is one time the wife can't!


void init_USART_0(void)
{
	static const gpio_map_t USART_GPIO_MAP =
	{
		{USART_0_RX_PIN, USART_0_RX_FUNCTION},
		{USART_0_TX_PIN, USART_0_TX_FUNCTION},
	};
		static const usart_options_t USART_0_OPTIONS =
		{
			.baudrate		= USART_0_BAUD_RATE,
			.charlength		= USART_0_CHARLENGTH,
			.paritytype		= USART_0_PARITY,
			.stopbits		= USART_0_STOPBITS,
			.channelmode   = USART_0_MODE
		};
		
	gpio_enable_module(USART_GPIO_MAP, sizeof(USART_GPIO_MAP) / sizeof(USART_GPIO_MAP[0]));
	usart_init_rs232(USART_0, &USART_0_OPTIONS, CLOCK_PBA_FREQ);
	return;
}

void USART_0_Interrupt_Init(void)
{
    Disable_global_interrupt();
	INTC_init_interrupts();
	INTC_register_interrupt(&usart_0_int_handler, USART_0_IRQ, AVR32_INTC_INT0);
	USART_0->rtor = 8 << AVR32_USART_RTOR_TO_OFFSET;
	USART_0->cr = USART_0->cr | 1 << AVR32_USART_CR_STTTO_OFFSET;	
	//USART_0->rtor =1024;
	USART_0->ier = AVR32_USART_IER_TIMEOUT_MASK;
	//USART_0->cr = AVR32_USART_RETTO_MASK;
	gpio_tgl_gpio_pin(TEST_LED);
    Enable_global_interrupt();
	return;
	
}

__attribute__((__interrupt__))
void usart_0_int_handler(void)
{
	int c,b;

	if (USART_0->csr & AVR32_USART_TIMEOUT_MASK)
	{
			gpio_tgl_gpio_pin(TEST_LED);
			usart_reset_status(USART_0);
			if (buffer_pointer) {
				pdca_reload_channel( PDCA_CHANNEL_NUMBER,
				(void *)Buffer_2, sizeof(Buffer_2));
			}
			else {
				pdca_reload_channel( PDCA_CHANNEL_NUMBER,
				(void *)Buffer_1, sizeof(Buffer_1));
			}

			/* Switch to the other input buffer */
			buffer_pointer = !buffer_pointer;
			buffer_ready = !buffer_pointer;
			USART_0->cr = AVR32_USART_RETTO_MASK;

	}

}

Thanks,

David

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

3 observations ;

1) : The CR is write-only, so USART_0->cr = USART_0->cr | 1 << AVR32_USART_CR_STTTO_OFFSET; is a problem.

2) : You enable the retrigger timeout (RETTRO) which will cause periodic interrupts. (but the period will depend on the value in RTOR)

3) : If the cause of an interrupt is not handled properly then that will retrigger an ISR at a fairly constant rate.

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

Hi miketech and thanks for the reply.  The line you mention in #1, I found in 4 or 5 pots dealing with pdca and USART timeout.  Well except for a small difference-I managed to leave out a pair of ().  So it should read 

usart-0->cr = (usart-0->cr | 1 << AVR32_USART_CR_STTTO_OFFSET);

does this make more sense to you?
 

#2 the time between cycles of USART data is 320ms. I am aiming for a timeout of 300ms to prevent multiple timeouts between cycles of data.  However, it does not appear that my writing to rtor is having an effect, as the timeout interrupts are occurring at 4us intervals-unless something else is causing the interrupts, but I have tried to only enable the timeout interrupt.

 

#3 I need to look to see if something else in the USART is causing the interrupt

 

thanks agin for your input

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

The USART CR is write-only, so usart-0->cr = (usart-0->cr | 1 << AVR32_USART_CR_STTTO_OFFSET); still does not make any sense to me.
You are lucky that a read of the USART CR is returning all bits as zero.


Are you using interrupts for the PDC ?
If yes, then you will need to disable the TRC and/or RCZ interrupt(s) if you do not reload the PDC inside the isr.