SAM4L and RS232 with interrupts

Discussion around product based on ARM Cortex M4 core.
This forum will be discontinued soon.

Moderators: nferre, ncollot

idefix
Posts: 5
Joined: Wed Jul 16, 2014 9:14 am

SAM4L and RS232 with interrupts

Fri May 06, 2016 10:19 am

Dear all,

I have already a complete queuing system for another controller and I would like to port it to the SAM4L architecture.
The questions are related to the following datasheet:
http://www.atmel.com/Images/Atmel-42023 ... asheet.pdf

For this I had to rewrite the interrupt handler, but I have here 2 questions:

1. What interrupt flags should I use to signal the handler that a byte can be transmitted (maybe TXEMPTY) and for receiving (I think RXBUFF)?

2. The interrupt is fired again and again so I think I had to reset the flags?
Currently the flag is read with:

Code: Select all

	/* Read USART Status. */
	ul_status = usart_get_status(USART1);
The status is always 0x1202 so:
TXRDY
TXEMPTY
RXBUFF
is marked, how can I stop the interrupt from triggering again?

Thanks a lot for answers.
Matthias
tsvoipio
Posts: 54
Joined: Wed Aug 19, 2015 9:44 pm

Re: SAM4L and RS232 with interrupts

Fri May 06, 2016 4:38 pm

idefix wrote:Dear all,

I have already a complete queuing system for another controller and I would like to port it to the SAM4L architecture.
The questions are related to the following datasheet:
http://www.atmel.com/Images/Atmel-42023 ... asheet.pdf

For this I had to rewrite the interrupt handler, but I have here 2 questions:

1. What interrupt flags should I use to signal the handler that a byte can be transmitted (maybe TXEMPTY) and for receiving (I think RXBUFF)?

2. The interrupt is fired again and again so I think I had to reset the flags?
Currently the flag is read with:

Code: Select all

	/* Read USART Status. */
	ul_status = usart_get_status(USART1);
The status is always 0x1202 so:
TXRDY
TXEMPTY
RXBUFF
is marked, how can I stop the interrupt from triggering again?

Thanks a lot for answers.
Matthias
The bits you need are TXRDY and RXRDY.

The TXRDY bit is turned on when the transmitter holding register is empty, and the bit is off when the holding register is busy. It is safe to write to the transmitter when TXRDY is on. To get rid of the interrupt request after sending the last byte, turn off the corresponding mask bit.

The RXRDY bit is turned on when a byte is loaded to the receiver holding register, and the bit is turned off when the byte is read from the holding register.

The TXEMPTY bit tells that both the transmitter holding register and the transmit shift register are empty, so the current transmission is complete. Its main use is to know when it it safe to turn off possible external transmit buffers or modem transmit channels.

To receive a block:

Set up buffer pointer and count,
Set RXRDY bit in interrupt mask.

At receive interrupt:

Read receiver holding register, save to buffer,
If end of block, clear RXRDY bit in interrupt mask.

To send a block:

Set up buffer pointer and count,
Check that TXRDY is set
Get first byte from buffer, write to transmitter holding register,
Advance buffer pointer and count,
Set TXRDY bit in interrupt mask.

At transmit interrupt:
If more bytes to send, write next byte to transmitter, advance pointer and count,
if no more bytes to send, clear TXRDY mask bit.

--

-TV
idefix
Posts: 5
Joined: Wed Jul 16, 2014 9:14 am

Re: SAM4L and RS232 with interrupts

Sun May 08, 2016 10:33 pm

tsvoipio wrote: The bits you need are TXRDY and RXRDY.

The TXRDY bit is turned on when the transmitter holding register is empty, and the bit is off when the holding register is busy. It is safe to write to the transmitter when TXRDY is on. To get rid of the interrupt request after sending the last byte, turn off the corresponding mask bit.
great, thanks a lot for your explanation!
The sending part is working perfectly fine, using my queuing system.
The RXRDY bit is turned on when a byte is loaded to the receiver holding register, and the bit is turned off when the byte is read from the holding register.
here I have a problem.
I have an Atmel ICE connected to the SAM4L so I stepped now over the code.
I have an external IC connected to USART1. If I write a 0x01 to it, it will directly answer with 0x03 (I think you can alse just connect RX with TX, should do the trick).
I can see the answer with my logic analyser and I also see, while I debug the code, that the RXRDY bit in CSR is written to 1 and that 0x03 is in RHR.

But I see really a very strange behaviour.
While I step on chip using jtag I see that the RXRDY bit is directly cleared again to 0 (not in the ISR) and the interrupt that is fired a little bit later (maybe because the TX is enabled) reads the RXRDY bit as 0.

I tried to paste you the code from the debugger, by stepping the code (as the lib will be able to handle more than one usart sometimes the variable usart is used, that points to the usart that should be used). I tried to bring all relavant code from several nested functions into a single sequence to make it as easy as possible read:

Code: Select all

#define DISABLE_IRQS	cpu_irq_disable()
#define ENABLE_IRQS	cpu_irq_enable()

usart_serial_init(...)
NVIC_ClearPendingIRQ(USART1_IRQn);
NVIC_EnableIRQ(USART_NCN_IRQn);
usart_enable_interrupt(usart, US_IER_RXRDY);
DISABLE_IRQs
usart_enable_interrupt(usart, US_IER_TXRDY);
usart_serial_putchar(usart, c);
In ASF it is using the line to write the byte:
# ifdef USART1
	if (USART1 == p_usart) {
		while (usart_write(p_usart, c)!=0); <--- after this line is executed the CSR (RXRDY is 1)
		return 1; <---- after this line is executed the CSR (RXRDY is 0 again)
	}
# endif
ENABLE_IRQS
I jumped into the usart_write function from ASF:

Code: Select all

uint32_t usart_write(Usart *p_usart, uint32_t c)
{
	if (!(p_usart->US_CSR & US_CSR_TXRDY)) {
		return 1;
	}

	p_usart->US_THR = US_THR_TXCHR(c); <--- after this line is executed the CSR (RXRDY is 1)
	return 0; <--- after this line is executed the CSR (RXRDY is 0)
}
Do you have an idea what can cause the RXRDY flag to go directly back to 0 again?
Maybe I missed a configuration of a bit?
tsvoipio
Posts: 54
Joined: Wed Aug 19, 2015 9:44 pm

Re: SAM4L and RS232 with interrupts

Mon May 09, 2016 11:04 am

As there is a common interrupt line you have to handle both interrupts in a common handler:

1. Read active interrupts = status & mask
2. If active & RXRDY, handle receiver
3. If active & TXRDY, handle transmitter.

The ASF is a sorry mess, as it attempts to fit all the processors. I never cared to wade into it, but simply abandoned and run the bare metal directly.

--

-TV

Return to “SAM4 Cortex-M4 MCU”

Who is online

Users browsing this forum: No registered users and 1 guest