Can anyone help me with the handling interrupts in kinetis k60?
Hi,
Are you using Processor Expert?
If not, first you need to use Enable the Interrupts:
After this you need to code your ISR e.g
void My_ISR() {
//ISR code
}
and put the name in the specific vector in Project_Settings-->Startup_Code-->kinetis_sysinit.c (do not forget to put the prototype as external in kinetis_sysinit.c)
In the attachments you can find the code for enable_irq().
If you need it I can post an example later,
Regards.
I have an issue with the supplied 'How to handle interrupts in kinetis k60.txt', and it is the same issue I have with the arm_cm4 files I find in Freescale example code. The register name NVICICPR0 is short for 'NVIC Interrupt Clear Pending Register 0', and NVICISER0 is 'NVIC Interrupt Set Enable Register 0' (as described in 'DUI0553A_cortex_m4_dgug.pdf'). 'Set' and 'Clear' registers, like those also available on Port I/O in Kinetis (such as Port A 'set' GPIOA_PSOR), accept '1' bits to perform the named function, and zero bits where NOT to perform any action. So first and foremost it is unnecessary to 'or equals' (|=) those kinds of registers, and simply writing the '1' bit(s) does exactly what you want and sets or clears the appropriate bit(s) in said register. However, for something like NVICICPR0 (and NVICICER0 as is in the matching disable_irq function) this 'or equals' Read-Modify-Write sequence has a VERY UNDESIRED side effect, in that the NVICICPR0 'read' will return '1' bits for ALL pending interrupts at the time, and thus the write-back will clear ANY pending interrupt, not only on the 'desired' new-interrupt, throwing them all away! Similarly, the original 'disable_irq' code using a RMW of NVICICER0 will clear ALL interrupts enabled in that register, as the 'read' operation returns ALL currently enabled interrupts.
Corrected code, with some optimization:
void enable_irq (int irq)
{
int div;
register long int Ibit;
/* Make sure that the IRQ is an allowable number. Right now up to 91 is
* used.
*/
if (irq > 91)
printf("\nERR! Invalid IRQ value passed to enable irq function!\n");
/* Determine which of the NVICISERs corresponds to the irq */
div = irq & (3*32);
Ibit = 1 << (irq & (32-1));
switch (div)
{
case (0*32):
NVICICPR0 = Ibit;
NVICISER0 = Ibit;
break;
case (1*32):
NVICICPR1 = Ibit;
NVICISER1 = Ibit;
break;
case (2*32):
NVICICPR2 = Ibit;
NVICISER2 = Ibit;
break;
}
}
void disable_irq (int irq)
{
int div;
register long int Ibit;
/* Make sure that the IRQ is an allowable number. Right now up to 91 is
* used.
*/
if (irq > 91)
printf("\nERR! Invalid IRQ value passed to disable irq function!\n");
/* Determine which of the NVICICERs corresponds to the irq */
div = irq & (3*32);
Ibit = 1 << (irq & (32-1));
switch (div)
{
case (0*32):
NVICICER0 = Ibit;
break;
case (1*32):
NVICICER1 = Ibit;
break;
case (2*32):
NVICICER2 = Ibit;
break;
}
}
Yes, it means nobody should try to use the samples as a library. For serious projects all this has to be rewritten. In fact the KL0x processors have a bit manipulation engine BME that implements decorated storage like PSOR, PCOR, PTOR for all peripherals except the private peripherals of the core. For example if you define a macro
#define ioorw(dest) *(uint32_t *)((((int)&dest) & 0x000FFFFC) | 0x48000000)
instead of writing
// enable clock gate for LPTMR module | |
SIM_SCGC5 |= SIM_SCGC5_LPTMR_MASK; |
you can write
// enable clock gate for LPTMR module | |
ioorh(SIM_SCGC5) = SIM_SCGC5_LPTMR_MASK; |
and you will typically have 3 instead of 5 code words. The BME has several functions like this. The KL05-SC examples do not show this at all. If you use the samples as a library, you will have code overhead - and even errors as mentioned above.
If this is true, the compiler should figure this out, not the programmer.
And you know what else would be SWEET -- if the compilers would work with the BME and packed booleans (and other packed fields???) in RAM!
Well, if the compiler does not know about the BME, then the attempted optimizations will have no effect.
No, the compiler will never convert a = operator back into a |= operator, but it could do the other way if it knew about decorated storage. For me, these optimizations work as described and i think a 70 percent performance improvement on many low level operations is something important. If there was any know-how in the freescale team on using decorated storage and on compilers doing it automatically, they did not respond until now to my earlier question on BME.
what is "decorated storage" Google does not know
search for "BME Kinetis". 'Decorated storage' means that the address bits have a 'decoration': one or multiple bits added to the physical address bits to tell the hardware to do something special. Freescale is using BME (Bit Manipulation Engine) with decorated storage to have atomic bit operations performed by the M0+ core, as there is no 'bit banding' as in the ARM Cortex M3 core.
By the way, speaking of Port Set/Clear/Toggle PSOR, PCOR, PTOR usage, I see in places in Freescale 'demo' code where they do '|=' (or equals) on those also! There is no HARM in doing this, as these registers always read ZERO, but it is certainly a WASTE of time & space! As such, they are a 'poor example'!
Hi,
In the attachments you will find the project TWR-K60-IRQ-SW1 in CW 10.3 (TWR-K60N512 at 100 Mhz) . It uses the Interrupt of PORTA, entries in ISR (Interrupt Service Routine) when SW1 is Pressed and toggle one led.
Let me know if you have any problems with this.
Hope this helps,
Regards.
On Wed, Apr 10, 2013 at 10:46 PM, Adrian Sanchez Cano <