MCF52235EVB - Help with Interrupts

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MCF52235EVB - Help with Interrupts

5,215 Views
ornini
Contributor I
Hi,
 
I'm learning how to use the coldfire MC, using the MCF52235EVB, and I need some help.
 
Does anyone has a simple code for configuration of an external Interrupt. I mean I want to handle a task as soon as I recieved an external Interrupt from external source.
 
Thanks in advance

--
Alban Edit: Please always mention part number in subject line.



Message Edited by Alban on 2007-07-09 04:53 PM
Labels (1)
0 Kudos
9 Replies

972 Views
ornini
Contributor I
STILL DOES NOT WORK
 
I add the last instruction as you said, and I've changed the level sensetive to BOTH.
 
 MCF_GPIO_PNQPAR = 0 | MCF_GPIO_PNQPAR_IRQ1_IRQ1;
 MCF_EPORT_EPPAR0 = 0 | MCF_EPORT_EPPAR_EPPA1_BOTH;
 MCF_EPORT_EPIER0 = 0 | MCF_EPORT_EPIER_EPIE1;
 MCF_INTC0_ICR1 =  (MCF_INTC_ICR_IL(4) | MCF_INTC_ICR_IP(4));
 MCF_INTC0_IMRL &= ~MCF_INTC_IMRL_MASK1;
Any Idea Please???
0 Kudos

972 Views
mjbcswitzerland
Specialist V
Hi

Do a last check so verify that the processor interrupts are not masked at the core.
Your start up file may or may not be doing this. If it is not, you will need to call something like asm_int_on() during the initialisation which will unmask the core interrupts:

This is the standard method which should be included in one of the stationary assembler files:
_asm_int_on:    link    A6,#-4    movem.l d7,(SP)    move.w  SR,D7           andi.l   #0xf8ff,d7  /* enable interrupts  */     move.w  D7,SR        movem.l (SP),D7    lea     4(SP),SP            unlk    A6           rts 

 the SR bits 8,9, and 10 are cleared so that all interrupt levels are allowed to interrupt the core.

It is best to use your debugger and look at the values of the SR (status register) and also the other registers that you have changed so that you are sure of what is going on - you can also see how far the interrupt is propogating through the chain - it must get set in the Eport interrupt register, then the interrupt controller interrupt register and finally cause the interrupt at the core.

If you still don't get any further I suggest that you register for the uTasker project at www.uTasker.com where you will then receive all code necessary. The project is free for all non-commercial work and includes direct support as well as in its own forum.

Regards

Mark

0 Kudos

972 Views
Kremer
Contributor I
 Ornini
 
 As in many micro controllers, the interrupt scheme has mask bits for each interrupt source and a mask all bit, to quick disable all interrupts at once.
 I don´t see in your code where you unmask all interrupts:
 
MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASKALL); // Unmask all interrupts
 
I see you included the unmask part for IRQ1, so keep this line on you code:
 
MCF_INTC0_IMRL &=  ~MCF_INTC_IMRL_MASK1;
 
 Regards
 
0 Kudos

972 Views
mjbcswitzerland
Specialist V
Yes, Kremer is right.
IC_IMRL_0 &= ~0x02; // unmask interrupt source
is correct when the general mask bit has ALREADY been cleared.

IC_IMRL_0 &= ~0x03; // unmask interrupt source AND MASK ALL BIT

This may be what is missing...

Regards

Mark

0 Kudos

972 Views
ornini
Contributor I
Sorry guys,
 
Don't know what to tell you - Still do not wanna work.
 
I looked at the disassemble file for any line of what Mark suggested - and I could not find anything like SR or andi.l   #0xf8ff,d7  /* enable interrupts  */
 
Maybe this can help ???
Code:
*******;   21:  MCF_GPIO_PNQPAR = (0 | MCF_GPIO_PNQPAR_IRQ1_IRQ1); ;0x0000000E  0x41F900000000           lea      ___IPSBAR,a00x00000014  0x223C00100068           move.l   #1048680,d1           ; '...h'0x0000001A  0x7004                   moveq    #4,d00x0000001C  0x31801800               move.w   d0,(a0,d1.l);;   22:  MCF_EPORT_EPPAR0 = (0 | MCF_EPORT_EPPAR_EPPA1_BOTH); ;0x00000020  0x41F900000000           lea      ___IPSBAR,a00x00000026  0x223C00130000           move.l   #1245184,d1           ; '....'0x0000002C  0x700C                   moveq    #12,d00x0000002E  0x31801800               move.w   d0,(a0,d1.l);;   23:  MCF_EPORT_EPIER0 = (0 | MCF_EPORT_EPIER_EPIE1); ;0x00000032  0x41F900000000           lea      ___IPSBAR,a00x00000038  0x223C00130003           move.l   #1245187,d1           ; '....'0x0000003E  0x7002                   moveq    #2,d00x00000040  0x11801800               move.b   d0,(a0,d1.l);;   24:  MCF_INTC0_ICR1 =  (MCF_INTC_ICR_IL(4) | MCF_INTC_ICR_IP(4)); ;0x00000044  0x41F900000000           lea      ___IPSBAR,a00x0000004A  0x7024                   moveq    #36,d00x0000004C  0x11400C41               move.b   d0,3137(a0);;   25:  MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASKALL); // Unmask all interrupts ;0x00000050  0x41F900000000           lea      ___IPSBAR,a00x00000056  0x41E80C0C               lea      3084(a0),a00x0000005A  0x2D48FFF8               move.l   a0,-8(a6)0x0000005E  0x226EFFF8               movea.l  -8(a6),a10x00000062  0x206EFFF8               movea.l  -8(a6),a00x00000066  0x70FE                   moveq    #-2,d00x00000068  0xC090                   and.l    (a0),d00x0000006A  0x2280                   move.l   d0,(a1);;   26:  MCF_INTC0_IMRL &= ~MCF_INTC_IMRL_MASK1; ;   27:     ;0x0000006C  0x41F900000000           lea      ___IPSBAR,a00x00000072  0x41E80C0C               lea      3084(a0),a00x00000076  0x2D48FFFC               move.l   a0,-4(a6)0x0000007A  0x226EFFFC               movea.l  -4(a6),a10x0000007E  0x206EFFFC               movea.l  -4(a6),a00x00000082  0x70FD                   moveq    #-3,d00x00000084  0xC090                   and.l    (a0),d00x00000086  0x2280                   move.l   d0,(a1);********;   58: __interrupt__ void irq_1_isr(void) ;   59: { ;0x00000000                    _irq_1_isr:;                             irq_1_isr:0x00000000  0x4E560000               link     a6,#00x00000004  0x4FEFFFF4               lea      -12(a7),a70x00000008  0x48D70103               movem.l  d0-d1/a0,(a7);;   60:  while (!(MCF_EPORT_EPPDR0 & MCF_EPORT_EPPDR_EPPD1)) {}; ;0x0000000C  0x41F900000000           lea      ___IPSBAR,a00x00000012  0x203C00130005           move.l   #1245189,d0           ; '....'0x00000018  0x12300800               move.b   (a0,d0.l),d10x0000001C  0x7000                   moveq    #0,d00x0000001E  0x1001                   move.b   d1,d00x00000020  0x028000000002           andi.l   #0x2,d0               ; '....'0x00000026  0x4A80                   tst.l    d00x00000028  0x67E2                   beq.s    *-28                  ; 0x0000000c;;   61:  stop=1; ;0x0000002A  0x7001                   moveq    #1,d00x0000002C  0x13C000000000           move.b   d0,_stop0x00000032  0x4CD70103               movem.l  (a7),d0-d1/a00x00000036  0x4E5E                   unlk     a60x00000038  0x4E73                   rte      0x0000003A  0x4E71                   nop      *******Thanks againI really appreciate your help


 


0 Kudos

972 Views
Kremer
Contributor I
 As Mark pointed before, try to use level sensing instead of edge sensing when working with switches.
 
CF_EPORT_EPPAR0 = 0  | MCF_EPORT_EPPAR_EPPA4_LEVEL;
 
Regards
0 Kudos

972 Views
mjbcswitzerland
Specialist V
Hi

Take a look at the uTasker project - it is free for education/hobby work and also includes all that you need for working with the IRQs in the M52235.

The following shows the set up of a port interrupt in user code where IRQ1 (any IRQ from 1..15 is supported in the M52235) is assigned a user definable priority, to be falling/rising/both or level sensitive and given a user call back routine (test_irq_1() in this case).

    INTERRUPT_SETUP interrupt_setup;                                     // interrupt configuration parameters    interrupt_setup.int_type     = PORT_INTERRUPT;                       // identifier when configuring    interrupt_setup.int_handler  = test_irq_1;                           // handling function    interrupt_setup.int_priority = (INTERRUPT_LEVEL_2);                  // low priority    interrupt_setup.int_port_bit = 1;                                    // The IRQ input connected    interrupt_setup.int_port_sense = IRQ_BOTH_EDGES;                     // Interrupt on this edge    fnConfigureInterrupt((void *)&interrupt_setup);                      // configure test interrupt

 In this case the call back routine can be declared as a normal subroutine and the set up of all registers and handling of the IRQ itself is performed in the driver code. The driver source code is included if the low level details are required.
The uTasker project has an integrated M52235 simulator so you can test the set up and interrupt routines by simply clicking on the ports (which will be displayed as IRQ inputs rather than GPIO if configured correctly). The IRQ will be called according to the port set up (the edge or edges selected) so this can also be verified.

You can get full details at www.uTasker.com
Note too that the uTasker project is fully supported per email and, as from 9.7.2007, from its own forum - a preview is also available at the link (under forum) and any one can register once it goes on-line!

Regards

Mark  Butcher


0 Kudos

972 Views
Kremer
Contributor I
 Basically you need:
 
1) Setup the desired pin to work as a IRQ (one of the alternate functions) by configuring the Port´s registers.
 
MCF_GPIO_PNQPAR = 0 | MCF_GPIO_PNQPAR_IRQ1_IRQ1;
 
2)  Setup the type of trigger signal for this IRQ (edge, level, type of edge...)
 
MCF_EPORT_EPPAR0 = 0 | MCF_EPORT_EPPAR_EPPA1_LEVEL;
 
3) Clear any possible existing interrupt from that IRQ
 
MCF_EPORT_EPIER0 = 0 | MCF_EPORT_EPIER_EPIE1;
 
4) Define the interrupt level and priority
 
MCF_INTC0_ICR1 =  (INTERRUPT_LEVEL_4 | INTERRUPT_PRIORITY_4);
 
5) Add the isr address to vector list (on vectors.s)
 
vector41:   .long   _irq_1_isr//_irq1_handler
 
6) Write the isr and specify it as so:
 
__declspec(interrupt) void irq_1_isr(void)
{
 
 Your code here...
 
}
 
 Or
 
Download Coldfire_Lite from this link:
 
 
This is a complete example for 5223X and it uses the EVB switches as external interrupts. All the code is there.
0 Kudos

972 Views
ornini
Contributor I
Thanks for the quick responses, but unfurtiontly I still can't perform a simple Interrupt request.
 
I try on the EVB to press SW3 (IRQ1) in order to activate the interrupt.
 
Kremer, I try to follow your instructions, but I probably miss something.
 
First file is the main.c:
Code:
/* * File:  main.c * Purpose:  sample program * */#include <stdio.h>#include "common.h" unsigned char stop=0; void delay(int t_end){ int i,j; for (i=0;i<t_end;i++) {  for(j=0;j<10000;j++);  }}int main(){ unsigned char i;     MCF_GPIO_PNQPAR = 0 | MCF_GPIO_PNQPAR_IRQ1_IRQ1; MCF_EPORT_EPPAR0 = 0 | MCF_EPORT_EPPAR_EPPA1_LEVEL; MCF_EPORT_EPIER0 = 0 | MCF_EPORT_EPIER_EPIE1; MCF_INTC0_ICR1 =  (MCF_INTC_ICR_IL(4) | MCF_INTC_ICR_IP(4)); Leds_Init(); while(1) {  for (i=0; i<0x10; i++)  {//   board_led_display(i); //   delay(100);   if (stop==1)   {    return;   }  }   }  return 0;}__interrupt__ void irq_1_isr(void){ while (!(MCF_EPORT_EPPDR0 & MCF_EPORT_EPPDR_EPPD1)) {}; stop=1;}

 
2nd file that I've changed is:
Code:
  .  .  .#define _irq_handler      irq_handler#define _irq_1_isr      irq_1_isr  .  .  ..extern _irq_handler.extern _irq_1_isr  .  .  .//vector41: .long _irq1_handlervector41: .long _irq_1_isr  .  .  .

 
I run it, but it doesn't stop when I press the SW3.
 
What am I missing?
0 Kudos