So yesterday i got a new gadget to play with, the M52235EVB with the MCF52235 chip. I've managed to load it with the sample code and run it successfully. I also managed to configure the GPIO and make the LEDs flash, yay considering I'm a complete newbie to Freescale .
The I proceeded to look into using an external interrupt to switch an LED on. The EVB has switches connected to IRQ1, IRQ4 and IRQ11. So i decided to configure IRQ4 (Switch 1). Based on all the reading I've done on the questions asked in the forum and the Reference Manual the code below should work:
void ini_interrupts(){ // Setup pin as IRQ4 pin MCF_GPIO_PNQPAR = 0 | MCF_GPIO_PNQPAR_IRQ4_IRQ4; // Set the type of signal level MCF_EPORT0_EPPAR = 0 | MCF_EPORT_EPPAR_EPPA4_LEVEL; // Enable IRQ4 MCF_EPORT0_EPIER = 0 | MCF_EPORT_EPIER_EPIE4; // Define the interrupt prioirty and level for IRQ4 MCF_INTC0_ICR04 = 0 | MCF_INTC_ICR_IP(4) | MCF_INTC_ICR_IL(4); // Unmask IRQ4 MCF_INTC0_IMRL = 0 | ~(MCF_INTC_IMRL_INT_MASK4|MCF_INTC_IMRL_MASKALL);}
So i've set the pin to IRQ4, set the signal level, enabled IRQ4 and unmasked it. Now i need to add the handler subroutine in the interrupt table "vectors.s"...so here's the problem, where do i find this file?? Searched for it but can't find it. How do i create a new one. Any help would be appreciated, thank you.
Solved! Go to Solution.
So after much reading and valuable input from mjbcswitzerland and input from Freescale after submitting a service request I have finally solved the problem of using SW1 (IRQ4 on M52235EVB) to switch on the LEDs . I want to post the solution for all future newbies / beginners / new to Freescale people. For all those looking to setup a simple IRQ interrupt or even make an LED flash (my first task) you can use this example. My main.c looks like:
#include "support_common.h" /* include peripheral declarations and more */ #if (CONSOLE_IO_SUPPORT || ENABLE_UART_SUPPORT) /* Standard IO is only possible if Console or UART support is enabled. */ #include <stdio.h> #endif void ini_interrupts() { // Setup pin as IRQ4 pin MCF_GPIO_PNQPAR = 0 | MCF_GPIO_PNQPAR_IRQ4_IRQ4; // Set the type of signal level MCF_EPORT0_EPPAR = 0 | MCF_EPORT_EPPAR_EPPA4_LEVEL; // Enable IRQ4 MCF_EPORT0_EPIER = 0 | MCF_EPORT_EPIER_EPIE4; // Define the interrupt prioirty and level for IRQ4 MCF_INTC0_ICR04 = 0 | MCF_INTC_ICR_IP(4) | MCF_INTC_ICR_IL(4); // Unmask IRQ4 MCF_INTC0_IMRL = 0 | ~(MCF_INTC_IMRL_INT_MASK4|MCF_INTC_IMRL_MASKALL); // Enable global interrupts asm(move.w #0x2000,SR); } void ini_LED() { /* Enable signals as GPIO */ MCF_GPIO_PTCPAR = 0 | MCF_GPIO_PTCPAR_DTIN3_GPIO | MCF_GPIO_PTCPAR_DTIN2_GPIO | MCF_GPIO_PTCPAR_DTIN1_GPIO | MCF_GPIO_PTCPAR_DTIN0_GPIO; /* Enable signals as digital outputs */ MCF_GPIO_DDRTC = 0 | MCF_GPIO_DDRTC_DDRTC3 | MCF_GPIO_DDRTC_DDRTC2 | MCF_GPIO_DDRTC_DDRTC1 | MCF_GPIO_DDRTC_DDRTC0; MCF_GPIO_PORTTC = 0; // TURN LEDS OFF } int main(void) { ini_interrupts(); // Initialise interrupt ini_LED(); // Set up LEDs for the M52235EVB Board while (1) { ; // Infinite do nothing loop } } // ISR to switch LEDs on __declspec(interrupt) void irq4_isr() { //Switch LEDs on MCF_GPIO_PORTTC = 0xFF; //Clear IRQ4 flag MCF_EPORT0_EPFR = 0 | MCF_EPORT_EPFR_EPF4; }
The "exceptions.c" file is too big to post so i've just attached it. This is for all people who use CodeWarrior and were as confused as I was as to "where is the vector table?" (Topic title). Enjoy .
So i've opened up the "exceptions.c" file...i can see a part of the file that looks like a vector table, but i'm not sure how exactly to add my interrupt handler to the list. I know it should be vector number 68 (64 + 4 (IRQ4)). How do I add it and then where do i write the actual routine to handle the interrupt??
How do I attach the "exceptions.c" and "exceptions.h" files to this post.... can't find anything in the reply menu
Hi, I found it. I've attached the "exceptions.c" and "exceptions.h" files.
Please can you help me as to where I must put in my IRQ4 interrupt stuff...I know it's vector number 68.
Thanks.
Hi
IRQ4 is indeed exception 68, so you can place your routine at that location:
asm_exception_handler, /* 68 (0x110) Device-specific interrupts */
(plug in the name of your IRQ in place of the default exception hanlder)
the list of exceptions in the file exceptions.c doesn't otherwise seem to suit the M5223X (only the comments). Below is a complete list of M522XX exceptions (in hex rather than decimal - just convert and plug into the correct location as required) :
#define IRQ1_VECTOR 0x41
#define IRQ2_VECTOR 0x42
#define IRQ3_VECTOR 0x43
#define IRQ4_VECTOR 0x44 // decimal 68
#define IRQ5_VECTOR 0x45
#define IRQ6_VECTOR 0x46
#define IRQ7_VECTOR 0x47
#define SW_WD_VECTOR 0x48
#define DMA0_VECTOR 0x49
#define DMA1_VECTOR 0x4a
#define DMA2_VECTOR 0x4b
#define DMA3_VECTOR 0x4c
#define UART0_VECTOR 0x4d
#define UART1_VECTOR 0x4e
#define UART2_VECTOR 0x4f
#define IIC_VECTOR 0x51
#define QSPI_VECTOR 0x52
#define DTIM0_VECTOR 0x53
#define DTIM1_VECTOR 0x54
#define DTIM2_VECTOR 0x55
#define DTIM3_VECTOR 0x56
#define FEC_TX_F_VECTOR 0x57
#define FEC_TX_B_VECTOR 0x58
#define FEC_TX_UND_VECTOR 0x59
#define FEC_COLL_VECTOR 0x5a
#define FEC_RX_F_VECTOR 0x5b
#define FEC_RX_B_VECTOR 0x5c
#define FEC_MII_VECTOR 0x5d
#define FEC_LATE_VECTOR 0x5e
#define FEC_HB_VECTOR 0x5f
#define FEC_STOP_VECTOR 0x60
#define FEC_BERR_VECTOR 0x61
#define FEC_BAB_TX_VECTOR 0x62
#define FEC_BAB_RX_VECTOR 0x63
#define EPHY_VECTOR 0x64
#define GPT_TOF_VECTOR 0x69
#define GPT_PAIF_VECTOR 0x6a
#define GPT_PAOVF_VECTOR 0x6b
#define GPT_C0F_VECTOR 0x6c
#define GPT_C1F_VECTOR 0x6d
#define GPT_C2F_VECTOR 0x6e
#define GPT_C3F_VECTOR 0x6f
#define PMM_LVDF_VECTOR 0x70
#define ADC_ADCA_VECTOR 0x71
#define ADC_ADCB_VECTOR 0x72
#define ADC_ADCINT_VECTOR 0x73
#define PWM_INT_VECTOR 0x74
#define RNGA_VECTOR 0x75
#define USB_OTG_VECTOR 0x75 // M5222X / M5221X
#define PIT0_VECTOR 0x77
#define PIT1_VECTOR 0x78
#define CFM_CBEIF_VECTOR 0x7b
#define CFM_CCIF_VECTOR 0x7c
#define CFM_PVIF_VECTOR 0x7d
#define CFM_AEIF_VECTOR 0x7e
#define IIC_1_VECTOR 0x7e // M5221X
#define RTC_VECTOR 0x7f
#define CAN0_VECTOR 0x88
#define CAN1_VECTOR 0x89
#define CAN2_VECTOR 0x8a
#define CAN3_VECTOR 0x8b
#define CAN4_VECTOR 0x8c
#define CAN5_VECTOR 0x8d
#define CAN6_VECTOR 0x8e
#define CAN7_VECTOR 0x8f
#define CAN8_VECTOR 0x90
#define CAN9_VECTOR 0x91
#define CAN10_VECTOR 0x92
#define CAN11_VECTOR 0x93
#define CAN12_VECTOR 0x94
#define CAN13_VECTOR 0x95
#define CAN14_VECTOR 0x96
#define CAN15_VECTOR 0x97
#define CANERR_VECTOR 0x98
#define CANBOFF_VECTOR 0x99
#define IRQ8_VECTOR 0xa0
#define IRQ9_VECTOR 0xa1
#define IRQ10_VECTOR 0xa2
#define IRQ11_VECTOR 0xa3
#define IRQ12_VECTOR 0xa4
#define IRQ13_VECTOR 0xa5
#define IRQ14_VECTOR 0xa6
#define IRQ15_VECTOR 0xa7
Note however that usually this table is not used directly from FLASH since it doesn't allow exchanging interrupts at run time but that is a project decision.
Don't forget to declare yout interrupt handler accordingly so that CodeWarrior compiles it correctly. Eg.
static __interrupt__ void _irq4_handler(void)
{
...
}
When using GCC it needs a prototype like:
static void _irq4_handler(void) __attribute__((interrupt_handler));
Regards
Mark
Ok I'm a bit confused about the exceptions not seeming to suit the M5223X family and the list that you wrote, where should this be placed? What I did do is in the "exceptions.c" file declare the interrupt handler:
extern void my_irq();
Then in the list below I added this handler in the list:
asm_exception_handler, /* 66 (0x108) */ asm_exception_handler, /* 67 (0x10C) */ my_irq, /* 68 (0x110) */ asm_exception_handler, /* 69 (0x114) */ asm_exception_handler, /* 70 (0x118) */ asm_exception_handler, /* 71 (0x11C) */
Then at the bottom of the "main.c" file I wrote my interrupt handler to light the LEDs as a sign that the interrupt occured:
void my_irq() { MCF_GPIO_PORTTC = 0x0F; }
This compiles with no errors but the LEDs don't flash .
I know the LEDs are configured correctly because I can switch them on and off in the main routine.
Hi
The exception.c is a general file for all Coldfire (which are however not all the same). It is only the comments which don't match - they are probably from a big Coldfire so only a detail. See the list for your processor in teh user's manual section 15.3.6.1
If you don't declare your interrupt correctly (use __interrupt__ atribute) the interrupt routine will crash on return because it will be compiled to return with RTS rather than RTE. Perhaps it enters once and then hangs(?).
Your routine must also clear the interrupt - for IRQ4 by doing
EPFR0 = 0x10; // clear interrupt flag
If you don't do this it will re-enter again immediately and the LED will blink so fast that it looks to be not blinking at all.
Further it may be that your code is not using the interrupts defined in exceptions.c but instead points the VBR (Vector Base Register)to the start of SRAM. In this case you need to ensure that there is either a memcpy() of the const set in exceptions.c to SRAM, or your routine is entered there.
Finally check that interrupts have been unmasked in the SR so that peripheral interrupts can occur (usually there is a routine called something like asm_int_on() to do this).
Regards
Mark
So after much reading and valuable input from mjbcswitzerland and input from Freescale after submitting a service request I have finally solved the problem of using SW1 (IRQ4 on M52235EVB) to switch on the LEDs . I want to post the solution for all future newbies / beginners / new to Freescale people. For all those looking to setup a simple IRQ interrupt or even make an LED flash (my first task) you can use this example. My main.c looks like:
#include "support_common.h" /* include peripheral declarations and more */ #if (CONSOLE_IO_SUPPORT || ENABLE_UART_SUPPORT) /* Standard IO is only possible if Console or UART support is enabled. */ #include <stdio.h> #endif void ini_interrupts() { // Setup pin as IRQ4 pin MCF_GPIO_PNQPAR = 0 | MCF_GPIO_PNQPAR_IRQ4_IRQ4; // Set the type of signal level MCF_EPORT0_EPPAR = 0 | MCF_EPORT_EPPAR_EPPA4_LEVEL; // Enable IRQ4 MCF_EPORT0_EPIER = 0 | MCF_EPORT_EPIER_EPIE4; // Define the interrupt prioirty and level for IRQ4 MCF_INTC0_ICR04 = 0 | MCF_INTC_ICR_IP(4) | MCF_INTC_ICR_IL(4); // Unmask IRQ4 MCF_INTC0_IMRL = 0 | ~(MCF_INTC_IMRL_INT_MASK4|MCF_INTC_IMRL_MASKALL); // Enable global interrupts asm(move.w #0x2000,SR); } void ini_LED() { /* Enable signals as GPIO */ MCF_GPIO_PTCPAR = 0 | MCF_GPIO_PTCPAR_DTIN3_GPIO | MCF_GPIO_PTCPAR_DTIN2_GPIO | MCF_GPIO_PTCPAR_DTIN1_GPIO | MCF_GPIO_PTCPAR_DTIN0_GPIO; /* Enable signals as digital outputs */ MCF_GPIO_DDRTC = 0 | MCF_GPIO_DDRTC_DDRTC3 | MCF_GPIO_DDRTC_DDRTC2 | MCF_GPIO_DDRTC_DDRTC1 | MCF_GPIO_DDRTC_DDRTC0; MCF_GPIO_PORTTC = 0; // TURN LEDS OFF } int main(void) { ini_interrupts(); // Initialise interrupt ini_LED(); // Set up LEDs for the M52235EVB Board while (1) { ; // Infinite do nothing loop } } // ISR to switch LEDs on __declspec(interrupt) void irq4_isr() { //Switch LEDs on MCF_GPIO_PORTTC = 0xFF; //Clear IRQ4 flag MCF_EPORT0_EPFR = 0 | MCF_EPORT_EPFR_EPF4; }
The "exceptions.c" file is too big to post so i've just attached it. This is for all people who use CodeWarrior and were as confused as I was as to "where is the vector table?" (Topic title). Enjoy .
Hi
Often the vector table is positioned at the start of SRAM (it can also be fixed at the start of FLASH but this is generally less flexible). When in SRAM it is usually defined in the linker script file, so will not be found in directly in code (often called __VECTOR_RAM).
The specific handler is then enetere into the SRAMusing somethig like the following:
__VECTOR_RAM[iVectNumber] = (unsigned long)new_handler;
Note also that the vector base register can only be written using specific instruction and so you should find the configuration somewhere looking something like:
mcf5xxx_wr_vbr((unsigned long)__VECTOR_RAM);
Regards
Mark
www.uTasker.com
- OS, TCP/IP stack, USB, device drivers and simulator for M521X, M521XX, M5221X, M5222X, M5223X, M5225X. One package does them all - "Embedding it better..."