AnsweredAssumed Answered

Why can't I read from USARTx->SR in interrupt mode (STM32-Discovery)?

Question asked by tumati.pradeep on Jul 12, 2012
Latest reply on Jul 13, 2012 by tumati.pradeep
Hi,

Hardware -> STM32-Discovery
IDE-> Keil uVision

getBit(USART2->SR, position) works in the non-interrupt mode, but, it doesn't in the USARTn interrupt mode...!

I have linked the USART1's TX to the USART2's RX. Usart1's TX is working correctly; I have checked it with a logic analyzer. Now, in both usarts, I notice that I can't read the value of USARTx->SR in the interrupt mode. The debugger in the uVision shows me the right values in the SR register; I see ORE, IDLE, RXNE, TC & TXE turned on. However, when I tried to retrieve the value of USARTn->SR, I get a 0.

int b=USART1->SR;    // returns 0
int b=USART_GetFlagStatus(USART2, USART_FLAG_RXNE); // returns 0

See the line against the comment [ISSUE] below...

None of the code examples (receiveData within interrupt mode) that I have seen in this forum work. Is there something that I am missing? Whats going on here?

Any suggestion/advice is highly appreciated. Thanks.
#include "wrapper.h"
 
USART_InitTypeDef USART_InitTypeDef2={
                9600,
                USART_WordLength_8b,
                USART_StopBits_1,
                USART_Parity_No,
                (USART_Mode_Rx | USART_Mode_Tx ),
                USART_HardwareFlowControl_None
};
 
volatile int x=0;
unsigned char buffer2[MAX_BUFFER_SIZE];
 
void __setup_USART2_pins(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
 
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
 
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
}
 
void __setup_USART2_Interrupt(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
 
        NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); 
     
        // Enable the USARTx Interrupt
        NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        NVIC->ISER[1] |= (1 << (USART2_IRQn & 0x1F)); // enable interrupt in NVIC
}
 
void initUSART2()
{
        AFIO->MAPR   &= ~(1 << 3);                      // clear USART2 remap
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA , ENABLE);
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
        __setup_USART2_pins();
        __setup_USART2_Interrupt();
                 
        USART_Init(USART2,&USART_InitTypeDef2);
        USART2->CR1 |= CR1_UE_Set;          // Enable USART
        USART2->CR1 |= USART_Mode_Tx;       // Enable TX operation
        USART2->CR1 |= USART_Mode_Rx;       // Enable RX operation
        USART2->CR1 |= USART_FLAG_RXNE ;        // Enable RX interrupt mode
}
 
void sendUSART2(int size)
{
    int index=0;
    if (buffer2==NULL)
        return;
 
    // Iterate over the buffer2 and print char by char
    for (index = 0; index<size; index ++) {
        USART_SendData(USART2, (uint8_t) buffer2[index]);  
         
        // Wait until the TXE bit is set to 1
        while (!getBit(USART2->SR, 7));
         
        if (index>MAX_BUFFER_SIZE)
            break;
    }
 
    //Loop until the end of transmission; this is very important
  while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
}
 
void USART2_IRQHandler()
{
    volatile int b = USART_GetFlagStatus(USART2, USART_FLAG_RXNE); // <- [ISSUE]
    buffer2[x++]=USART_ReceiveData(USART2);
    return;
}

Outcomes