This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

UCD3138 Family - Software Interrupt arguments getting corrupted by interrupt disable code

As of today, the latest version of the software interrupt entry looks like this:

#pragma INTERRUPT(software_interrupt,SWI)
void software_interrupt(Uint32 arg1, Uint32 arg2, Uint32 arg3, Uint8 swi_number)
//void software_interrupt(Uint32 *address, Uint32 data, Uint32 more_data, Uint8 swi_number)
{
 //make sure interrupts are disabled
    asm(" MRS     r4, cpsr ");   // get psr
    asm(" ORR     r4, r4, #0xc0 "); // set interrupt disables
    asm(" MSR     cpsr_cf, r4");   // restore psr

 switch (swi_number) //handle flash write/erase and ROM backdoor first

With some codes and newer versions of the compiler, the compiler is moving a parameter in the software interrupt call into R4, which is then corrupted by the write to the CPSR to disable the interrupts.  There are several ways around this:

The safest is to push R4 onto the stack disable the interrupts, and then pop it again when done:

    asm (" STMFD   SP!, {R4} "); //Store R4
       //make sure interrupts are disabled
   asm(" MRS     r4, cpsr ");    // get psr
   asm(" ORR     r4, r4, #0xc0 "); // set interrupt disables
   asm(" MSR     cpsr_cf, r4"); // restore psr
   asm (" LDMFD   SP!, {R4}  ");   //Restore R4

 


A faster but riskier option is to use R5 instead.  This seemed to be safe on the one code we've tried.  Bear in mind that all use of assembly language inside C functions is risky, and can always stop working when new versions of the compiler change how the registers are being used. 

For complete safety, and complete assembly language function could be written to disable the interrupts, but this would slow the software interrupt down more. 

Happy Debugging,

Ian Bower

6 Replies

  • So far we've only seen this happen with CCS 6.1. With 6.1, we've had to switch to 5.xx versions of the C compiler, so it's possible that if a 5.xx compiler is used in 6.0 (and not emulating a 4.xx compiler), the same thing may happen.

    Happy Debugging,

    Ian Bower

  • In reply to Ian Bower:

    I am using CCS 6.1 with armcl.exe v5.1.6 have the same issue.
  • Thanks for posting this info Ian!

    Did we answer your question? Click on the green "Verify Answer" button!
    Getting Started with the UCD3138, UCD3138064, UCD3138A64 or UCD3138128? Take a look at the training labs!
    Which topology are you using?  Try out the UCD3138 EVMs: 
    PFC | LLC | HSFB | PSFB 
    Need to upgrade your firmware without turning off your power supply? The 
    UCD3138064 supports on-the-fly firmware upgrades!

  • UART0  interrupt  define

    #pragma INTERRUPT(uart_interrupt,5)
    void uart_interrupt(void)   

    is  wrong

    how define

  • In reply to user4351959:

    There is no pragma support for any interrupts other than the ones provided with the EVM code, primarily the standard and fast interrupts. The UART is supported by the INTREQ, INTIVEC, and FIRIVEC registers. If you look at section 16.4 in the UCD3138 reference guide, you can see some suggestions for how use them. Note that the xxxIVEC registers are not actually cleared on read. They always reflect the status of the highest priority interrupt which is active. The only way to change these registers is to make the individual interrupt from the peripheral go away.

    Happy Debugging,

    Ian Bower

  • In reply to Ian Bower:

    In the future, it would be helpful if you could put questions like this in their own new string, to make searching easier.

    Happy Debugging,

    Ian Bower

This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.