I'm having some problems where, after a seemingly random amount of time, UART1 will suddenly stop receiving data. Other interrupts on VIC1, like external interrupts through the WIU channel, continue to function fine.
I am wondering if this is related to the new errata that was added to the November 2008 document for the STR9 (item 2.17). The workaround here is not very clear and in fact causes my application to crash when the first interrupt from any source is received. My best interpretation of the fix is to adjust the code to fit my ISR routine in 91x_vect.s file by changing the #12 in the last line to the appropriate number for my application (number of code lines prior to the LDR instruction times 4). As I said, though, this doesn't work. Has anyone else successfully implemented a workaround to this errata? If your fix was done for use with FreeRTOS that's a bonus for me but I'd like to take a look at any working fixes that I can. Thanks!
Obviously there is a chance to be due to Daisy chained interrupt controller VIC1 Hardware Priority management limitation already mentioned I the current Errata sheet but I can't confirm. For your information ST plan to update the AN2593 ''STR91x interrupt management'' with a software example demonstrating how to implement the Workaround through an easy example. This will be available beginning of January 2009. Kind regards, Kais.
we have had a similar problem with the uart1 stops triggering. we have suspected a modification in our IRQHandler that disabled interrupts. it seems to work fine after we put the modification back.
my question is how should we go about to determine the cause of the problem if interrupt stops trigerring? (sorry just new to Arm) thanks.
I just found out the CODE tag doesnt work for me. Message becomes blank. Following is my message:
I have been trying to find a set of source code for the interrupt management issues that would fit to our development environment. currently we are using ARM Developer Suite v1.2 (ADS 1.2). our IRQHandler is in this format: IRQHandler SUB lr,lr,#4 ; Update the link register SaveContext r0,r12 ; Save the workspace plus the current ; return address lr_irq and spsr_irq LDR r0, = VectorAddress LDR r0, [r0] ; Read the routine address LDR r1, = VectorAddressDaisy LDR r1, [r1] ; Padding between the acknowledge and re-enable of interrupts ; For more details, please refer to the following URL ; http://www.arm.com/support/faqip/3682.html NOP NOP ;put back modification for test uart1 problem MSR cpsr_c,#0x1F ; Switch to SYS mode and enable IRQ ; MSR cpsr_c,#0x1F | I_Bit ; Switch to SYS mode and enable IRQ ; '08-Nov-18 M.T. STMFD sp!,{lr} ; Save the link register. LDR lr, = IRQ_ReturnAddress ; Read the return address. MOV pc, r0 ; Branch to the IRQ handler. IRQ_ReturnAddress LDMFD sp!,{lr} ; Restore the link register. MSR cpsr_c,#0xD2 | I_Bit ; Switch to IRQ mode and disable IRQ LDR r0, = VectorAddress ; Write to the VectorAddress to clear the STR r0, [r0] ; respective interrupt in the internal interrupt LDR r1, = VectorAddressDaisy ; Write to the VectorAddressDaisy to clear the STR r1,[r1] ; respective interrupt in the internal interrupt RestoreContext r0,r12 ; Restore the context and return to the... ; ...program execution. What we have found that there are examples of the interrupt management document for RVDK which uses a slightly different interrupt handler. And it seems the so called stacking preamble offset is different for each compiler? We are researching this issue (we are new to ARM). Question: Is there any sample that would fit to the interrupt handler that we use? Failing that, how would i go about to adjust the sample code to fit to our IRQHandler? We are worried we might inadvertently read or write to DVAR twice for example? Or is it safe? [ This message was edited by: nle on 28-10-2009 06:00 ] [ This message was edited by: nle on 28-10-2009 06:01 ]
Thanks for the highly detailed explanation regarding VICs usage.
I just have an extra question: I want to use one FIQ (associated with only one source from TIMx) with the highest priority, and two or three IRQ (UART0, I2C, SSP), I want the FIQ be able to interrupt all other IRQ in progress. I do not need the IRQ to interrupt another IRQ. Shall I just add the dummy write to VIC0-VAR in the IRQ handler. Do I have to add dummy write to VIC0-VAR in the FIQ handler too? Do I have to add the IENABLE/IDISABLE in the IRQ handler to allow FIQ to interrupt IRQ? Thanks in advance for the IRQ/FIQ clarification Joel
I have found this particular IRQ handler. It came from STR910 evaluation board sample source.
I have been comparing this with the latest stmicro samples and also sample from interrupt management recommendations document. And had some time to review the section on interrupts from the reference manual. I now start to think there are some questionable lines in this sample IRQHandler, which our previous team had followed as is, in relation to our interrupt handler functions that only handle the related interrupt and doesnt write to VARs: -In the beginning of IRQHandler, reading VectorAddressDaisy, which is VIC1.VAR. -At the end of IRQHandler, writing to both VectorAddress and VectorAddressDaisy (VIC0.VAR and VIC1.VAR). Our system use several uarts simultaneously and we have experienced various interrupt and uart strange behaviour. We are now in the process to try the latest sample from the interrupt management recommendation. I have also been informed by previous team that the setting of I-Bit was to disable nested interrupt as part of the design. I have temporarily put it back to the original sample. Actually we have tested both but there is not much difference. We still have problems on missed characters, interrupts not triggering, interrupts with no events and worst case program just stopped. This program crash happens very rarely but still happens if running after several hours. By the way, our system originally did not have such issues when only the Timer0 and Uart0 were running. We started having problems as we expand our program to use the additional Uarts. [ This message was edited by: nle on 06-11-2009 10:39 ]
stmicro support engineer has given me permission to post this information. now i understand more how it works in structure and sequence. we have implemented the AN2593 recommendation just the other day. hopefully this fixes our problems.
========================================= Dear User, Please find here below latest information concerning the request R09450103 Erwin, Ok. Looks like I will have to provide a detailed explaination. Not sure if you have read the ARM document about the VIC IP so I am attaching the document for your reference. Note that VIC controllers (VIC0 and VIC1) are IPs from ARM and the details we have provided on the our reference manual and AN2593 application note is based on this. If you look closely on the VIC diagrams, the interrupt controller and the ARM9 core are two separate entities. You know that the ARM9 has only two interrupt lines, FIQ and IRQ. While the VIC0 and the daisy-chained VIC1 hands all the interrupt lines comming from peripherals. VIC0 and VIC1 also handles the prioritization. The ARM9 only waits for an FIQ or IRQ signal and will just fetch the address of the interrupt subroutine provided by VIC0. The ARM9 only cares about FIQ and IRQ prioritization and not the prioritization defined on VIC0 and VIC1. Now with this in mind, it would be easy for you to understand my explaination why there is a need to read and write to the VAR in your interrrupt service routine (ISR). When an interrupt occurs, say on VIC0 (e.g. ADC generating the interrupt), of course the VIC0 will handle the prioritization. And when it resolves the prioritization, it will put the address of the ISR into the VIC0_VAR. And then the VIC0 generates an IRQ signal, for example, to the ARM9 core. This you should know already. Now at this point the VIC0 will keep this interrupt request active. When the ARM9 core receives the IRQ signal, it will call\jump to the GLOBAL IRQ handler. You will find this handler in the 91x_vect.s file. In this handler, this where the VIC0_VAR is read to fetch the address of the ISR and then the program counter (PC) will jump to the ISR handler function (e.g. ADC_IRQHandler where ADC is on VIC0). Now the reason for READING the VAR, aside from fetching the address and jumping to the ISR, is for the ARM9 core to tell the VIC0 that the core is now handling the interrupt and that the VIC0 should now take note and manage the prioritization, etc. Now at the end of ISR, the ARM9 core will also need to tell the VIC0 that the core has finished executing the ISR. The mechanism to do this is by WRITING a dummy data to the VIC0_VAR. This mechanism allows the VIC0 to be able write a new ISR address to the VAR if there are pending interrupts. The WRITING operation\event is basically a signal that the ARM9 core has finished executing the ISR and this triggers an update for a new ISR address if there are pending interrupts (otherwise it will put in the default interrupt handler address - DefaultVector_Handler). Note that in the Global IRQ Handler, only the VIC0_VAR is accessed by the core. This is because the VIC0 is responsible of singalling the IRQ and managing and providing the address to the core. Now if the interrupt source is from a peripheral assigned on the VIC1 (e.g.USAR0), the VIC1 will of course manage the priorities and then VIC1 will pass the address to VIC0 and after managing the priority, VIC0 will put the address on the VIC0_VAR. Then same thing will happen as before, but in your interrupt service routine\handler you will need to perform a READ on the VIC1_VAR as well to tell the VIC1 that that the ARM9 core is now executing the ISR. And when you exit for the ISR, you only need to WRITE a dummy data to the VIC1_VAR. No need for VIC0_VAR. This is clearly explained in the AN2593. And you are also provided an sample source as companion of the AN2593. Please use this sample source code as reference in writing your interrupt service routine. Note that on this sample code, you are able to handle nested interrupts. The addition of the IENABLE and IDISABLE macros makes nested interrupts possible. I understand your concern on the WRITING operation but this operation is simply to signal the VIC that the core is finished with the current request. It does not really overwrite the content. It only sort of ''unlocks'' the VAR to be updated with a new ISR address. If you have an nested interrupt, all information of the current context will be PUSHed to the stack and later will be POPed from the stack so you do not loose the return address and the previous context. You will see these in the IRQ Handler in the 91x_vect.s file. Note that you will need to clear the request flag from the peripheral side (e.g. UART0) to prevent the VIC from re-issuing the interrupt request all over again. But I guess you know this already. If you are looking at the sample source code for the STR9 eval board included in the firware library, please take note that the implementation is for concurrent interrupts. You can still use these codes as reference but I strongly recommend to use the sample code in the AN2593 for proper management of the daisy-changed interrupt. In summary: READING the VAR: - updates the priority logic in the VIC and will also masks any interrupt with the same or lower priority level. It basically tells the VIC that the core will now execute the interrupt. WRITING to the VIC0_VAR or VIC1_VAR depending on the source of the interrupt: - updates again the priority logic in the VIC and this will allow the same or next and lower priority interrupts to generate an IRQ to the core. It basically tells that the core has finished executing the corresponding interrupt handler. If you look at the reference manual, Table 13 VIC Interrupt Channels, you will see which peripheral interrupt is connected to which VIC. Refer to this so that you will know whether you need to READ VIC1 and to know which VIC to WRITE. ========================================= [ This message was edited by: nle on 13-11-2009 11:39 ] [ This message was edited by: nle on 13-11-2009 11:43 ]