This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Interrupt stops randomly

Hi,

Mocroprocessor: AT91SAM7s128
Toolchain: RealView MDK-ARM Version: 3.20

I have the following ADC code need to be run while interrupts disabled to eliminate 60hz noise. So I put it inside SWI (all interrupts are disabled in SWI).

int __swi(1) GetRawCountsFromExternalADC2DataBuffer(unsigned short * P);
int __SWI_1 (unsigned short * P)
{
    unsigned int Index;
    unsigned int Sum;

    // Start the ADC
    StartPWMC();

    do    // Eliminate first reading
    {
        // Check if the ADC ready for the data
        Sum = CheckADCReady();
    }while(Sum == 0);
    SelectSpiPort(SPI_ADC);
    GetDataFromSpi();

    // Start get 1024 readins
    for(Index = 0; Index < TOTAL_SAMPLE; Index ++)
    {
        do
        {
            // Check if the ADC ready for the data
            Sum = CheckADCReady();
        }while(Sum == 0);

        SelectSpiPort(SPI_ADC);
        *(P + Index) = (unsigned short)GetDataFromSpi();
    }

    // Stop the ADC
    StopPWMC();
    return(1);
}

The problem is that all interrupts (Timer and UART) will be stopped after it runs for random time. I also
use the spuriouse interrupt handler to fix the problem, but it is not working.

The following code is used to catch the spurious interrupts.


// STORE SPURIOUS INTERRUPT HANDLER TO AIC_SPU
    AT91C_BASE_AIC->AIC_SPU = (unsigned long) SpuriousInterruptHandler;

static void SpuriousInterruptHandler(void)
{
    // END OF INTERRUPT
    AT91C_BASE_AIC->AIC_EOICR = 0; }

If I am not using disable/enable interrupts for ADC code (data with 60hz will not right), the code runs without any problem.

Any comments are appreciated!

  • Please provide your SWI Handler.

    The problem may be related to an improper SWI Handler.

  • Here is the SWI handler I am suing. It is from Keil.

    T_Bit           EQU     0x20
    
                    PRESERVE8                      ; 8-Byte aligned Stack
                    AREA    SWI_Area, CODE, READONLY
                    ARM
    
                    EXPORT  SWI_Handler
    SWI_Handler
    
                    STMFD   SP!, {R12, LR}         ; Store R12, LR
                    MRS     R12, SPSR              ; Get SPSR
                    STMFD   SP!, {R8, R12}         ; Store R8, SPSR
                    TST     R12, #T_Bit            ; Check Thumb Bit
                    LDRNEH  R12, [LR,#-2]          ; Thumb: Load Halfword
                    BICNE   R12, R12, #0xFF00      ;        Extract SWI Number
                    LDREQ   R12, [LR,#-4]          ; ARM:   Load Word
                    BICEQ   R12, R12, #0xFF000000  ;        Extract SWI Number
    
                    LDR     R8, SWI_Count
                    CMP     R12, R8
                    BHS     SWI_Dead               ; Overflow
                    ADR     R8, SWI_Table
                    LDR     R12, [R8,R12,LSL #2]   ; Load SWI Function Address
                    MOV     LR, PC                 ; Return Address
                    BX      R12                    ; Call SWI Function
    
                    LDMFD   SP!, {R8, R12}         ; Load R8, SPSR
                    MSR     SPSR_cxsf, R12         ; Set SPSR
                    LDMFD   SP!, {R12, PC}^        ; Restore R12 and Return
    
    SWI_Dead        B       SWI_Dead               ; None Existing SWI
    
    SWI_Cnt         EQU    (SWI_End-SWI_Table)/4
    SWI_Count       DCD     SWI_Cnt
    
                    IMPORT  __SWI_0
                    IMPORT  __SWI_1
                    ;IMPORT  __SWI_2
                    ;IMPORT  __SWI_3
    SWI_Table
                    DCD     __SWI_0                ; SWI 0 Function Entry
                    DCD     __SWI_1                ; SWI 1 Function Entry
                    ;DCD     __SWI_2                ; SWI 2 Function Entry
                    ;DCD     __SWI_3                ; SWI 3 Function Entry
    ;               ...
    SWI_End
    
    
                    END
    

    Xiao

  • Hi all,

    I have the following update:

    If I stop the debuger (ULINK 2) after all the interrupts stop, I can see both I and F flags are set to 1 in SPSR. This means all the IRQ and FIQ are disabled.

    I know SWI blocks all the interrupts during its operation, why interrupts are not enabled sometime afte SWI is done?

    Regards,
    Xiao

  • why interrupts are not enabled sometime afte SWI is done?

    How sure are you that your SWI actually is done, at that point? Did you check the stack(s) and the program counter at the point you stopped it?

  • Hi,

    I know the SWI is done because the code goes back to the main loop and waiting for new interrupts. I can step through all the code inside the main loop.

    The new interrupt coming in while SWI is disabling interrupt may cause this problem. Is it possible?

    By the way, I found following:

    - Interrupt stops (no scan activity)
    - Stop the ULINK
    - Open "Timer Counter" under "Peripherals" menu
    - Press start and the code is running again

    Openning of "timer counter" window seems re-enable interrupts

    Regards,
    Xiao

  • Do you have a __swi(0) ?

    If you don't have a __swi(0), then change your swi number to 0 first.

    And maybe, take a look at the below link, and try the updated SWI Handler provided by Franc Urbanc

    http://www.keil.com/forum/docs/thread14826.asp

  • Hi,

    Yes, I have __swi(0). SWI0 is used to program one page of the flash memory. It works very well. I use it for firmware upgrade and storing calibration constants into flash (flash like EEPROM) without any problems.

    The difference between SWI0 and SWI1 is the time spent for the operation.

    SWI0 only spents couple of mini seconds to finish. And the SWI1 needs at least 16ms, sometime it can use up to 256 mini seconds if I want high resolution reading.

    Another difference is SWI1 is used much much more often than SWI0.

    Thanks for the link! I will try the updated SWI handler.

    Regards,
    Xiao

  • Hi,

    Quick Update:

    The updated SWI handler is not working.

    Xiao

  • It is really frustrating problem.

    I use the RTOS when I first started this project and RTOS stops randomly. I was told by some posts on this forum that Keil has a fix for the "RTOS stop" (related to interrupt detection).

    I stopped using RTOS and have the same problem again. I think there something wrong in this compiler dealing with the interrupt. Actually RTOS does the pretty much same thing as I do. Both use SWI very offen.

    Regards,
    Xiao