LLWU on PORTE not working

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

LLWU on PORTE not working

1,327 次查看
rahuludasi
Contributor I

I have a LLWU set up on PTB0/LLWU_P5 which works fine, generates the interrupt. I tried adding another one on PTE4/LLWU_P2 without any success.

My setup code is,

LLWU_PE1_WUPE2(0x03) in init_lpm.c under LPM_OPERATION_MODE_STOP

GPIOE_PDDR                    0x00000000;

#define TW_WAKE_ID                    (GPIO_PORT_E | GPIO_PIN4)

#define TW_WAKE_MUX               LWGPIO_MUX_E4_GPIO

My initialisation code is,

static void tw_isr (void *pin)

{

//    lwgpio_toggle_value (&led1);

      lwgpio_int_clear_flag (pin);

    _lwevent_set (&app_event, PIN_EVENT_MASK);

  

}

static void tw_interrupt_init (void)

{

    static LWGPIO_STRUCT sw;

    printf("Going to init tw interrupt\n");

    //PTE4 llwu p2

    //************************************************************************************

    /* Set the pin to input */

    if (!lwgpio_init(&sw, TW_WAKE_ID, LWGPIO_DIR_INPUT, LWGPIO_VALUE_NOCHANGE))

    {

        printf("\nSW initialization failed.\n");

        _task_block();

    }

    /* Set functionality to GPIO mode */

    lwgpio_set_functionality(&sw, TW_WAKE_MUX);

  

    /* Enable pull up */

    lwgpio_set_attribute(&sw, LWGPIO_ATTR_PULL_UP, LWGPIO_AVAL_ENABLE);

    /* Setup the pin interrupt mode */

    if (!lwgpio_int_init(&sw, LWGPIO_INT_MODE_FALLING))

    {

        printf("Initializing SW for interrupt failed.\n");

        _task_block();

    }

    /* Install gpio interrupt service routine */

    _int_install_isr(lwgpio_int_get_vector(&sw), tw_isr, (void *) &sw);

  

    /* Set interrupt priority and enable interrupt source in the interrupt controller */

    _bsp_int_init(lwgpio_int_get_vector(&sw), 3, 0, TRUE);

  

    /* Enable interrupt for pin */

    lwgpio_int_enable(&sw, TRUE);

  

}

void initLowPower()

{

    //configure pin interrupts

    tw_interrupt_init();

    _int_install_unexpected_isr();

    _lpm_register_wakeup_callback(BSP_LLWU_INTERRUPT_VECTOR, BSP_LLWU_INTERRUPT_PRIORITY, NULL);

    /* Install interrupt for timer wakeup */

    install_timer_interrupt();

  

    /* Create global event */

    if (_lwevent_create(&app_event, 0) != MQX_OK)

    {

        printf("\nCreating app_event failed.\n");

        _task_block();

    }

  

    if (_lpm_get_reset_source() != MQX_RESET_SOURCE_LLWU)

        printf("\nNormal hardware wakeup\n");

    else

    printf("\nWake up by reset from LLWU\n");

}

The llwu code on the PORTB seems to work fine and is similar, not sure if there are any bsp specific changes needed for PORTE llwu.

Thanks,

Rahul

标记 (3)
0 项奖励
回复
2 回复数

1,028 次查看
mjbcswitzerland
Specialist V

Hi Rahul

Since the location of the LLWU pins are not the same on all devices it is important to specify which part you are using - presumably a Kinetis K part.

Below is how I verify all 16 K64 LLWU interrupt (for example):

// Configure all 16 K64 LLWU pins

//

INTERRUPT_SETUP interrupt_setup; // interrupt configuration parameters

interrupt_setup.int_type = PORT_INTERRUPT; // identifier to configure port interrupt

interrupt_setup.int_port_sense = (IRQ_FALLING_EDGE | PULLUP_ON | ENABLE_PORT_MODE);

interrupt_setup.int_type = WAKEUP_INTERRUPT; // configure as wake-up interrupt

interrupt_setup.int_handler = test_irq_5;

interrupt_setup.int_port = PORTA; // the port that the interrupt input is on

interrupt_setup.int_port_bits = (PORTA_BIT4 | PORTA_BIT13);

fnConfigureInterrupt((void *)&interrupt_setup); // configure wakeup pins on this port

interrupt_setup.int_port = PORTB; // the port that the interrupt input is on

interrupt_setup.int_port_bits = PORTB_BIT0;

fnConfigureInterrupt((void *)&interrupt_setup); // configure wakeup pins on this port

interrupt_setup.int_port = PORTC; // the port that the interrupt input is on

interrupt_setup.int_port_bits = (PORTC_BIT1 | PORTC_BIT3 | PORTC_BIT4 | PORTC_BIT5 | PORTC_BIT6 | PORTC_BIT11);

fnConfigureInterrupt((void *)&interrupt_setup); // configure wakeup pins on this port

interrupt_setup.int_port = PORTD; // the port that the interrupt input is on

interrupt_setup.int_port_bits = (PORTD_BIT0 | PORTD_BIT2 | PORTD_BIT4 | PORTD_BIT6);

fnConfigureInterrupt((void *)&interrupt_setup);// configure wakeup pins on this port

interrupt_setup.int_port = PORTE; // the port that the interrupt input is on

interrupt_setup.int_port_bits = (PORTE_BIT1 | PORTE_BIT2 | PORTE_BIT4);

fnConfigureInterrupt((void *)&interrupt_setup); // configure wakeup pins on this port

fnSetLowPowerMode(LLS_MODE);

This is the LLWU method as used in the uTasker project - µTasker LLWU Support

whereby this attaches each LLWU pin to the same interrupt (they can however each have their own or share interrupts in groups).

Notice that the interrupt sense is controlled by

interrupt_setup.int_port_sense = (IRQ_FALLING_EDGE | PULLUP_ON | ENABLE_PORT_MODE);

and all pins are set to falling edge sensitive.

At the same time the control flags PULLUP_ON and ENABLE_PORT_MODE are used. The first means that the pins characteristics are set to have a pullup (this is set in its GPIO mode) so that unconnected pins are held at '1' so that the falling edge can function.

The second (ENABLE_PORT_MODE) is also important because it specifies that the pin should be set to its GPIO mode.

First I'll give two examples to explain why this is useful and then also explain why it can also be critical for the LLWU to operate correctly.

If a LLUW pin is used as a peripheral input - eg. UART0_RX (some chips share UART Rx with LLWU) I configure with interrupt_setup.int_port_sense = (IRQ_FALLING_EDGE | PULLUP_ON); [pull up is optional] so that the original peripheral function is not disturbed. When in a low leakage mode the LLWU pin function becomes active and then it will wake on a falling edge on the input.

If the pin is not used for other functions it may default to disabled or an analogue peripheral function - in this case I use interrupt_setup.int_port_sense = (IRQ_FALLING_EDGE | PULLUP_ON | ENABLE_PORT_MODE); which configures the pull-up AND sets the pin function to the GPIO mode (moving from an analogue or disabled mux setting).

A potentially important fact about using the LLWU is to ensure that the LLWU is connected because what I find is that if the ENABLE_PORT_MODE control is not used on some pins (those that are disabled by default) the LLWU also doesn't operate. In the case of analogue inputs the pull-up is not connected, which can also mean that the wakeup doesn't operate because no falling edge is possible (in my test setup).

I don't know the methods that you are using but suggest that you examine the PORTx_CRn setting used to ensure that the pin MUX is not in the disabled state. My tests show that I can either get all LLWU inputs to work or else only a select few operate, the difference being pulely in the MUX setting used!

Regards

Mark

Kinetis: µTasker Kinetis support

LLWU: µTasker LLWU Support

For the complete "out-of-the-box" Kinetis experience and faster time to market

0 项奖励
回复

1,028 次查看
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Rahul Udasi,

     Please tell us the full name of your chp and the code you are refering, then we can help you better.

Waiting for your reply!

Jingjing

0 项奖励
回复