AnsweredAssumed Answered

USART6 RXNE?

Question asked by nunes.ricardo on Sep 1, 2016
Latest reply on Sep 2, 2016 by nunes.ricardo
I'm trying to implement an asynchronous USART using ISR to communicate with FTDI and Bluetooth Modules (RX and TX at 115kbps). I have a STM32F446RE with the following test code:

void USART6_IRQHandler(void)
{
    if(__HAL_USART_GET_FLAG(&stdio_handle, USART_FLAG_RXNE))
    {
        grb_write(&rb_rx, USART6->DR);
        __HAL_USART_CLEAR_FLAG(&usart_handle, USART_FLAG_RXNE);
    }
 
    if(__HAL_USART_GET_FLAG(&usart_handle, USART_FLAG_TXE))
    {
        if(grb_is_empty(&rb_tx))
        {
            CLEAR_BIT(USART6->CR1, USART_CR1_TXEIE);
            asm volatile("nop");
            asm volatile("nop");
        }
        else
        {
            uint8_t rx;
            grb_read(&rb_tx, &rx);
            USART6->DR = rx;
        }
    }
 
    NVIC_ClearPendingIRQ(USART6_IRQn);
}
 
int main()
{
       HAL_Init();
    SystemInit();
    SystemClock_Config();
    SystemCoreClockUpdate();
 
        __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_USART6_CLK_ENABLE();
 
    /// Init STDIO USART
    GPIO_InitTypeDef usart_gpio;
 
    /// TX pin (C6)
    usart_gpio.Pin = GPIO_PIN_6;
    usart_gpio.Mode = GPIO_MODE_AF_PP;
    usart_gpio.Pull = GPIO_NOPULL;
    usart_gpio.Speed = GPIO_SPEED_FREQ_HIGH;
    usart_gpio.Alternate =  GPIO_AF8_USART6;
    HAL_GPIO_Init(GPIOC, &usart_gpio);
 
    // RX pin (C7)
    usart_gpio.Pin = GPIO_PIN_7;
    usart_gpio.Mode = GPIO_MODE_AF_PP;
    usart_gpio.Pull = GPIO_NOPULL;
    usart_gpio.Speed = GPIO_SPEED_FREQ_HIGH;
    usart_gpio.Alternate =  GPIO_AF8_USART6;
    HAL_GPIO_Init(GPIOC, &usart_gpio);
 
    usart_handle.Instance = USART6;
    usart_handle.Init.Mode = USART_MODE_TX_RX;
    usart_handle.Init.BaudRate = 9600;
    usart_handle.Init.WordLength = USART_WORDLENGTH_8B;
    usart_handle.Init.StopBits = USART_STOPBITS_1;
    usart_handle.Init.Parity = USART_PARITY_NONE;
    usart_handle.Init.CLKLastBit = USART_LASTBIT_DISABLE;
    usart_handle.Init.CLKPhase = USART_PHASE_1EDGE;
    usart_handle.Init.CLKPolarity = USART_POLARITY_HIGH;
 
    assert(HAL_USART_DeInit(usart_handle) == HAL_OK);
    assert(HAL_USART_Init(usart_handle) == HAL_OK);
 
    __HAL_USART_ENABLE_IT(usart_handle, USART_IT_RXNE);
     
    HAL_NVIC_ClearPendingIRQ(USART6_IRQn);
    HAL_NVIC_SetPriority(USART6_IRQn, 3, 0);
    HAL_NVIC_EnableIRQ(USART6_IRQn);
         
        while(1);
}


If I connect USART6 to an FTDI and use a terminal to send characters I can see the messages flowing in the RX line with an oscilloscope but ISR is never called. If I change the code to transmit using ISR (enable TXE interrupt and putting data in my grb) everything is transmited and visible in the PC terminal. 

I tried with a sync version. Inestad of IRQ Handler I have this code:

uint16_t Data = 'a';
 
while(1)
{
    while(!__HAL_USART_GET_FLAG(&stdio_handle, USART_FLAG_TXE)); // Wait for Empty
    USART6->DR = Data;
 
    while(!__HAL_USART_GET_FLAG(&stdio_handle, USART_FLAG_RXNE)); // Wait for Empty
    Data = USART6->DR; // Collect Char
}

I tried to make an implementation of a loopback UART. I'm using PUTTY for this test and if I keep pressing the same key in the terminal I see some random characters appearing as a response.

Am I doing something wrong? I know that a similar code works for UART, but there is none free in this project.

Outcomes