Other Parts Discussed in Thread: C2000WARE
Hey,
I am using the TMS320F280039C and I'm wanting to trigger a software interrupt. I see the CPU timers but is there a way to simply trigger a software interrupt? If not, I can make the CPU timers work.
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.
Hey,
I am using the TMS320F280039C and I'm wanting to trigger a software interrupt. I see the CPU timers but is there a way to simply trigger a software interrupt? If not, I can make the CPU timers work.
Hi Derek,
Thanks for the question! Just to clarify, when you mean software interrupt, do you mean the USER 1-12 interrupts (the "User-Defined Trap") interrupts? If so, these can be triggered with the TRAP command (excerpt below from SPRU430, "TMS320C28x CPU and Instruction Set"):
If you are referring to the peripheral interrupts (part of the ePIE) then these can simply be forced by setting the flag registers for the respective interrupt. For example, in the diagram from the TRM below, you can just set the PIEIFRx.y for whichever interrupt you want to trigger:
I hope this helps with getting started!
Regards,
Vince
I am looking for a interrupt I can trigger from another interrupt. Basically I have a 250us interrupt and every 4th interrupt I want to trigger another interrupt to start. What would be best for this and is there a demo on how to use it?
For ARM for instance, I was using an ADC interrupt and then triggering a SWI (software interrupt) every 4th run of the ADC interrupt. It's a fast / slow thread sort of structure.
Hi Derek,
Thanks for the clarification, the USER* interrupts are exactly what you're looking for then.
While we don't have an example that directly uses the USER* interrupts, from the standpoint of enabling/handling in the ISR itself they are functionally identical to the CPU TIMER1/TIMER2 interrupts in the following C2000Ware driverlib example:
C2000Ware_####\driverlib\f28003x\examples\timer\timer_ex1_cputimers.c
So basically when going from CPU TIMER interrupts to USER# interrupts, you'll register the interrupts the same (but for the correct USER# values), enable interrupts the same, and in the ISR itself, want to clear the AC_GROUP#s similarly.
The reason they're handled the same as the TIMER interrupts is because they are at the level of an interrupt "Group", see how they are in the same CPU Interrupt Vector table as the CPU TIMER# interrupts:
I hope this helps!
Regards,
Vince
Just to clarify that -
How would I go about enabling and generating the USER interrupt 1? I can't use the CPU_Timer functions can I? I don't see a base address for the user interrupts that would be written into HWREGH?
Hi Derek,
To register and enable the interrupt, you need:
1. "Interrupt_register" function, but substitute for your USER# interrupt. All values for user defined traps can be found in:
driverlib\f28003x\driverlib\inc\hw_ints.h
Example:
#define INT_ILLEGAL 0x00130000U // Illegal Operation Trap #define INT_USER1 0x00140000U // User Defined Trap 1 #define INT_USER2 0x00150000U // User Defined Trap 2 #define INT_USER3 0x00160000U // User Defined Trap 3 #define INT_USER4 0x00170000U // User Defined Trap 4 #define INT_USER5 0x00180000U // User Defined Trap 5 #define INT_USER6 0x00190000U // User Defined Trap 6 #define INT_USER7 0x001A0000U // User Defined Trap 7 #define INT_USER8 0x001B0000U // User Defined Trap 8 #define INT_USER9 0x001C0000U // User Defined Trap 9 #define INT_USER10 0x001D0000U // User Defined Trap 10 #define INT_USER11 0x001E0000U // User Defined Trap 11 #define INT_USER12 0x001F0000U // User Defined Trap 12
2. Now just call the "Interrupt_enable" function for your chosen trap interrupt above:
Example (substitute the TIMERs for the USER#):
Interrupt_enable(INT_TIMER0); Interrupt_enable(INT_TIMER1); Interrupt_enable(INT_TIMER2);
Now that you've registered and enabled them, just trigger these "trap" interrupts inside of the other interrupts using what I mentioned in the first post (the "TRAP" instruction).
Regards,
Vince
All I have to do to initialize the interrupt is this?
Interrupt_register(INT_USER1, &usr1SlowThreadISR);
Interrupt_enable(INT_USER1);
How do I issue the "TRAP" instruction to trigger the interrupt?
Hi Derek,
For using the TRAP instruction, it is as I mentioned in the first post, you will need to run an assembly instruction with the "TRAP" instruction for the given USER#. In the image in that post, you can see that "USER1" is Vector #20. So to call the USER1 ISR, you would simply need to do something like:
asm(" TRAP #20"); // Vector to User interrupt #1
Though, having said all this, I should note you could also just do a function call instead of an "ISR" like this TRAP call. All you would need to do is disable interrupts inside that function so it doesn't get interrupted. Something like
function_name(){ DINT; // DISABLE INTERRUPTS //rest of function code EINT; // ENABLE INTERRUPTS }
Regards,
Vince
Thanks for the help!
So I did this to initialize the interrupt:
This to trigger the interrupt:
How to do acknowledge the interrupt and how do I set the priority of the interrupt? I don't see the USER interrupts listed in the PIEIER registers. I want USER1 to be lower priority than all of my other interrupts. For instance, I want this interrupt to be priority 15 whereas I have my motor control interrupt at priority 13 and my SPI interrupt to read my resolver at priority 6.
USER1 is not in group 1, but I acknowledge group 1 interrupts like this from other demos. How do I acknowledge and set priority of USER interrupts?
Hi,
These USER interrupts do not need to be acknowledged since they are essentially function calls. For prioritization, there is no default priority for the USER interrupts so you must prioritize them within your code. When the USER ISR enters, you will need to check what interrupts are already triggered and make a decision in the ISR.
Regards,
Vince
Thanks for your help! I will try the USER interrupt. As long as it's low priority that's probably ok. We'll see how it goes. I might switch back to trying to utilize a CPU timer if I find the USER interrupt does not work well for my application.
I could theoretically use a CPU timer the same way I think - use CPUTimer_startTimer to start a timer with a fixed short delay (10us or something). Then I can stop the timer until next time I want to trigger an interrupt.