Hristo Mitrev
Hristo Mitrev

Reputation: 17

Why can't I read interrupt flag from my main loop?

I'm writing code for stm32l011 MCU and it have to do one basic task for now - wait for a specific byte(predefined by me) from the UART and following "\r\n" or "\n\r" sequence. If it receives that, it set's a null pointer to the address of the predefined char, which is read and handled in the main loop.

    volatile uint8_t uart_buff[UART_BUFF_LEN] = {'\0'};
    volatile uint8_t *uart_data = NULL;
    volatile uint8_t *uart_stack = uart_buff+2;

    void USART2_IRQHandler(void){
        if(LL_USART_IsActiveFlag_RXNE(USART2)){
            *uart_stack = LL_USART_ReceiveData8(USART2);
            user_uart_send_byte(*uart_stack);

            //same as if(!(strcmp((uart_stack-1), "\r\n") || strcmp((uart_stack-1), "\n\r")))
            if((*uart_stack == '\r' || *uart_stack == '\n') && (*(uart_stack-1) == '\r' || *(uart_stack-1) == '\n'))
            {
                uart_data = uart_stack - 2;
                uart_stack = uart_buff+2;
            }

            uart_stack++;
        }
    }

and main:

    extern volatile uint32_t systick_counter_ms;
    extern volatile uint8_t *uart_data;

    int main(void){

        init();

        while(1)
        {
            LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_3);
            //delay_ms(1); //without that it doesn't want to work
            if(uart_data)
            {
                adc_transmit_reading(*uart_data);
                uart_data = NULL;
            }
        }
    }

I wrote the C program above and it didn't seem to work. But when I introduced delay in the main loop it just magically sprang to life. Why is that? Key things to note: There's echo from the UART so I'm sure that it handles the interrupt properly in both cases, also I tried to remove optimizations of the compiler(which optimizes for size(Os)) by using volatile variables. Also the delay is made by while loop, which waits interrupt which increments variable every millisecond.

My layman's guess is that because I'm only looping around that uart_data pointer, somehow the synchronization between the interrupt and main loop isn't happening.

Thanks in advance :)

Upvotes: 1

Views: 653

Answers (1)

Louis Caron
Louis Caron

Reputation: 1332

The problem is that you have indicated that your uart_data points to volatile data. But in your loop, you are testing the pointer and not the data.

So you must indicate that your pointer is volatile as well:

extern volatile uint8_t * volatile uart_data;

You can find more information in this post: Why is a point-to-volatile pointer, like "volatile int * p", useful?

Upvotes: 3

Related Questions