cancel
Showing results for 
Search instead for 
Did you mean: 

USART help - basic IRQ handler

john
Associate II
Posted on August 23, 2008 at 07:34

USART help - basic IRQ handler

34 REPLIES 34
st3
Associate II
Posted on May 17, 2011 at 12:38

There is an interrupt-driven example included with the Firmware Library - USARTs 1&2 send to each other...

john
Associate II
Posted on May 17, 2011 at 12:38

Hi,

I'm looking at a simple/basic interrupt handling code to handle

the USART - not using DMA.

So to receive into a buffer, and transmit from a buffer, all under

interrupt.

Then with the support functions for the main code to be able to

start a Tx (give a buffer/data), and read from the Rx buffer.

Note - I have code to do this, but my Rx routine is dropping a

character (or two) occasionally, so I just wanted to see if anyone

has good reliable code to do this, then I can see what I'm missing ?

Thanks,

John.

john
Associate II
Posted on May 17, 2011 at 12:38

Hi st7,

Thanks - yes, I have been through all the examples.

Trouble is, they are all one-shot. They work fine, but just do

one send/receive, then stop/hang.

I think you are referring to example 4 - none of the Tx is triggered

from the main code, it all happens automatically from within the IRQ's.

Yours,

John.

john
Associate II
Posted on May 17, 2011 at 12:38

Hi Giovanni,

Thanks for the help - I downloaded your RTOS and had a look around.

from ports, ARMCM3-STM32F103

stm32_serial.c

line 71

if (sr & SR_TXE) {

your using TXE: Transmit Data Register Empty

the same as the examples from ST.

I found that this interrupt is constantly firing after the

Tx buffer has been sent, because the Transmit Data Register

is empty... so it is disabled at the end of data Tx.

I'm looking into using TC (Transmission Complete Interrupt),

so it does not need repeatedly enabling/disabling.

----

I see to read from the buffer (queue), you disable interrupts:

chIQGet() / chSysLock()

and the same for writing to the output buffer (queue):

chOQPut() / chSysLock()

----

It looks to me like your code and mine are the same, at least

logically - only I use the ST libraries, instead of direct

register accessing.

How did you test your code ?

If I run a loopback build in my STM32 device, and connect hyper-term

(from a PC) to it - all works fine. Sent chars are echo'd back.

The situation where I get dropped input chars (into the STM32) is

when it is sending AT command strings to a GSM module. That module

echo's back the characters it receives, probably a lot faster, so

there is 2-way traffic on the USART.

So I still don't understand why I'm dropping Rx chars.

Any other thoughts welcome...

John.

lanchon
Associate III
Posted on May 17, 2011 at 12:38

hi John,

> my Rx routine is dropping a character (or two) occasionally

very probably a race condition, post your code and I'll take a look at it. (no need to post makefiles or complete app cause I won't run it.)

disirio
Associate II
Posted on May 17, 2011 at 12:38

Hello, the project in my signature includes a STM32 demo with a complete interrupt-driven UART driver. The driver uses circular buffers.

Even if you don't plan to use an RTOS it should still useful as an example.

regards,

Giovanni

---

ChibiOS/RT

http://chibios.sourceforge.net

john
Associate II
Posted on May 17, 2011 at 12:38

I'm trying to get a interrupt when the USART has completed sending

a single character.

So I'm trying to use TC/TCIE.

Is this ONLY for DMA (frames ?), or should it work after a direct

call to USART_SendData() ?

Thanks,

John.

john
Associate II
Posted on May 17, 2011 at 12:38

Hi lanchon,

Thanks - I thought of that, and so removed all IRQ enable/disable

from all of the receiving side of the USART code. It is never

disabled, but still misses chars (they are definately there, the PC

see them).

If you still want to see the code, let me know - I'll have to tidy

it a bit, as I'm trying all sorts...

John.

16-32micros
Associate III
Posted on May 17, 2011 at 12:38

Hi,

Could you please provide me your configuration speed : CPU and APBs ?

It seems like the core (Cortex-M3) generates bufferable write transfer. This means that the CPU consider that the data is written from an AHB point of view while the APB write transfer is managed by the AHB2APB bridge and could be written later. In this case the CPU left the interrupt routine while the interrupt is not yet cleared the cpu will re-enter again on the interrupt handler. To avoid this race condition, could you try the following :

1) ISR routine has to clear the interrupt peripheral flag when just entering in the routine to avoid interrupt missing.

2) ISR routine has to Implement a write to the APB peripheral register ( to clear the peripheral flag) then followed by a read access to the same register/flag. This operation will force the write buffer to complete the effective write the bit in the register.

cheers,

STOne-32.