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.

setting XF bit inside interrupt

Other Parts Discussed in Thread: CCSTUDIO

Guys,

Is there a simple way to set the XF bit to drive the LED output inside an interrupt? The problem I have is that the ST1_55 register is restored/reverted to it's pre-interrupt state when the interrupt is exited, I believe. I want to be able to do this in C. May I possibly have to use other GPIO?

 

Thanks,

Jonathan

  • Hi Jonathan,

    I use the following C code which is called from within an SWI interrupt to toggle XF and have had no problems:

    #include <csl_chip.h>

    void toggle(void)

    {

       static int xf_value;

        if ((xf_value=CHIP_FGET(ST1_55,XF)) == 0x1)
        {
            CHIP_FSET(ST1_55,XF,0x0); 
        }
        else
        {
            CHIP_FSET(ST1_55,XF,0x1);
        }

    }

    C takes care, I believe, of the necessary context save and restore.

    Regards, Andrew

  • Could you explain why this works? I have two questions about the code:

    1.: At the beginning of every interrupt service routine, the content of ST1_55 should be pushed to the stack. Likewise, at the end it should be popped back - therefore, the status of the XF bit should be the same as at the start of the ISR. Why does your code circumvent this behaviour?

    2.: Why do you need the static variable xf_value?

     

    Thanks a lot in advance,

    Michael

  • Until you mentioned it I had not given any thought to why it works.  If all functions including ISR are written in C then push/pop operations are hidden from the programmer and hence of little concern.

    I just checked an assembly ISR that is called from C and it does not directly save or restore the stack so context saving presumably carried out, again, by the C compiler.  I agree that this still does not explain why XF remains unchanged.  If I get a chance I'll try toggling XF within my C called assembly ISR and see what happens.

    The static variable XF is not required. I copied and pasted and it was originally included so it could be added to a watch window for debug - apologies for any confusion.

    Regards, Andrew 

  • I have been working on this problem since January.

    Thought it was my code.

     

     

     

    if

     

     

    (ledstatus == 1) asm(" BIT (ST1, #ST1_XF) = #0");

    I use this code to toggle XF. Works ok outside the timer logic.

    When used with a timer IRS routine it is not effective.


     could not open source file "csl_chip.h"

    Where is csl_chip.h?

    Thank you

    Martin

  • Hi Martin,

    first of all: The status registers are always pushed to the stack when an ISR is called. After the ISR is executed, the registers are then popped back (have a look at the disassembly window: the RETI (return from interrupt) command is used to leave the ISR. As per assembly documents, this pops the status registers back from the stack).

    Then you mentioned the csl_chip.h. How does this relate to the XF bit, or is this a different problem? As a remark: there are two CSLs out there: One "normal" CSL and one "Low-Power CSL". You have to use the low-power one.

    Regards,

    Michael

  • I am using the latest csl version for the ubs stk.

      C:\Program Files\TMS320VC55XCSL-LOWPWR\c55xx_csl

    Using this example from above.

     

    if ((xf_value=CHIP_FGET(ST1_55,XF)) == 0x1)

     

    Martin Potts

  • I am using CCS Version 3.1 where csl_chip.h is in C:\CCStudio_v3.1\C5500\csl\include and a 5509A DSP.

    I just downloaded the TMS320C55x Chip Support Library for VC5504, VC5505, C5504, C5505, C5514, and C5515 device called C55XCSL-LOWPOWER.  There is no sign of csl_chip.h and I can not find CHIP Macros CHIP_FGET() and CHIP_SET().

    C55XCSL-LOWPOWER downloaded from: http://focus.ti.com/docs/toolsw/folders/print/sprc133.html

    The CHIP MACROS are described here: http://focus.ti.com/general/docs/litabsmultiplefilelist.tsp?literatureNumber=spru433j

    Is there is any support for CHIP MACROS in C55XCSL-LOWPOWER?

    Regards, Andrew

  • I'm not sure, but a software interrupt may not save and restore ST1_55 in the same way as a hardware interrupt. I can confirm, though, that a hardware interrupt will restore XF to its previous value no matter how you change it.

    Regardless of whether SWI works, don't set XF within any interrupt routine. Instead, change some other global variable (it must be declared volatile), preferably with the minimum calculations needed, and return from the interrupt. Then your main code loop can do any further calculations based on the global variable and set XF accordingly. When you set XF from your main code outside the interrupt, the value will not be changed back to its previous setting. A side effect of this is that you will spend less time executing code inside the interrupt, and that's probably a good thing.

    In my situation, I sometimes want the XF LED to blink once per second. So my interrupt routines calculate a global variable which counts in seconds. Then, my main routine keeps a shadow variable so that the loop can detect when the global changes. As soon as the global changes, I toggle XF and update the shadow variable. This is rather crude, since the LED is on for 1 second and then off for 1 second, but that's good enough for my debugging.

    If you want something different than what I've described, then make sure that the global variable gives you the information you need. Your main loop will not update XF instantaneously, but it will certainly be fast enough for the human eye.

  • I've just checked with the version 4.3.6 code generation tools we use (C compiler) and confirmed it does the same as the earlier tools we used. That is at the end of a compiler generated interrupt routine it ends with a simple reti. This means the XF flag is not preserved by the compiler. I've also just stepped through the sine() function in Ti's DSP library and this pushs and pops ST1_55 without any regard to the XF flag. So if it is changed in an ISR interrupting the sine func the change will be undone at the end of the sine(). This is causing us a major headache, we will have to abandone use of the XF pin.

    Note there will be exactly the same problem with the HINT pin flag in ST3_55 if it is changed in an ISR. Examination of the assembler in a test ISR I've had the compiler produce shows it is pushing and poping ST3_55 without preserving the HINT flag.

    So the XF and HINT pins can only be safely modified in the background routine or in an ISR if only a pulse (no net change) is created while global interrupts are disabled.

    Hope that helps someone.

    John

  • As I mentioned earlier in this thread, you should not design your program so that XF is modified inside an interrupt service routine.  Instead, set a flag, and then check that flag in your main code in order to set XF.  (If you are using DSP/BIOS, then there might be some kind of semaphore that you can safely set instead of setting XF directly within your ISR, and then the RTOS will pass the notification on to your main thread).

    While I'm mentioning this, I should also point out that there are API that you cannot call within an ISR, so XF is not the only DSP feature which is off limits within an ISR.  Typically, an ISR is part of an OS, but even when you are running without an OS, and perhaps are only using the CSL, you still must treat ISR code as special code with certain limitations.