We needed to switch the gpio port that was being used to bring the KL05 out of VLLS1 mode. We were using PTB0 (a supported LLWU pin) that was wired to an accelerometer interrupt line that generated a falling edge when a double tap is detected. This would change the state and/or bring the system out of VLLS1 mode. That worked perfectly. Then we needed to switch the design to use a force sensing resistor with a pullup (instead of the accelerometer double tap detect) on PTB2. The issue we are having is that the KL05 enters the VLLS1, but doesn't stay there. It immediately comes out of VLLS1 without any input. The system can literally sit there without being touched and will enter and then immediately exit VLLS1 mode. I have a scope probe on the FSR line and the pin is not going low (trigger set all the way up to 2.5v).
Below is the gpio init code, interrupt handler, and code snippet showing system going into VLLS1 mode. The code for PTB0 is commented out and the code for PTB2 is right above it.
void gpio_init(void)
{
// FSR press detect
PORTB_PCR2 = PORT_PCR_MUX(1) // Alt1: GPIO
| PORT_PCR_IRQC(0x0A); // Falling edge
PORTB_PCR2 |= PORT_PCR_ISF_MASK; // clear flag
/*
// MMA845x INT2 - Double pulse detection
PORTB_PCR0 = PORT_PCR_MUX(1) // Alt1: GPIO
| PORT_PCR_IRQC(0x0A) // Falling edge
| PORT_PCR_PE_MASK // Pull enable
| PORT_PCR_PS_MASK; // Pull select - pullup
PORTB_PCR0 |= PORT_PCR_ISF_MASK; // clear flag
*/
enable_irq(INT_PORTB - 16);
}
void PORTB_IRQHandler(void)
{
if(PORTB_PCR2 & PORT_PCR_ISF_MASK)
{
delay_ms(1000);
if(GPIOB_PDIR | 1<<2)
{
state_change(0);
printf("\r\nFSR press\r\n");
}
// Clear the interrupt flag
PORTB_PCR2 |= PORT_PCR_ISF_MASK;
}
/*
if(PORTB_PCR0 & PORT_PCR_ISF_MASK)
{
MMA845x_pulse_flag_set();
// Read the INT_SOURCE register
tmp = hal_dev_mma8451_read_reg(0x0C);
if((tmp & 0x08) == 0x08)
{
// Yes. Read the (PULSE_SRC) Pulse source register to clear the flag.
tmp = hal_dev_mma8451_read_reg(0x22);
// Double pulse has been detected - change state
state_change(0);
}
// Clear the interrupt flag
PORTB_PCR0 |= PORT_PCR_ISF_MASK;
}
*/
}
// Code to go into VLLS1
case LOW_POWER_STATE:
{
// Turn off LEDs
PORTB_PCR10 = PORT_PCR_MUX(1);
GPIOB_PDDR |= 0x00000400;
GPIOB_PSOR |= 0x00000400;
// Disable SWD pin
PORTA_PCR0 = PORT_PCR_MUX(1);
PORTA_PCR2 = PORT_PCR_MUX(1);
// Put KL05 in low power
SMC_PMPROT = SMC_PMPROT_AVLLS_MASK; // Allow device to go into low-leakage power mode
SMC_PMCTRL = SMC_PMCTRL_STOPM(4);
SMC_STOPCTRL = SMC_PMCTRL_STOPM(1); // VLLS1
dummyread=SMC_PMCTRL; // Give time for PMCTRL register to write
MCG_C6&=~MCG_C6_CME0_MASK; // Turn off Clock Monitor
// LLWU config
LLWU_F1 |= LLWU_F1_WUF5_MASK; // Clear wakeup flag for PTB2/LLWU_P5
LLWU_PE2 = LLWU_PE2_WUPE5(2); // Configure wakeup on PTB2/LLWU_P5 (falling edge)
LLWU_ME = LLWU_ME_WUME5_MASK;
/*
LLWU_F1 |= LLWU_F1_WUF4_MASK; // Clear wakeup flag for PTB0/LLWU_P4 (Accelerometer INT2 line to PTB0)
LLWU_PE2 = LLWU_PE2_WUPE4(2); // Configure wakeup on PTB0/LLWU_P4 (falling edge)
LLWU_ME = LLWU_ME_WUME4_MASK;
*/
while(1)
{
stop();
}
}
已解决! 转到解答。
Hi Bryan,
The code I am running normally would place the FRDM-KL05 into VLLS1 mode and use the LLWU TSI0 touch sensor interface to wake the device up.
I added the below code to that application to enable the PTB2 pin to be configured as an input LLWU source. I also used the internal PTB2 pull-up resistor and then simple shorted it to ground via resistor to test from TP20 to J8 pin 1.
#if 1 //DES 1=test(... Set Pin B2 to GPIO function, pull-up enabled) , 0=default code
PORTB_PCR2 = PORT_PCR_MUX(1) |
PORT_PCR_PE_MASK |
PORT_PCR_PS_MASK;
#endif
#if 1 //DES 1=test, 0=default code
// Need to enable a wake up source also
LLWU_PE2=LLWU_PE2_WUPE5(2); //DES set PTB2 falling edge interrupt for LLWU
LLWU_F1|=LLWU_F1_WUF5_MASK; //DES Clear PTB2 flag
#endif
Attached is my ZIP project. It is using IAR.
Regards,
David
Hi Bryan
There is no issue with PTB2's LLWU_P5 so I would suggest ensuring that you don't have any LLWU flags already set when moving to the low leakage power mode; rather than just resetting the single flag of interest you could reset all possible flags to be sure, remembering that LLWU flags used to wakeup the processor will still remain pending after a previous wakeup reset.
Note also that you don't need to configure the port as an interrupt input for the LLWU functionality to operate.
You may find something of use at http://www.utasker.com/kinetis/LLWU.html where practicalities of the LLWU module are discussed.
I have also attached a binary for the FRDM-KL05Z board which shows PTB2 wakeup operation. This pin is also used by UART0 Rx (connected to the OpenSDA's virtual COM) so once the processor is set to a (V)LLS mode a reception on that interface will wake (reset) the processor.
If you have a FRDM-KL05Z as reference you can try it as follows:
1. Load the binary and connect to the UART via the OpenSDA virtual COM at 115'200 Baud.
2. Hit the return key for a menu and enter the "Administrator" sub-menu
3. The present mode can be requested with "show_lp"
show_lp
0 = RUN
1 = WAIT [active]
2 = STOP
3 = VLPR
4 = VLPS
5 = LLS
6 = VLLS0
7 = VLLS1
8 = VLLS3
The default is WAIT (the processor will be switching between RUN and WAIT whenever it can and needs to)
LLWU operation is configured on LLWU_P5, whereby PTB2 is used as UART Rx during operating modes.
By commanding a LLS power mode, eg. "set_lp 7" the processor will be set to the mode as soon as it has nothing else to complete (such as the UART prompt sent as confirmation). The current consumption in that mode can be measured.
4. The processor can be woken (via WAKEUP reset) by typing any key, due to the fact that the UART0 RX input is now performing its LLWU function (LLWU_P5)
Regards
Mark
P.S. Note that the low power modes are controlled dynamically in the uTasker project and the LLWU interface is simple to control (see link above). The (low power) code is usable for all KL and K devices and builds with CW, KDS, IAR, Keil, Crossworks, Atollic, CooCox, Green Hills, GCC and VisualStudio (where the operation can also be simulated).
Kinetis: µTasker Kinetis support
KL05: µTasker FRDM-KL05Z support
For the complete "out-of-the-box" Kinetis experience and faster time to market
Hi Bryan,
The code I am running normally would place the FRDM-KL05 into VLLS1 mode and use the LLWU TSI0 touch sensor interface to wake the device up.
I added the below code to that application to enable the PTB2 pin to be configured as an input LLWU source. I also used the internal PTB2 pull-up resistor and then simple shorted it to ground via resistor to test from TP20 to J8 pin 1.
#if 1 //DES 1=test(... Set Pin B2 to GPIO function, pull-up enabled) , 0=default code
PORTB_PCR2 = PORT_PCR_MUX(1) |
PORT_PCR_PE_MASK |
PORT_PCR_PS_MASK;
#endif
#if 1 //DES 1=test, 0=default code
// Need to enable a wake up source also
LLWU_PE2=LLWU_PE2_WUPE5(2); //DES set PTB2 falling edge interrupt for LLWU
LLWU_F1|=LLWU_F1_WUF5_MASK; //DES Clear PTB2 flag
#endif
Attached is my ZIP project. It is using IAR.
Regards,
David