forked from Imagelibrary/rtems
atsam: Add ATSAM_POWER_WAIT_MODE
This commit is contained in:
@@ -179,9 +179,6 @@ void atsam_power_handler_rtc_driver(
|
|||||||
/**
|
/**
|
||||||
* @brief Power handler to enter the processor sleep mode.
|
* @brief Power handler to enter the processor sleep mode.
|
||||||
*
|
*
|
||||||
* For the power off state, the processor is set into the sleep mode and issues
|
|
||||||
* a wait for interrupt instruction.
|
|
||||||
*
|
|
||||||
* @see ATSAM_POWER_SLEEP_MODE().
|
* @see ATSAM_POWER_SLEEP_MODE().
|
||||||
*/
|
*/
|
||||||
void atsam_power_handler_sleep_mode(
|
void atsam_power_handler_sleep_mode(
|
||||||
@@ -189,6 +186,18 @@ void atsam_power_handler_sleep_mode(
|
|||||||
atsam_power_state state
|
atsam_power_state state
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power handler to enter the processor wait mode.
|
||||||
|
*
|
||||||
|
* The internal flash is put into deep sleep mode.
|
||||||
|
*
|
||||||
|
* @see ATSAM_POWER_WAIT_MODE().
|
||||||
|
*/
|
||||||
|
void atsam_power_handler_wait_mode(
|
||||||
|
const atsam_power_control *controls,
|
||||||
|
atsam_power_state state
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializer for a peripheral power support.
|
* @brief Initializer for a peripheral power support.
|
||||||
*
|
*
|
||||||
@@ -213,6 +222,9 @@ void atsam_power_handler_sleep_mode(
|
|||||||
#define ATSAM_POWER_SLEEP_MODE \
|
#define ATSAM_POWER_SLEEP_MODE \
|
||||||
{ .handler = atsam_power_handler_sleep_mode }
|
{ .handler = atsam_power_handler_sleep_mode }
|
||||||
|
|
||||||
|
#define ATSAM_POWER_WAIT_MODE \
|
||||||
|
{ .handler = atsam_power_handler_wait_mode }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Data for RTC driver power support.
|
* @brief Data for RTC driver power support.
|
||||||
*
|
*
|
||||||
|
|||||||
195
bsps/arm/atsam/start/power-wait.c
Normal file
195
bsps/arm/atsam/start/power-wait.c
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 embedded brains GmbH
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bsp/power.h>
|
||||||
|
#include <bsp/linker-symbols.h>
|
||||||
|
|
||||||
|
#include <libchip/chip.h>
|
||||||
|
|
||||||
|
BSP_FAST_TEXT_SECTION static void
|
||||||
|
pmc_wait_for_master_clock_ready(volatile Pmc *pmc)
|
||||||
|
{
|
||||||
|
while ((pmc->PMC_SR & PMC_SR_MCKRDY) == 0) {
|
||||||
|
/* Wait */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BSP_FAST_TEXT_SECTION static void
|
||||||
|
pmc_set_master_clock_source(volatile Pmc *pmc, uint32_t mckr)
|
||||||
|
{
|
||||||
|
pmc->PMC_MCKR =
|
||||||
|
(pmc->PMC_MCKR & ~PMC_MCKR_CSS_Msk) | (mckr & PMC_MCKR_CSS_Msk);
|
||||||
|
}
|
||||||
|
|
||||||
|
BSP_FAST_TEXT_SECTION static void
|
||||||
|
pmc_set_master_clock_prescaler(volatile Pmc *pmc, uint32_t mckr)
|
||||||
|
{
|
||||||
|
pmc->PMC_MCKR =
|
||||||
|
(pmc->PMC_MCKR & ~PMC_MCKR_PRES_Msk) | (mckr & PMC_MCKR_PRES_Msk);
|
||||||
|
}
|
||||||
|
|
||||||
|
BSP_FAST_TEXT_SECTION static void
|
||||||
|
pmc_set_master_clock_division(volatile Pmc *pmc, uint32_t mckr)
|
||||||
|
{
|
||||||
|
pmc->PMC_MCKR =
|
||||||
|
(pmc->PMC_MCKR & ~PMC_MCKR_MDIV_Msk) | (mckr & PMC_MCKR_MDIV_Msk);
|
||||||
|
}
|
||||||
|
|
||||||
|
BSP_FAST_TEXT_SECTION static void
|
||||||
|
pmc_wait_for_main_rc_osc(volatile Pmc *pmc)
|
||||||
|
{
|
||||||
|
while ((pmc->PMC_SR & PMC_SR_MOSCRCS) == 0) {
|
||||||
|
/* Wait */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BSP_FAST_TEXT_SECTION static void
|
||||||
|
pmc_wait_for_main_osc_selection(volatile Pmc *pmc)
|
||||||
|
{
|
||||||
|
while ((pmc->PMC_SR & PMC_SR_MOSCSELS) == 0) {
|
||||||
|
/* Wait */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BSP_FAST_TEXT_SECTION static void
|
||||||
|
pmc_use_main_rc_osc_4mhz(volatile Pmc *pmc)
|
||||||
|
{
|
||||||
|
uint32_t ckgr_mor;
|
||||||
|
|
||||||
|
ckgr_mor = pmc->CKGR_MOR;
|
||||||
|
ckgr_mor |= CKGR_MOR_KEY_PASSWD;
|
||||||
|
|
||||||
|
/* Enable main RC oscillator */
|
||||||
|
ckgr_mor |= CKGR_MOR_MOSCRCEN;
|
||||||
|
PMC->CKGR_MOR = ckgr_mor;
|
||||||
|
pmc_wait_for_main_rc_osc(pmc);
|
||||||
|
|
||||||
|
/* Set main RC oscillator frequency to 4MHz */
|
||||||
|
ckgr_mor &= ~CKGR_MOR_MOSCRCF_Msk;
|
||||||
|
ckgr_mor |= CKGR_MOR_MOSCRCF_4_MHz;
|
||||||
|
pmc->CKGR_MOR = ckgr_mor;
|
||||||
|
pmc_wait_for_main_rc_osc(pmc);
|
||||||
|
|
||||||
|
/* Switch to main RC oscillator */
|
||||||
|
ckgr_mor &= ~CKGR_MOR_MOSCSEL;
|
||||||
|
pmc->CKGR_MOR = ckgr_mor;
|
||||||
|
pmc_wait_for_main_osc_selection(pmc);
|
||||||
|
pmc_wait_for_master_clock_ready(pmc);
|
||||||
|
}
|
||||||
|
|
||||||
|
BSP_FAST_TEXT_SECTION static void
|
||||||
|
pmc_use_main_ext_osc(volatile Pmc *pmc)
|
||||||
|
{
|
||||||
|
uint32_t ckgr_mor;
|
||||||
|
|
||||||
|
ckgr_mor = pmc->CKGR_MOR;
|
||||||
|
ckgr_mor |= CKGR_MOR_KEY_PASSWD;
|
||||||
|
|
||||||
|
/* Enable main external oscillator */
|
||||||
|
ckgr_mor |= CKGR_MOR_MOSCRCF_12_MHz | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCRCEN |
|
||||||
|
CKGR_MOR_MOSCXTST(DEFAUTL_MAIN_OSC_COUNT);
|
||||||
|
PMC->CKGR_MOR = ckgr_mor;
|
||||||
|
pmc_wait_for_main_rc_osc(pmc);
|
||||||
|
pmc_wait_for_master_clock_ready(pmc);
|
||||||
|
|
||||||
|
/* Switch to main external oscillator */
|
||||||
|
ckgr_mor |= CKGR_MOR_MOSCSEL;
|
||||||
|
pmc->CKGR_MOR = ckgr_mor;
|
||||||
|
pmc_wait_for_main_osc_selection(pmc);
|
||||||
|
pmc_wait_for_master_clock_ready(pmc);
|
||||||
|
}
|
||||||
|
|
||||||
|
BSP_FAST_TEXT_SECTION void
|
||||||
|
atsam_power_handler_wait_mode(
|
||||||
|
const atsam_power_control *control,
|
||||||
|
atsam_power_state state
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_interrupt_level level;
|
||||||
|
volatile Pmc *pmc;
|
||||||
|
uint32_t mckr;
|
||||||
|
uint32_t fmr;
|
||||||
|
uint32_t fsmr;
|
||||||
|
|
||||||
|
(void) control;
|
||||||
|
pmc = PMC;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case ATSAM_POWER_OFF:
|
||||||
|
rtems_interrupt_disable(level);
|
||||||
|
|
||||||
|
mckr = pmc->PMC_MCKR;
|
||||||
|
|
||||||
|
/* Switch main clock to main RC oscillator (4MHz) */
|
||||||
|
pmc_use_main_rc_osc_4mhz(pmc);
|
||||||
|
pmc_set_master_clock_source(pmc, PMC_MCKR_CSS_MAIN_CLK);
|
||||||
|
pmc_wait_for_master_clock_ready(pmc);
|
||||||
|
pmc_set_master_clock_prescaler(pmc, PMC_MCKR_PRES_CLK_1);
|
||||||
|
pmc_wait_for_master_clock_ready(pmc);
|
||||||
|
pmc_set_master_clock_division(pmc, PMC_MCKR_MDIV_EQ_PCK);
|
||||||
|
pmc_wait_for_master_clock_ready(pmc);
|
||||||
|
|
||||||
|
/* Set flash wait state to 0 */
|
||||||
|
fmr = EFC->EEFC_FMR;
|
||||||
|
EFC->EEFC_FMR = EEFC_FMR_FWS(0);
|
||||||
|
|
||||||
|
/* Enter wait mode */
|
||||||
|
fsmr = pmc->PMC_FSMR;
|
||||||
|
pmc->PMC_FSMR = fsmr | PMC_FSMR_LPM;
|
||||||
|
pmc->CKGR_MOR = CKGR_MOR_KEY_PASSWD | CKGR_MOR_WAITMODE;
|
||||||
|
pmc_wait_for_master_clock_ready(pmc);
|
||||||
|
__asm__ volatile ( "wfe" : : : "memory" );
|
||||||
|
pmc->PMC_FSMR = fsmr;
|
||||||
|
|
||||||
|
/* Restore main clock */
|
||||||
|
pmc_set_master_clock_prescaler(pmc, mckr);
|
||||||
|
pmc_wait_for_master_clock_ready(pmc);
|
||||||
|
pmc_set_master_clock_division(pmc, mckr);
|
||||||
|
pmc_wait_for_master_clock_ready(pmc);
|
||||||
|
pmc_set_master_clock_source(pmc, mckr);
|
||||||
|
pmc_wait_for_master_clock_ready(pmc);
|
||||||
|
pmc_use_main_ext_osc(pmc);
|
||||||
|
|
||||||
|
/* Restore flash wait state */
|
||||||
|
EFC->EEFC_FMR = fmr;
|
||||||
|
|
||||||
|
rtems_interrupt_enable(level);
|
||||||
|
break;
|
||||||
|
case ATSAM_POWER_INIT:
|
||||||
|
rtems_interrupt_disable(level);
|
||||||
|
|
||||||
|
pmc->PMC_FSMR = (pmc->PMC_FSMR & ~PMC_FSMR_FLPM_Msk)
|
||||||
|
| PMC_FSMR_FLPM(PMC_FSMR_FLPM_FLASH_DEEP_POWERDOWN);
|
||||||
|
|
||||||
|
/* No Cortex-M7 Deep Sleep mode (Backup Mode) */
|
||||||
|
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||||
|
|
||||||
|
rtems_interrupt_enable(level);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -100,6 +100,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/start/pin-config.c
|
|||||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/start/pmc-config.c
|
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/start/pmc-config.c
|
||||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/start/power-clock.c
|
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/start/power-clock.c
|
||||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/start/power-rtc.c
|
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/start/power-rtc.c
|
||||||
|
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/start/power-wait.c
|
||||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/start/power.c
|
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/start/power.c
|
||||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/start/restart.c
|
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/start/restart.c
|
||||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/start/sdram-config.c
|
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/start/sdram-config.c
|
||||||
|
|||||||
Reference in New Issue
Block a user