简体   繁体   中英

FPGA interrupt handling in C

I have a coursework for designing a state machine on the Microblaze microprocessor in C. The problem I have is that I have to change a certain picture. Let's say I press BTNL on the FPGA; I have to be presented with a landscape picture for 5 secs and after certain 3 secs I have to make that picture flash. In the meantime, the time 5s -> 0s has to be displayed on the 7-segment display. This is the case where the button has been detected and the flashing mode has to be displayed. The interrupt occurs every 0.004s and the microprocessor's clock is 100MHz.

for(j=0; j<=5secs; j++)
{
    if(j>3secs)
    {
        if(counter == sec){
            counter=0;
            if(temp==white){ //white background
                temp=background;
            }
            else temp=white;
        }else counter++;
        XGpio_DiscreteWrite(&REGION[4],1,temp);
    }
    else XGpio_DiscreteWrite(&REGION[4],1,temp);
    if(j==5secs)
        states = IDLE;
}

My main problem is with displaying the number on the 7-segment display. When I place the displayNumber() function in the case, the whole thing just freezes once it goes to the displayNumber() line. I know the nested for loops cost a lot of time and energy and I think this might cause the problem, but I cannot find a working solution. Any thoughts or advice are really appreciated.

Another thing is that I tried with a flag, but because of the interrupt handling it doesn't work.

EDIT: I am not trying to get a copy/paste solution of my problem. The whole thing is quite massive, I mean verilog project along with the files for the other functions done in c. I didn't expect you to run the code and reproduce the whole thing, because I had been provided the Verilog project by the school, so you have to generate a bitstream and then upload and run the whole thing on the board. I am here just looking for a suggestion about How would you improved this, have you encountered such behaviour with FPGAs, any ideas.

Thanks for the time spent to read the question!

Thanks to Craig, I did paid more attention on how the displayNumber() func was all set up. So it came out that it stuck in the interrupt and I just had to drive it from other place. So thank you for pointing the right direction, Craig!

If you think this might not be beneficial for anyone else, let me know so I can delete it.

So, the problem was with the definition of the ISR and its combination with the DisplayNumber() func.

Basically, my ISR looked like:

void hwTimerISR(void *CallbackRef)
{
interruptServiced = FALSE;
interruptCounter++;
if (interruptCounter == 1)
{
    interruptCounter = 0;
    displayDigit(); //needed to display the number on the display
    operation(state); // function that moves the FSM's states
    interruptServiced = TRUE;
}

return;
}

Basically, the problem was that in the case where I had to cout 5 secs, the displayNumber function would call the displayDigit() and it will all stuck. What I did was to change the states not in the operation function but in the main.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM