MCF5223X: TCP/IP stack: AN3470SW Enable interrupts from switches (/IRQ1, /IRQ4, /IRQ7)

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

MCF5223X: TCP/IP stack: AN3470SW Enable interrupts from switches (/IRQ1, /IRQ4, /IRQ7)

1,813 Views
Martin_
NXP Employee
NXP Employee
Hi all,
If someone would like to use external interrupts from switches in AN3470SW, here is the proposal: 
 
The switch interrupts are disabled by default, the project just polls them. 
 
To enable interrupts for them, we could enable already pre-prepared code inside mcf5223_gpio_init function:
Code:
#if 1  // EMG - Need to poll Switch state from web server    /* Enable IRQ signals on the port */    MCF_GPIO_PNQPAR = 0        | MCF_GPIO_PNQPAR_IRQ1_IRQ1        | MCF_GPIO_PNQPAR_IRQ4_IRQ4        | MCF_GPIO_PNQPAR_IRQ7_IRQ7;        MCF_GPIO_PGPPAR = 0        | MCF_GPIO_PGPPAR_IRQ11_IRQ11;            /* Set EPORT to look for rising edges */    MCF_EPORT_EPPAR0 = 0        | MCF_EPORT_EPPAR_EPPA1_RISING        | MCF_EPORT_EPPAR_EPPA4_RISING        | MCF_EPORT_EPPAR_EPPA7_RISING;            MCF_EPORT_EPPAR1 = 0        | MCF_EPORT_EPPAR_EPPA11_RISING;            /* Clear any currently triggered events on the EPORT  */    MCF_EPORT_EPIER0 = 0        | MCF_EPORT_EPIER_EPIE1        | MCF_EPORT_EPIER_EPIE4        | MCF_EPORT_EPIER_EPIE7;           MCF_EPORT_EPIER1 = 0        | MCF_EPORT_EPIER_EPIE11;           /* Enable interrupts in the interrupt controller */ MCF_INTC0_IMRL &=  ~(MCF_INTC_IMRL_MASK1); //  MCF_INTC0_IMRL &=  ~(MCF_INTC_IMRL_MASK4); //  MCF_INTC0_IMRL &=  ~(MCF_INTC_IMRL_MASK7); //  MCF_INTC1_ICR35 = MCF_INTC_ICR_IL(4);    MCF_INTC1_IMRH &=  ~(MCF_INTC_IMRH_MASK35); #else

If we look at the code we will see the interrupts are being unmasked in the MCF_INTC0_IMRL interrupt mask register in this order:
Code:
mcf5223_gpio_init() {        ...    /* Enable interrupts in the interrupt controller */    MCF_INTC0_IMRL &=  ~(MCF_INTC_IMRL_MASK1); //     MCF_INTC0_IMRL &=  ~(MCF_INTC_IMRL_MASK4); //     MCF_INTC0_IMRL &=  ~(MCF_INTC_IMRL_MASK7); //     ...    MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASKALL);    ...}

 
However, the transition of the MCF_INTC0_IMRL[MASKALL] bit from 1 to 0 will set all the remaining 63bits to 1, therefore masking all interrupt sources.
 
If we modify the unmasking to the following order:

 

Code:
//maskall first    MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASKALL);    ...    MCF_INTC0_IMRL &=  ~(MCF_INTC_IMRL_MASK1); //     MCF_INTC0_IMRL &=  ~(MCF_INTC_IMRL_MASK4); //     MCF_INTC0_IMRL &=  ~(MCF_INTC_IMRL_MASK7); //

the interrupts from switches work then.

 

Additionally, if we slightly modified and moved the mcf5223_powerup_config() function call before mcf5223_gpio_init() function call, the poll_switches() function would detect SW1 and SW2 power up states correctly:

 

 

Code:
void mcf5223_powerup_config( void ){ //these two registers will be overwritten later in the mcf5223_gpio_init() if required MCF_GPIO_PNQPAR = 0; MCF_GPIO_PGPPAR = 0; powerup_config_flags = poll_switches() | 0x80;// powerup_config_flags = 0x01;   // DHCP enabled  }
Code:
mcf5223_gpio_init(){    ...    mcf5223_powerup_config();    mcf5223_gpio_init();    ...}


 



Message Edited by macl on 2007-08-20 03:42 PM
Labels (1)
0 Kudos
1 Reply

352 Views
mjbcswitzerland
Specialist V
Hi Martin

I know that it is not related to AN3470SW but here is the method for configuring these interrupts in the uTasker project (interested people can get full details at the link below) - it can set up any IRQ1..IRQ15 (note that not all are available on the  smaller chips)

    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    interrupt_setup.int_priority = (INTERRUPT_LEVEL_3);                  // low priority    interrupt_setup.int_handler  = test_irq_4;                           // handling function    interrupt_setup.int_port_bit = 4;                                    // The IRQ input connected    interrupt_setup.int_port_sense = IRQ_RISING_EDGE;                    // Interrupt on this edge    fnConfigureInterrupt((void *)&interrupt_setup);                      // configure test interrupt    interrupt_setup.int_priority = (INTERRUPT_LEVEL_3);                  // low priority    interrupt_setup.int_handler  = test_irq_5;                           // handling function    interrupt_setup.int_port_bit = 5;                                    // The IRQ input connected    interrupt_setup.int_port_sense = IRQ_RISING_EDGE;                    // Interrupt on this edge    fnConfigureInterrupt((void *)&interrupt_setup);                      // configure test interrupt    interrupt_setup.int_priority = (INTERRUPT_LEVEL_4);                  // low priority (test not available on 80 pin devices)    interrupt_setup.int_handler  = test_irq_7;                           // handling function    interrupt_setup.int_port_bit = 7;                                    // The IRQ input connected    interrupt_setup.int_port_sense = IRQ_FALLING_EDGE;                   // Interrupt on this edge    fnConfigureInterrupt((void *)&interrupt_setup);                      // configure test interrupt    interrupt_setup.int_priority = (INTERRUPT_LEVEL_6);                  // low priority    interrupt_setup.int_handler  = test_irq_11;                          // handling function    interrupt_setup.int_port_bit = 11;                                   // The IRQ input connected (on all devices)    interrupt_setup.int_port_sense = IRQ_RISING_EDGE;                    // Interrupt on this edge    fnConfigureInterrupt((void *)&interrupt_setup);                      // configure test interrupt

Here 5 are configured - each can be assigned a priority, rising, falling, toggle or edge sensitive plus an interrupt handler - eg.
static void test_irq_7(void){    fnInterruptMessage(OWN_TASK, IRQ7_EVENT);}
which causes a task to be woken which writes a message to a UART (not visible here) to inform that IRQ7 was detected.

The uTasker simulator allows the user to see the function set to the port bits and to click on them to toggle their input state. If the pin state change matches the set up the simulator also executes the interrupt code so that all can be verified / tested before moving to hardware.

Below is a screen shot of the simulator in action, where the 5 IRQ pins are visible. The cursor was positioned over IRQ1 pin where its function is being displayed.



The project is open source and completely free for non-commercial (hobby, educational, etc.) use.
The uTasker has its own support forum at http://www.uTasker.com/forum/
Every one is welcome to check it out!

Regards

Mark


www.uTasker.com

 

 

0 Kudos