cancel
Showing results for 
Search instead for 
Did you mean: 

USART irq keeps triggering (TXE but TXEIE not enabled?)

domen2
Associate III
Posted on July 23, 2009 at 10:41

USART irq keeps triggering (TXE but TXEIE not enabled?)

4 REPLIES 4
domen2
Associate III
Posted on May 17, 2011 at 13:18

USART1 with remapped pins, only TX and RX are used.

When chatting with bluetooth module (via USART) stm32 sometimes gets stuck in USART irq (depends on data sent from bluetooth module).

The thing is that I only enabled TXE and RXNE interrupts, and these two aren't getting triggered.

USART1:

{SR = 0xc0 , RESERVED0 = 0x0, DR = 0x74, RESERVED1 = 0x0, BRR = 0x11, RESERVED2 = 0x0, CR1 = 0x202c, RESERVED3 = 0x0, CR2 = 0x0, RESERVED4 = 0x0, CR3 = 0x0, RESERVED5 = 0x0, GTPR = 0x0, RESERVED6 = 0x0}

SR = 0xc0

- TXE transmit data register empty

- TC transmission complete

CR1 = 0x202c

- UE usart enable

- RXNEIE RXNE interrupt enable

- TE transmitter enable

- RE receiver enable

So... seems I'm getting TXE interrupts, but they're not enabled.

This only seems to happen when sending data from bluetooth->cortex, the reverse direction works fine. It only seems to happen with this bluetooth module - same serial worked fine when connected to PC.

TXEIE was disabled before in the serial irq, after last buffer character was transmitted.

What am I doing wrong?

andreas2
Associate II
Posted on May 17, 2011 at 13:18

Hard to tell for sure without a look at your ISR...

Are you sure you're actually interrupting on the TXE event, not just reading the flag from the SR and interpreting that as an interrupt? That flag should be set always if you're not currently transmitting since the transmit register surely would be empty in that case.

domen2
Associate III
Posted on May 17, 2011 at 13:18

Well... here it is, the idea is that for TX it reads bytes from circ buf, and disables TXEIE when buf is empty.

usart_irqhandler is only called from the three IRQ hooks below.

From experimenting I've done, it seems it might be related to inexact baudrate.

Code:

void usart_irqhandler(enum usart_id usart_id)

{

struct usart_data *usart = &usarts[usart_id];

USART_TypeDef *usart_dev = usart->usart_dev;

usart->irqs++;

if (USART_GetITStatus(usart_dev, USART_IT_TXE)) {

unsigned char *data;

int len;

usart->irqs_tx++;

if ((data = circ_buf_get_bytes_start(usart->txbuf, &len)) &&

(usart_id != USART_RFCOMM || gpio_get_value(CB_RTS) == 0)) { /* this clears TXE */

USART_SendData(usart_dev, *data);

circ_buf_get_bytes_final(usart->txbuf, 1);

} else {

USART_ITConfig(usart_dev, USART_IT_TXE, DISABLE);

}

} else if (USART_GetITStatus(usart_dev, USART_IT_RXNE)) {

int c = USART_ReceiveData(usart_dev);

if (circ_buf_put_bytes(usart->rxbuf, (unsigned char *)&c, 1))

usart->ovf_rx++;

if (usart_id == USART_RFCOMM) /* CTS handling */

if (circ_buf_free(usart->rxbuf) == 0)

gpio_set_value(CB_CTS, 1);

}

}

void USART1_IRQHandler()

{

usart_irqhandler(USART_ID_1);

}

void USART2_IRQHandler()

{

usart_irqhandler(USART_ID_2);

}

void USART3_IRQHandler()

{

usart_irqhandler(USART_ID_3);

}

domen2
Associate III
Posted on May 17, 2011 at 13:18

SOLVED

------

Jeez, I'm such an idiot.

} else if (USART_GetITStatus(usart_dev, USART_IT_RXNE)) {

should not be in else, since both interrupts can occur at the same time.