Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kinetis: Implement low power modes #7897

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a42df69
frdm-k64f: Add LPTMR configuration
Sep 13, 2018
5a92a2d
kinetis: Add low power support
Jun 3, 2017
1a6d526
fixup! kinetis: Add low power support
Nov 2, 2018
8b241f9
fixup! kinetis: Add low power support
Nov 2, 2018
fe9b294
fixup! fixup! kinetis: Add low power support
Nov 2, 2018
f4d2a53
squash kinetis: PIT only block low power when a target is set
Sep 11, 2018
17f71b9
cpu/kinetis: Implement uart_poweron/uart_poweroff
Mar 18, 2018
4041c4d
boards/mulle: Add UART LLWU config
Mar 17, 2018
c03644a
boards/frdm-kw41z: Add UART LLWU config
Mar 18, 2018
b41c6d9
boards/frdm-k64f: Add UART LLWU config
Mar 18, 2018
bc92d8b
boards/teensy31: Add UART LLWU config
Jun 30, 2018
da8a4d9
boards/pba-d-01-kw2x: Add UART LLWU config
Jun 30, 2018
4eb0db5
boards/frdm-k22f: Add UART LLWU config
Jun 30, 2018
1772982
boards/mulle: Update LPTMR config with LLWU
Jun 30, 2018
70a3ef8
boards/frdm-k22f: Update LPTMR config with LLWU
Jun 30, 2018
196de13
boards/frdm-kw41z: Update LPTMR config with LLWU
Jun 30, 2018
9e92ff8
frdm-kw41z: Initialize DCDC module during board_init
Jun 11, 2018
859baa7
kinetis: Discard noisy bytes from LPUART
Mar 18, 2018
26b776a
Revert "kinetis: Discard noisy bytes from LPUART"
Oct 10, 2018
120c379
fixup! fixup! fixup! kinetis: Add low power support
Nov 2, 2018
19cdf6c
squash kinetis-pm improve LPUART with LLS
Nov 2, 2018
e43d783
fixup! boards/frdm-kw41z: Add UART LLWU config
Nov 5, 2018
015f654
fixup! boards/teensy31: Add UART LLWU config
Nov 5, 2018
9c04a18
fixup! boards/frdm-k22f: Update LPTMR config with LLWU
Nov 5, 2018
90e7e96
frdm-k64f: Update LPTMR config with LLWU
Nov 5, 2018
44d15e2
fixup! boards/frdm-kw41z: Update LPTMR config with LLWU
Nov 5, 2018
14c0243
fixup! boards/mulle: Update LPTMR config with LLWU
Nov 5, 2018
f2368d1
squash kinetis llwu clean up
Nov 7, 2018
a34d7ac
frdm: Set connect_assert_srst in default OpenOCD configuration
Nov 27, 2018
0215897
usb-kw41z: Update periph_conf.h for low power support
Dec 1, 2018
74ecf4e
squash kinetis uart pm_block handling clean up
Dec 13, 2018
bcbe91d
squash kinetis: Move PM_BLOCK to periph_cpu.h
Dec 13, 2018
42be256
squash kinetis: Add low power handling in i2c periph
Dec 13, 2018
7ab0e94
fixup! squash kinetis uart pm_block handling clean up
Dec 14, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion boards/common/frdm/dist/openocd-klx.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ transport select swd
# Kinetis L series CPUs
source [find target/klx.cfg]

reset_config srst_only
# The debug module is stopped in low leakage modes, we use connect_assert_srst
# to hold the device in reset while connecting with OpenOCD to make sure that we
# always get a connection even when the application uses low power modes.
reset_config srst_only connect_assert_srst

$_TARGETNAME configure -event gdb-attach {
halt
Expand Down
5 changes: 4 additions & 1 deletion boards/common/frdm/dist/openocd-kx.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
# Kinetis K series CPUs
source [find target/kx.cfg]

reset_config srst_only
# The debug module is stopped in low leakage modes, we use connect_assert_srst
# to hold the device in reset while connecting with OpenOCD to make sure that we
# always get a connection even when the application uses low power modes.
reset_config srst_only connect_assert_srst

$_TARGETNAME configure -event gdb-attach {
halt
Expand Down
18 changes: 10 additions & 8 deletions boards/frdm-k22f/include/periph_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,15 @@ static const clock_config_t clock_config = {
}, \
}
#define LPTMR_NUMOF (1U)
#define LPTMR_CONFIG { \
{ \
.dev = LPTMR0, \
.irqn = LPTMR0_IRQn, \
.src = 2, \
.base_freq = 32768u, \
}, \
}
#define LPTMR_CONFIG { \
{ \
.dev = LPTMR0, \
.base_freq = 32768u, \
.llwu = LLWU_WAKEUP_MODULE_LPTMR0, \
.src = 2, \
.irqn = LPTMR0_IRQn, \
}, \
}
#define TIMER_NUMOF ((PIT_NUMOF) + (LPTMR_NUMOF))

#define PIT_BASECLOCK (CLOCK_BUSCLOCK)
Expand All @@ -113,6 +114,7 @@ static const uart_conf_t uart_config[] = {
.scgc_bit = SIM_SCGC4_UART1_SHIFT,
.mode = UART_MODE_8N1,
.type = KINETIS_UART,
.llwu_rx = LLWU_WAKEUP_PIN_PTE1,
},
};

Expand Down
31 changes: 20 additions & 11 deletions boards/frdm-k64f/include/periph_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,26 @@ static const clock_config_t clock_config = {
* @{
*/
#define PIT_NUMOF (2U)
#define PIT_CONFIG { \
{ \
.prescaler_ch = 0, \
.count_ch = 1, \
}, \
{ \
.prescaler_ch = 2, \
.count_ch = 3, \
}, \
#define PIT_CONFIG { \
{ \
.prescaler_ch = 0, \
.count_ch = 1, \
}, \
{ \
.prescaler_ch = 2, \
.count_ch = 3, \
}, \
}
#define LPTMR_NUMOF (1U)
#define LPTMR_CONFIG { \
{ \
.dev = LPTMR0, \
.base_freq = 32768u, \
.llwu = LLWU_WAKEUP_MODULE_LPTMR0, \
.src = 2, \
.irqn = LPTMR0_IRQn, \
}, \
}
#define LPTMR_NUMOF (0U)
#define LPTMR_CONFIG {}
#define TIMER_NUMOF ((PIT_NUMOF) + (LPTMR_NUMOF))

#define PIT_BASECLOCK (CLOCK_BUSCLOCK)
Expand All @@ -107,6 +115,7 @@ static const uart_conf_t uart_config[] = {
.scgc_bit = SIM_SCGC4_UART0_SHIFT,
.mode = UART_MODE_8N1,
.type = KINETIS_UART,
.llwu_rx = LLWU_WAKEUP_PIN_UNDEF,
},
};

Expand Down
36 changes: 36 additions & 0 deletions boards/frdm-kw41z/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,42 @@

void board_init(void)
{
bit_set32(&SIM->SCGC5, SIM_SCGC5_DCDC_SHIFT);

/* We don't have a status bit for checking if the DCDC is in bypass mode
* so we check if the PSWITCH bit is set, assuming that the power switch
* has not been released since the DCDC was started. This is run early in
* the boot process so it should be fine. */
if (DCDC->REG0 & DCDC_REG0_PSWITCH_STATUS_MASK) {
/* DCDC is on */
/* Spin until DCDC output is stable */
while (!(DCDC->REG0 & DCDC_REG0_DCDC_STS_DC_OK_MASK)) {}
/* Set up DCDC for pulsed mode in VLPS, LLS */
DCDC->REG0 = (DCDC->REG0 & ~(DCDC_REG0_DCDC_VBAT_DIV_CTRL_MASK | DCDC_REG0_VLPS_CONFIG_DCDC_HP_MASK)) |
DCDC_REG0_DCDC_VBAT_DIV_CTRL(0b10) | /* provide VBAT/2 to ADC input to measure battery level */
DCDC_REG0_DCDC_LP_DF_CMP_ENABLE_MASK;
DCDC->REG1 = DCDC->REG1 |
DCDC_REG1_DCDC_LOOPCTRL_EN_CM_HYST_MASK |
DCDC_REG1_DCDC_LOOPCTRL_EN_DF_HYST_MASK;
DCDC->REG2 = DCDC->REG2 |
DCDC_REG2_DCDC_LOOPCTRL_HYST_SIGN_MASK;
DCDC->REG3 = (DCDC->REG3 &
~(DCDC_REG3_DCDC_MINPWR_HALF_FETS_MASK |
DCDC_REG3_DCDC_MINPWR_DOUBLE_FETS_MASK |
DCDC_REG3_DCDC_MINPWR_DOUBLE_FETS_PULSED_MASK)) |
DCDC_REG3_DCDC_MINPWR_HALF_FETS_PULSED_MASK;

/* Spin until DCDC is stable */
while (!(DCDC->REG0 & DCDC_REG0_DCDC_STS_DC_OK_MASK)) {}

/* DCDC has stabilized, halt stepping
* This must be set before entering low power modes */
DCDC->REG3 |= DCDC_REG3_DCDC_VDD1P5CTRL_DISABLE_STEP_MASK |
DCDC_REG3_DCDC_VDD1P8CTRL_DISABLE_STEP_MASK;

/* Spin until DCDC is stable */
while (!(DCDC->REG0 & DCDC_REG0_DCDC_STS_DC_OK_MASK)) {}
}
/* initialize the CPU core */
cpu_init();

Expand Down
14 changes: 11 additions & 3 deletions boards/frdm-kw41z/include/periph_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,11 @@ static const clock_config_t clock_config = {
#define LPTMR_CONFIG { \
{ \
.dev = LPTMR0, \
.irqn = LPTMR0_IRQn, \
.src = 2, \
.base_freq = 32768u, \
} \
.llwu = LLWU_WAKEUP_MODULE_LPTMR0, \
.src = 2, \
.irqn = LPTMR0_IRQn, \
}, \
}
#define TIMER_NUMOF ((PIT_NUMOF) + (LPTMR_NUMOF))
#define PIT_BASECLOCK (CLOCK_BUSCLOCK)
Expand All @@ -114,6 +115,13 @@ static const uart_conf_t uart_config[] = {
.scgc_bit = SIM_SCGC5_LPUART0_SHIFT,
.mode = UART_MODE_8N1,
.type = KINETIS_LPUART,
/* Undocumented behavior: LPUART fails to detect the START bit at wake up
* with LLWU sometimes. This seem to be related to using the builtin
* DCDC for powering the MCU. */
/* LLWU_WAKEUP_PIN_PTC6 is the correct setting on this dev board if you
* want to try using LLS mode, or if it does not matter that the UART RX
* byte is sometimes is corrupt */
.llwu_rx = LLWU_WAKEUP_PIN_UNDEF,
},
};
#define UART_NUMOF (sizeof(uart_config) / sizeof(uart_config[0]))
Expand Down
9 changes: 6 additions & 3 deletions boards/mulle/include/periph_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,11 @@ static const clock_config_t clock_config = {
#define LPTMR_CONFIG { \
{ \
.dev = LPTMR0, \
.irqn = LPTMR0_IRQn, \
.src = 2, \
.base_freq = 32768u, \
} \
.llwu = LLWU_WAKEUP_MODULE_LPTMR0, \
.src = 2, \
.irqn = LPTMR0_IRQn, \
}, \
}
#define TIMER_NUMOF ((PIT_NUMOF) + (LPTMR_NUMOF))

Expand Down Expand Up @@ -137,6 +138,7 @@ static const uart_conf_t uart_config[] = {
.scgc_bit = SIM_SCGC4_UART0_SHIFT,
.mode = UART_MODE_8N1,
.type = KINETIS_UART,
.llwu_rx = LLWU_WAKEUP_PIN_UNDEF,
},
{
.dev = UART1,
Expand All @@ -150,6 +152,7 @@ static const uart_conf_t uart_config[] = {
.scgc_bit = SIM_SCGC4_UART1_SHIFT,
.mode = UART_MODE_8N1,
.type = KINETIS_UART,
.llwu_rx = LLWU_WAKEUP_PIN_PTC3,
},
};

Expand Down
2 changes: 2 additions & 0 deletions boards/pba-d-01-kw2x/include/periph_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static const uart_conf_t uart_config[] = {
.scgc_bit = SIM_SCGC4_UART2_SHIFT,
.mode = UART_MODE_8N1,
.type = KINETIS_UART,
.llwu_rx = LLWU_WAKEUP_PIN_UNDEF,
},
{
.dev = UART0,
Expand All @@ -121,6 +122,7 @@ static const uart_conf_t uart_config[] = {
.scgc_bit = SIM_SCGC4_UART0_SHIFT,
.mode = UART_MODE_8N1,
.type = KINETIS_UART,
.llwu_rx = LLWU_WAKEUP_PIN_UNDEF,
}
};

Expand Down
2 changes: 2 additions & 0 deletions boards/teensy31/include/periph_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ static const uart_conf_t uart_config[] = {
.scgc_bit = SIM_SCGC4_UART0_SHIFT,
.mode = UART_MODE_8N1,
.type = KINETIS_UART,
.llwu_rx = LLWU_WAKEUP_PIN_UNDEF,
},
{
.dev = UART1,
Expand All @@ -126,6 +127,7 @@ static const uart_conf_t uart_config[] = {
.scgc_bit = SIM_SCGC4_UART1_SHIFT,
.mode = UART_MODE_8N1,
.type = KINETIS_UART,
.llwu_rx = LLWU_WAKEUP_PIN_PTC3,
},
};

Expand Down
11 changes: 8 additions & 3 deletions boards/usb-kw41z/include/periph_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,11 @@ static const clock_config_t clock_config = {
#define LPTMR_CONFIG { \
{ \
.dev = LPTMR0, \
.irqn = LPTMR0_IRQn, \
.src = 2, \
.base_freq = 32768u, \
} \
.llwu = LLWU_WAKEUP_MODULE_LPTMR0, \
.src = 2, \
.irqn = LPTMR0_IRQn, \
}, \
}
#define TIMER_NUMOF ((PIT_NUMOF) + (LPTMR_NUMOF))
#define PIT_BASECLOCK (CLOCK_BUSCLOCK)
Expand All @@ -114,6 +115,10 @@ static const uart_conf_t uart_config[] = {
.scgc_bit = SIM_SCGC5_LPUART0_SHIFT,
.mode = UART_MODE_8N1,
.type = KINETIS_LPUART,
/* LLWU_WAKEUP_PIN_PTC6 is the correct setting on this dev board if you
* want to try using LLS mode. The current setting will block LLS mode
* if UART RX is used, which is true in most applications */
.llwu_rx = LLWU_WAKEUP_PIN_UNDEF,
},
};
#define UART_NUMOF (sizeof(uart_config) / sizeof(uart_config[0]))
Expand Down
1 change: 1 addition & 0 deletions cpu/kinetis/Makefile.features
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ FEATURES_PROVIDED += periph_cpuid
FEATURES_PROVIDED += periph_hwrng
FEATURES_PROVIDED += periph_gpio
FEATURES_PROVIDED += periph_gpio_irq
FEATURES_PROVIDED += periph_llwu
FEATURES_PROVIDED += periph_mcg

include $(RIOTCPU)/cortexm_common/Makefile.features
6 changes: 5 additions & 1 deletion cpu/kinetis/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,14 @@ export UNDEF += $(BINDIR)/cpu/fcfield.o
# include common periph drivers
USEMODULE += periph_common

# select kinetis periph drivers
# select Kinetis periph drivers
USEMODULE += periph_llwu
USEMODULE += periph_mcg
USEMODULE += periph_wdog

# Enable power management by default
USEMODULE += pm_layered

# Define a recipe to build the watchdog disable binary, used when flashing
$(RIOTCPU)/$(CPU)/dist/wdog-disable.bin: $(RIOTCPU)/$(CPU)/dist/wdog-disable.s
$(Q)$(MAKE) -C $(RIOTCPU)/$(CPU)/dist/ $(notdir $@)
Expand Down
15 changes: 15 additions & 0 deletions cpu/kinetis/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
#ifdef MODULE_PERIPH_MCG
#include "mcg.h"
#endif
#if defined(MODULE_PERIPH_LLWU)
#include "llwu.h"
#elif defined(MODULE_PM_LAYERED)
#include "pm_layered.h"
#endif

/**
* @brief Initialize the CPU, set IRQ priorities
Expand All @@ -39,6 +44,16 @@ void cpu_init(void)
/* initialize the CPU clocking provided by the MCG module */
kinetis_mcg_init();
#endif

#if defined(MODULE_PERIPH_LLWU)
/* initialize the LLWU module for sleep/wakeup management */
llwu_init();
#elif defined(MODULE_PM_LAYERED)
/* Block LLS mode since we are not using the LLWU module, which is required
* to be able to wake up from LLS */
pm_block(KINETIS_PM_LLS);
#endif

/* trigger static peripheral initialization */
periph_init();
}
Loading