2009-07-23 01:41 AM
USART irq keeps triggering (TXE but TXEIE not enabled?)
2011-05-17 04:18 AM
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?2011-05-17 04:18 AM
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.2011-05-17 04:18 AM
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); }2011-05-17 04:18 AM
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.