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.

How to initialize the Interrupt Service Table ???

I'm trying to setup interrupts (on a C6748).  I'm able to set all the proper control registers such as (IER and INTMUX), but I'm having trouble initializing the Interrupt Service Table in memory (this table would contain jumps to my interrupt service routines.  (Apparently, the processor won't allow me to write to that section of memory -- perhaps because it is program memory space? I dunno.)  Perhaps there is a way to write into the Interrupt Service Table?  Or perhaps there is a way to get the Linker to automatically create and load that table?  Again, I dunno.

Documentation for the handling of interrupts seems to be parcelled out piecemeal into various manuals.  But they're all cryptic about how to setup the Interrupt Service Table. I presume there is a smooth way to do it, but I'm not finding it described anywhere.

So far I've looked in:

  • The Megamodule Reference Guide
  • The C6748 Instruction Set Handbook
  • The C6748 System Reference Guide
  • The C6000 Assembly Language Tools v7
  • The C6000 Optimizing Compiler v7
  • The DSP Assembly Language User Guide

(I writing in C using CCS, and not using the DSP-BIOS.  So, should I use the "interrupt" keyword when declaring my interrupt handlers?)

Thanks for your help.

 

  • Check out the attached project I wrote for 6455.  It's the same interrupt controller, etc. just a different memory map.  The interrupt service table itself needs to be aligned on a 1KB boundary.  The main files to look at are main.c, vectors.asm, and c6455.cmd. 

    6455 Starter Project.zip
  • Hi

    I would think the CSLR (register CSL) based example in the PSP driver package should help serve as a non BIOS , c example

    \packages\ti\pspiom\cslr\evm6748\examples\intc\src

    Hope this helps.

    Regards

    Mukul

  • Brad,

    Thanks for the example.  It is super helpful

    • I wasn't able to locate the header include file called out in main.com:  #include <cslr_intc.h>    It must contain a definition of CSL_IntcRegs, and perhaps some other stuff. ???
    • main.c apparently moves the Interrupt Service Table to a new location, starting at &ISTP_START (which your linker command file sets to location 0x800000), rather than use its default location.  I don't understand why that is done.  Why wouldn't the default location be suitable? Can't the linker/loader load it into the default location?
    • vectors.asm contains code for the non-maskable master reset.  But my understanding is that such code would be completely ignored in the C6748, since the non-maskable master reset always runs its default code -- unchangeable by the user.  (See The C674x Instruction Set handbook, Table 2-15. Interrupt Service Table Pointer Register (ISTP) Field Descriptions. page 46) Am I correct in my understanding?  I'm also confused when vectors.asm references "_c_int00" , since that is a reserved keyword for the master reset entry point (which cannot be changed).

    I'll try modeling my code after yours.  It looks like it will work. 

    Thanks again!

    P.S.  Mukul suggested I look in the "PSP driver package".  But I haven't found one that mentions pspiom or cslr.  Apparently I don't have the right file.  Where do I find it?

     

  • UPDATE:

    I tried a solution modeled on Brad Griffis's code (above) -- and it worked fine.  It assembled the interrupt vector table (from assembly code) and loaded it into memory.  Super.

    One caveat so far.  I haven't been able get it to load the interrupt vector table into the default location in memory (the default location specified in the ISTP control register (which is 0x00700000).  Instead, it allows me to load the interrupt vector table somewhere else in memory and then I must load the ISTP register with a pointer to that location. Why is that? 

    What must I do to load the interrupt vector table where the processor already expects it to be located? 

     

  • Walter Snafu said:
    One caveat so far.  I haven't been able get it to load the interrupt vector table into the default location in memory (the default location specified in the ISTP control register (which is 0x00700000).  Instead, it allows me to load the interrupt vector table somewhere else in memory and then I must load the ISTP register with a pointer to that location. Why is that? 

    First thing to check -- what is 0x00700000?

    As you can see that address corresponds to read only memory.  That's why you cannot put your table there, i.e. you cannot write to that address!  The L2 ROM is where we keep our bootloader.  When the device comes out of reset we always want our bootloader to execute.  If a reset occurred at run-time then the ISTP register would go back to its default value of 0x00700000 and the CPU would execute from the L2 ROM just like at power-up.

  • Walter Snafu said:
    vectors.asm contains code for the non-maskable master reset.  But my understanding is that such code would be completely ignored in the C6748, since the non-maskable master reset always runs its default code -- unchangeable by the user. 

    Although the name of it is "NMI", that vector actually gets used for both the NMI pin and exceptions.  For example, if an illegal instruction was executed you would execute that ISR.  There's actually a little more to it, i.e. you need to enable exceptions elsewhere.  You would need to read more from the "Exceptions" chapter in the CPU Reference Guide.  I didn't set it up in my example, but it's a really useful thing to enable.  Often during development it is easy to write some bad code (gasp!) that causes the CPU to jump off into the weeds.  Without exceptions enabled that can crash the whole CPU and from your perspective you'll just see CCS disconnect with some weird error.  If you enable exceptions many of those situations can be caught before the CPU goes haywire.

    Walter Snafu said:
    I'm also confused when vectors.asm references "_c_int00" , since that is a reserved keyword for the master reset entry point (which cannot be changed).

    It's not a reserved keyword, just a normal function that happens to be the typical entry point.

  • One other thing I should mention...  I did a "quick hack" in my vectors.asm file for branching to the ISR.  Here's how I did it:

    INT4:
            b    _my_isr
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP

    The reason I call it a hack is because that particular branch instruction is a relative branch instruction and will only be able to "reach" +/- 2MB (or maybe it was +/- 4MB).  So if for example vectors.asm is located in internal memory you could not branch to an ISR in external memory.  The "proper" way to right this would be as follows.  Here's a copy/paste of the code that BIOS uses (this is for the case where BIOS does not use the "dispatcher" so it would be like yours):

                        stw b0,*b15--[2]        ; temp save b0 on stack
                        mvkl isr_name,b0 ; load destination address to b0
                        mvkh isr_name,b0
                        b b0                    ; start branch to destination
                        ldw *++b15[2],b0        ; restore b0 register
                        nop 2                   ; fill 2 of b0 restore delay slots
                        nop                     ; fill delay slot, pad packet
                        nop                     ; fill delay slot, pad packet

    So I recommend using the above format for your ISRs rather than the "hack" that I did.

    Brad

     

     

     

  • One final note -- why are you not using BIOS?!  It is AWESOME!  It will setup the interrupts for you, setup the exceptions that I mentioned before, not to mention provides you a ton of useful functions and capabilities.  I recommend reconsidering on BIOS as it will likely prevent you from making a lot of mistakes!

  • Walter Snafu said:

    P.S.  Mukul suggested I look in the "PSP driver package".  But I haven't found one that mentions pspiom or cslr.  Apparently I don't have the right file.  Where do I find it?

     

    If you download the latest SW packages from

    http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/omap_l138/1_00/latest/index_FDS.html

    or

    http://www.ti.com/omapl138c6748sw  (takes you to the above link)

    It has

    C6748_dsp_setupwin32_1_00_00_08.exe Windows C6748 DSP Installer

    Once you install the above, you will find another .exe (BIOSPSP_01_30_00_Setup.exe), this installer has the driver package for peripherals on c6748, part of that package are simple non-bios register CSL (chip support library) based examples for some modules including DSP Interrupt Controller (INTC).

    pspdrivers_01_30_00\packages\ti\pspiom\cslr\evm6748\examples\intc\src

    Regards

    Mukul

  • Brad,

    THANK YOU!!!  You're super clear and super helpful. 

     

    FYI, I'll show something that was confusing me.  From the C674x Instruction Set manual:

    "After reset, you can relocate the IST by writing a new value to ISTB. If relocated, the first ISFP (corresponding to RESET) is never executed via interrupt processing, because reset clears the ISTB to its default value."  [page 46 -- Table 2-15. Interrupt Service Table Pointer Register (ISTP) Field Descriptions]

    The manual indicates "you can relocate the Interrupt Service Table".  When the fact is you MUST relocate it, if you want to set interrupt vectors different from the default.  [This is because (as you showed), on powerup, the ISTB points to an Interrupt Service Table in ROM, which cannot be changed.] 

  • I see what you mean.  To give you a little other insight, this register has been part of the c6000 architecture going all the way back to the 62x devices 10 years ago (or more!).  I had an old CPU Reference Guide from 2003 that has the following paragraph:

    "After reset, you can relocate the IST by writing a new value to ISTB.  If relocated, the first ISFP (corresponding to RESET) is never executed via interrupt processing, because reset sets the ISTB to 0."

    Sound familiar?!  :)  Back then it used to default to a value of 0 which happened to correspond to RAM.  That was back before ROM bootloaders existed (or at least before they were typical) and so at that time it was actually possible to put your vector table at that address and never change ISTP.

    One more thing to keep in mind is that the 674x Instruction Set manual is generic to the core, so depending on how we did our device integration you may or may not need to change that register.  In other words, it might not always be necessary to change it depending on the device we make.

    Glad you have it all working now.

     

  • Brad and Mukul,

    Thank you both for recommending that I install the BIOSPSP package.  Lots of goodies there for me to study and learn from. 

     

  • I'm comparing Brad's interrupt service routine with the one given in pspdrivers_01_30_00\packages\ti\pspiom\cslr\evm6748\examples\intc\src

    Brad uses something that seems essential, yet it is not within the BIOSPSP example:

    ; tell assembler not to use 16-bit compact instruction
    ; or else the vectors will not reside properly in memory
    ; (applies to entire section in which it is contained)
    .nocmp

     Without that assembler directive, the interrupt table will likely not assemble correctly into the interrupt fetch packet.

  • Interesting.  I couldn't find it documented, but perhaps macros have some kind of implicit alignment.  I verified in the map file that they definitely have the correct alignment.