mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #5157 from OpenNuvoton/nuvoton
NUC472/M453/M487/NANO130: Add updates for Nuvoton targetspull/5283/merge
commit
d6136b9790
|
@ -215,10 +215,15 @@ static void __eth_clk_pin_init()
|
|||
/* Init I/O Multi-function */
|
||||
/*---------------------------------------------------------------------------------------------------------*/
|
||||
// Configure RMII pins
|
||||
SYS->GPA_MFPL = SYS_GPA_MFPL_PA6MFP_EMAC_RMII_RXERR | SYS_GPA_MFPL_PA7MFP_EMAC_RMII_CRSDV;
|
||||
SYS->GPC_MFPL = SYS_GPC_MFPL_PC6MFP_EMAC_RMII_RXD1 | SYS_GPC_MFPL_PC7MFP_EMAC_RMII_RXD0;
|
||||
SYS->GPC_MFPH = SYS_GPC_MFPH_PC8MFP_EMAC_RMII_REFCLK;
|
||||
SYS->GPE_MFPH = SYS_GPE_MFPH_PE8MFP_EMAC_RMII_MDC |
|
||||
SYS->GPA_MFPL &= ~(SYS_GPA_MFPL_PA6MFP_Msk | SYS_GPA_MFPL_PA7MFP_Msk);
|
||||
SYS->GPA_MFPL |= SYS_GPA_MFPL_PA6MFP_EMAC_RMII_RXERR | SYS_GPA_MFPL_PA7MFP_EMAC_RMII_CRSDV;
|
||||
SYS->GPC_MFPL &= ~(SYS_GPC_MFPL_PC6MFP_Msk | SYS_GPC_MFPL_PC7MFP_Msk);
|
||||
SYS->GPC_MFPL |= SYS_GPC_MFPL_PC6MFP_EMAC_RMII_RXD1 | SYS_GPC_MFPL_PC7MFP_EMAC_RMII_RXD0;
|
||||
SYS->GPC_MFPH &= ~SYS_GPC_MFPH_PC8MFP_Msk;
|
||||
SYS->GPC_MFPH |= SYS_GPC_MFPH_PC8MFP_EMAC_RMII_REFCLK;
|
||||
SYS->GPE_MFPH &= ~(SYS_GPE_MFPH_PE8MFP_Msk | SYS_GPE_MFPH_PE9MFP_Msk | SYS_GPE_MFPH_PE10MFP_Msk |
|
||||
SYS_GPE_MFPH_PE11MFP_Msk | SYS_GPE_MFPH_PE12MFP_Msk);
|
||||
SYS->GPE_MFPH |= SYS_GPE_MFPH_PE8MFP_EMAC_RMII_MDC |
|
||||
SYS_GPE_MFPH_PE9MFP_EMAC_RMII_MDIO |
|
||||
SYS_GPE_MFPH_PE10MFP_EMAC_RMII_TXD0 |
|
||||
SYS_GPE_MFPH_PE11MFP_EMAC_RMII_TXD1 |
|
||||
|
|
|
@ -207,6 +207,9 @@ static void __eth_clk_pin_init()
|
|||
/* Init I/O Multi-function */
|
||||
/*---------------------------------------------------------------------------------------------------------*/
|
||||
// Configure RMII pins
|
||||
SYS->GPC_MFPL &= ~( SYS_GPC_MFPL_PC0MFP_Msk | SYS_GPC_MFPL_PC1MFP_Msk |
|
||||
SYS_GPC_MFPL_PC2MFP_Msk | SYS_GPC_MFPL_PC3MFP_Msk |
|
||||
SYS_GPC_MFPL_PC4MFP_Msk | SYS_GPC_MFPL_PC6MFP_Msk | SYS_GPC_MFPL_PC7MFP_Msk );
|
||||
SYS->GPC_MFPL |= SYS_GPC_MFPL_PC0MFP_EMAC_REFCLK |
|
||||
SYS_GPC_MFPL_PC1MFP_EMAC_MII_RXERR |
|
||||
SYS_GPC_MFPL_PC2MFP_EMAC_MII_RXDV |
|
||||
|
@ -215,12 +218,13 @@ static void __eth_clk_pin_init()
|
|||
SYS_GPC_MFPL_PC6MFP_EMAC_MII_TXD0 |
|
||||
SYS_GPC_MFPL_PC7MFP_EMAC_MII_TXD1;
|
||||
|
||||
|
||||
SYS->GPC_MFPH &= ~SYS_GPC_MFPH_PC8MFP_Msk;
|
||||
SYS->GPC_MFPH |= SYS_GPC_MFPH_PC8MFP_EMAC_MII_TXEN;
|
||||
// Enable high slew rate on all RMII pins
|
||||
PC->SLEWCTL |= 0x1DF;
|
||||
|
||||
// Configure MDC, MDIO at PB14 & PB15
|
||||
SYS->GPB_MFPH &= ~(SYS_GPB_MFPH_PB14MFP_Msk | SYS_GPB_MFPH_PB15MFP_Msk);
|
||||
SYS->GPB_MFPH |= SYS_GPB_MFPH_PB14MFP_EMAC_MII_MDC | SYS_GPB_MFPH_PB15MFP_EMAC_MII_MDIO;
|
||||
|
||||
}
|
||||
|
|
|
@ -117,10 +117,6 @@ struct pwmout_s {
|
|||
uint32_t pulsewidth_us;
|
||||
};
|
||||
|
||||
struct sleep_s {
|
||||
int powerdown;
|
||||
};
|
||||
|
||||
struct can_s {
|
||||
CANName can;
|
||||
char index;
|
||||
|
|
|
@ -339,25 +339,6 @@ static int i2c_set_int(i2c_t *obj, int inten)
|
|||
return inten_back;
|
||||
}
|
||||
|
||||
int i2c_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = i2c_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int i2c_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = i2c_modinit_tab + i2c_idx;
|
||||
struct nu_i2c_var *var = (struct nu_i2c_var *) modinit->var;
|
||||
if (var->obj) {
|
||||
// Disallow entering power-down mode if I2C transfer is enabled.
|
||||
if (i2c_active(var->obj)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << i2c_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastdata)
|
||||
{
|
||||
if (! buf || ! length) {
|
||||
|
|
|
@ -172,26 +172,6 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
pwmout_config(obj);
|
||||
}
|
||||
|
||||
int pwmout_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = pwm_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int pwm_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = pwm_modinit_tab + pwm_idx;
|
||||
if (modinit->modname != NC) {
|
||||
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(modinit->modname);
|
||||
uint32_t chn = NU_MODSUBINDEX(modinit->modname);
|
||||
// Disallow entering power-down mode if PWM counter is enabled.
|
||||
if ((pwm_base->CNTEN & (1 << chn)) && pwm_base->CMPDAT[chn]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << pwm_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t* obj)
|
||||
{
|
||||
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
|
||||
|
|
|
@ -87,6 +87,9 @@ time_t rtc_read(void)
|
|||
timeinfo.tm_mday = rtc_datetime.u32Day;
|
||||
timeinfo.tm_wday = rtc_datetime.u32DayOfWeek;
|
||||
timeinfo.tm_hour = rtc_datetime.u32Hour;
|
||||
if (rtc_datetime.u32TimeScale == RTC_CLOCK_12 && rtc_datetime.u32AmPm == RTC_PM) {
|
||||
timeinfo.tm_hour += 12;
|
||||
}
|
||||
timeinfo.tm_min = rtc_datetime.u32Minute;
|
||||
timeinfo.tm_sec = rtc_datetime.u32Second;
|
||||
|
||||
|
|
|
@ -656,33 +656,6 @@ int serial_irq_handler_asynch(serial_t *obj)
|
|||
return (obj->serial.event & (event_rx | event_tx));
|
||||
}
|
||||
|
||||
int serial_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = uart_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int uart_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = uart_modinit_tab + uart_idx;
|
||||
if (modinit->modname != NC) {
|
||||
UART_T *uart_base = (UART_T *) NU_MODBASE(modinit->modname);
|
||||
// Disallow entering power-down mode if Tx FIFO has data to flush
|
||||
if (! UART_IS_TX_EMPTY((uart_base))) {
|
||||
return 0;
|
||||
}
|
||||
// Disallow entering power-down mode if async Rx transfer (not PDMA) is on-going
|
||||
if (uart_base->INTEN & (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk)) {
|
||||
return 0;
|
||||
}
|
||||
// Disallow entering power-down mode if async Rx transfer (PDMA) is on-going
|
||||
if (uart_base->INTEN & UART_INTEN_RXPDMAEN_Msk) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << uart_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void uart0_vec_async(void)
|
||||
{
|
||||
uart_irq_async(uart0_var.obj);
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
*/
|
||||
|
||||
#include "sleep_api.h"
|
||||
#include "serial_api.h"
|
||||
#include "lp_ticker_api.h"
|
||||
|
||||
#if DEVICE_SLEEP
|
||||
|
||||
|
@ -25,77 +23,24 @@
|
|||
#include "objects.h"
|
||||
#include "PeripheralPins.h"
|
||||
|
||||
static void mbed_enter_sleep(struct sleep_s *obj);
|
||||
static void mbed_exit_sleep(struct sleep_s *obj);
|
||||
|
||||
int serial_allow_powerdown(void);
|
||||
int spi_allow_powerdown(void);
|
||||
int i2c_allow_powerdown(void);
|
||||
int pwmout_allow_powerdown(void);
|
||||
|
||||
/**
|
||||
* Enter Idle mode.
|
||||
* Enter idle mode, in which just CPU is halted.
|
||||
*/
|
||||
void hal_sleep(void)
|
||||
{
|
||||
struct sleep_s sleep_obj;
|
||||
sleep_obj.powerdown = 0;
|
||||
mbed_enter_sleep(&sleep_obj);
|
||||
mbed_exit_sleep(&sleep_obj);
|
||||
SYS_UnlockReg();
|
||||
CLK_Idle();
|
||||
SYS_LockReg();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter Power-down mode while no peripheral is active; otherwise, enter Idle mode.
|
||||
* Enter power-down mode, in which HXT/HIRC are halted.
|
||||
*/
|
||||
void hal_deepsleep(void)
|
||||
{
|
||||
struct sleep_s sleep_obj;
|
||||
sleep_obj.powerdown = 1;
|
||||
mbed_enter_sleep(&sleep_obj);
|
||||
mbed_exit_sleep(&sleep_obj);
|
||||
}
|
||||
|
||||
static void mbed_enter_sleep(struct sleep_s *obj)
|
||||
{
|
||||
// Check if serial allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = serial_allow_powerdown();
|
||||
}
|
||||
// Check if spi allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = spi_allow_powerdown();
|
||||
}
|
||||
// Check if i2c allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = i2c_allow_powerdown();
|
||||
}
|
||||
// Check if pwmout allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = pwmout_allow_powerdown();
|
||||
}
|
||||
// TODO: Check if other peripherals allow entering power-down mode
|
||||
|
||||
if (obj->powerdown) { // Power-down mode (HIRC/HXT disabled, LIRC/LXT enabled)
|
||||
SYS_UnlockReg();
|
||||
CLK_PowerDown();
|
||||
SYS_LockReg();
|
||||
}
|
||||
else { // CPU halt mode (HIRC/HXT enabled, LIRC/LXT enabled)
|
||||
SYS_UnlockReg();
|
||||
CLK_Idle();
|
||||
SYS_LockReg();
|
||||
}
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
}
|
||||
|
||||
static void mbed_exit_sleep(struct sleep_s *obj)
|
||||
{
|
||||
// TODO: TO BE CONTINUED
|
||||
|
||||
(void)obj;
|
||||
SYS_UnlockReg();
|
||||
CLK_PowerDown();
|
||||
SYS_LockReg();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -470,25 +470,6 @@ uint8_t spi_active(spi_t *obj)
|
|||
return (spi_base->CTL & SPI_CTL_SPIEN_Msk);
|
||||
}
|
||||
|
||||
int spi_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = spi_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int spi_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = spi_modinit_tab + spi_idx;
|
||||
if (modinit->modname != NC) {
|
||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(modinit->modname);
|
||||
// Disallow entering power-down mode if SPI transfer is enabled.
|
||||
if (spi_base->CTL & SPI_CTL_SPIEN_Msk) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << spi_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int spi_writeable(spi_t * obj)
|
||||
{
|
||||
// Receive FIFO must not be full to avoid receive FIFO overflow on next transmit/receive
|
||||
|
|
|
@ -118,10 +118,6 @@ struct pwmout_s {
|
|||
uint32_t pulsewidth_us;
|
||||
};
|
||||
|
||||
struct sleep_s {
|
||||
int powerdown;
|
||||
};
|
||||
|
||||
struct trng_s {
|
||||
uint8_t dummy;
|
||||
};
|
||||
|
|
|
@ -330,25 +330,6 @@ static int i2c_set_int(i2c_t *obj, int inten)
|
|||
return inten_back;
|
||||
}
|
||||
|
||||
int i2c_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = i2c_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int i2c_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = i2c_modinit_tab + i2c_idx;
|
||||
struct nu_i2c_var *var = (struct nu_i2c_var *) modinit->var;
|
||||
if (var->obj) {
|
||||
// Disallow entering power-down mode if I2C transfer is enabled.
|
||||
if (i2c_active(var->obj)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << i2c_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastdata)
|
||||
{
|
||||
if (! buf || ! length) {
|
||||
|
|
|
@ -167,26 +167,6 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
pwmout_config(obj, 1);
|
||||
}
|
||||
|
||||
int pwmout_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = pwm_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int pwm_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = pwm_modinit_tab + pwm_idx;
|
||||
if (modinit->modname != NC) {
|
||||
EPWM_T *pwm_base = (EPWM_T *) NU_MODBASE(modinit->modname);
|
||||
uint32_t chn = NU_MODSUBINDEX(modinit->modname);
|
||||
// Disallow entering power-down mode if PWM counter is enabled.
|
||||
if ((pwm_base->CNTEN & (1 << chn)) && pwm_base->CMPDAT[chn]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << pwm_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t* obj, int start)
|
||||
{
|
||||
EPWM_T *pwm_base = (EPWM_T *) NU_MODBASE(obj->pwm);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "mbed_error.h"
|
||||
#include "nu_modutil.h"
|
||||
#include "nu_miscutil.h"
|
||||
#include "mbed_mktime.h"
|
||||
|
||||
#define YEAR0 1900
|
||||
//#define EPOCH_YR 1970
|
||||
|
@ -88,11 +89,14 @@ time_t rtc_read(void)
|
|||
timeinfo.tm_mday = rtc_datetime.u32Day;
|
||||
timeinfo.tm_wday = rtc_datetime.u32DayOfWeek;
|
||||
timeinfo.tm_hour = rtc_datetime.u32Hour;
|
||||
if (rtc_datetime.u32TimeScale == RTC_CLOCK_12 && rtc_datetime.u32AmPm == RTC_PM) {
|
||||
timeinfo.tm_hour += 12;
|
||||
}
|
||||
timeinfo.tm_min = rtc_datetime.u32Minute;
|
||||
timeinfo.tm_sec = rtc_datetime.u32Second;
|
||||
|
||||
// Convert to timestamp
|
||||
time_t t = mktime(&timeinfo);
|
||||
time_t t = _rtc_mktime(&timeinfo);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
@ -104,18 +108,21 @@ void rtc_write(time_t t)
|
|||
}
|
||||
|
||||
// Convert timestamp to struct tm
|
||||
struct tm *timeinfo = localtime(&t);
|
||||
struct tm timeinfo;
|
||||
if (_rtc_localtime(t, &timeinfo) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
S_RTC_TIME_DATA_T rtc_datetime;
|
||||
|
||||
// Convert S_RTC_TIME_DATA_T to struct tm
|
||||
rtc_datetime.u32Year = timeinfo->tm_year + YEAR0;
|
||||
rtc_datetime.u32Month = timeinfo->tm_mon + 1;
|
||||
rtc_datetime.u32Day = timeinfo->tm_mday;
|
||||
rtc_datetime.u32DayOfWeek = timeinfo->tm_wday;
|
||||
rtc_datetime.u32Hour = timeinfo->tm_hour;
|
||||
rtc_datetime.u32Minute = timeinfo->tm_min;
|
||||
rtc_datetime.u32Second = timeinfo->tm_sec;
|
||||
rtc_datetime.u32Year = timeinfo.tm_year + YEAR0;
|
||||
rtc_datetime.u32Month = timeinfo.tm_mon + 1;
|
||||
rtc_datetime.u32Day = timeinfo.tm_mday;
|
||||
rtc_datetime.u32DayOfWeek = timeinfo.tm_wday;
|
||||
rtc_datetime.u32Hour = timeinfo.tm_hour;
|
||||
rtc_datetime.u32Minute = timeinfo.tm_min;
|
||||
rtc_datetime.u32Second = timeinfo.tm_sec;
|
||||
rtc_datetime.u32TimeScale = RTC_CLOCK_24;
|
||||
|
||||
// NOTE: Timing issue with write to RTC registers. This delay is empirical, not rational.
|
||||
|
|
|
@ -710,33 +710,6 @@ int serial_irq_handler_asynch(serial_t *obj)
|
|||
return (obj->serial.event & (event_rx | event_tx));
|
||||
}
|
||||
|
||||
int serial_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = uart_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int uart_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = uart_modinit_tab + uart_idx;
|
||||
if (modinit->modname != NC) {
|
||||
UART_T *uart_base = (UART_T *) NU_MODBASE(modinit->modname);
|
||||
// Disallow entering power-down mode if Tx FIFO has data to flush
|
||||
if (! UART_IS_TX_EMPTY((uart_base))) {
|
||||
return 0;
|
||||
}
|
||||
// Disallow entering power-down mode if async Rx transfer (not PDMA) is on-going
|
||||
if (uart_base->INTEN & (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk)) {
|
||||
return 0;
|
||||
}
|
||||
// Disallow entering power-down mode if async Rx transfer (PDMA) is on-going
|
||||
if (uart_base->INTEN & UART_INTEN_RXPDMAEN_Msk) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << uart_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void uart0_vec_async(void)
|
||||
{
|
||||
uart_irq_async(uart0_var.obj);
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
*/
|
||||
|
||||
#include "sleep_api.h"
|
||||
#include "serial_api.h"
|
||||
#include "lp_ticker_api.h"
|
||||
|
||||
#if DEVICE_SLEEP
|
||||
|
||||
|
@ -25,74 +23,24 @@
|
|||
#include "objects.h"
|
||||
#include "PeripheralPins.h"
|
||||
|
||||
static void mbed_enter_sleep(struct sleep_s *obj);
|
||||
static void mbed_exit_sleep(struct sleep_s *obj);
|
||||
|
||||
int serial_allow_powerdown(void);
|
||||
int spi_allow_powerdown(void);
|
||||
int i2c_allow_powerdown(void);
|
||||
int pwmout_allow_powerdown(void);
|
||||
|
||||
/**
|
||||
* Enter Idle mode.
|
||||
* Enter idle mode, in which just CPU is halted.
|
||||
*/
|
||||
void hal_sleep(void)
|
||||
{
|
||||
struct sleep_s sleep_obj;
|
||||
sleep_obj.powerdown = 0;
|
||||
mbed_enter_sleep(&sleep_obj);
|
||||
mbed_exit_sleep(&sleep_obj);
|
||||
SYS_UnlockReg();
|
||||
CLK_Idle();
|
||||
SYS_LockReg();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter Power-down mode while no peripheral is active; otherwise, enter Idle mode.
|
||||
* Enter power-down mode, in which HXT/HIRC are halted.
|
||||
*/
|
||||
void hal_deepsleep(void)
|
||||
{
|
||||
struct sleep_s sleep_obj;
|
||||
sleep_obj.powerdown = 1;
|
||||
mbed_enter_sleep(&sleep_obj);
|
||||
mbed_exit_sleep(&sleep_obj);
|
||||
}
|
||||
|
||||
static void mbed_enter_sleep(struct sleep_s *obj)
|
||||
{
|
||||
// Check if serial allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = serial_allow_powerdown();
|
||||
}
|
||||
// Check if spi allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = spi_allow_powerdown();
|
||||
}
|
||||
// Check if i2c allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = i2c_allow_powerdown();
|
||||
}
|
||||
// Check if pwmout allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = pwmout_allow_powerdown();
|
||||
}
|
||||
// TODO: Check if other peripherals allow entering power-down mode
|
||||
|
||||
if (obj->powerdown) { // Power-down mode (HIRC/HXT disabled, LIRC/LXT enabled)
|
||||
SYS_UnlockReg();
|
||||
CLK_PowerDown();
|
||||
SYS_LockReg();
|
||||
} else { // CPU halt mode (HIRC/HXT enabled, LIRC/LXT enabled)
|
||||
SYS_UnlockReg();
|
||||
CLK_Idle();
|
||||
SYS_LockReg();
|
||||
}
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
}
|
||||
|
||||
static void mbed_exit_sleep(struct sleep_s *obj)
|
||||
{
|
||||
(void)obj;
|
||||
SYS_UnlockReg();
|
||||
CLK_PowerDown();
|
||||
SYS_LockReg();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -461,25 +461,6 @@ uint8_t spi_active(spi_t *obj)
|
|||
return (spi_base->CTL & SPI_CTL_SPIEN_Msk);
|
||||
}
|
||||
|
||||
int spi_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = spi_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int spi_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = spi_modinit_tab + spi_idx;
|
||||
if (modinit->modname != NC) {
|
||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(modinit->modname);
|
||||
// Disallow entering power-down mode if SPI transfer is enabled.
|
||||
if (spi_base->CTL & SPI_CTL_SPIEN_Msk) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << spi_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int spi_writeable(spi_t * obj)
|
||||
{
|
||||
// Receive FIFO must not be full to avoid receive FIFO overflow on next transmit/receive
|
||||
|
|
|
@ -118,8 +118,8 @@ typedef enum {
|
|||
LED_GREEN = LED1,
|
||||
LED_YELLOW = LED2,
|
||||
// Button naming
|
||||
SW2 = PE_5,
|
||||
SW3 = PE_6,
|
||||
SW1 = PE_5,
|
||||
SW2 = PE_6,
|
||||
|
||||
} PinName;
|
||||
|
||||
|
|
|
@ -110,9 +110,6 @@ struct pwmout_s {
|
|||
uint32_t pulsewidth_us;
|
||||
};
|
||||
|
||||
struct sleep_s {
|
||||
int powerdown;
|
||||
};
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -49,23 +49,23 @@ static struct nu_gpio_irq_var gpio_irq_var_arr[] = {
|
|||
|
||||
#define NU_MAX_PORT (sizeof (gpio_irq_var_arr) / sizeof (gpio_irq_var_arr[0]))
|
||||
|
||||
#ifndef MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_ENABLE
|
||||
#define MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_ENABLE 0
|
||||
#ifndef MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE
|
||||
#define MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE 0
|
||||
#endif
|
||||
|
||||
#ifndef MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_ENABLE_LIST
|
||||
#define MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_ENABLE_LIST NC
|
||||
#ifndef MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE_LIST
|
||||
#define MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE_LIST NC
|
||||
#endif
|
||||
static PinName gpio_irq_debounce_arr[] = {
|
||||
MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_ENABLE_LIST
|
||||
MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE_LIST
|
||||
};
|
||||
|
||||
#ifndef MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE
|
||||
#define MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE GPIO_DBCLKSRC_IRC10K
|
||||
#ifndef MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE
|
||||
#define MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE GPIO_DBCLKSRC_IRC10K
|
||||
#endif
|
||||
|
||||
#ifndef MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE
|
||||
#define MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE GPIO_DBCLKSEL_16
|
||||
#ifndef MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE
|
||||
#define MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE GPIO_DBCLKSEL_16
|
||||
#endif
|
||||
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
|
||||
|
@ -90,12 +90,12 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
|
|||
// There is no need to call gpio_set() redundantly.
|
||||
|
||||
{
|
||||
#if MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_ENABLE
|
||||
#if MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE
|
||||
// Suppress compiler warning
|
||||
(void) gpio_irq_debounce_arr;
|
||||
|
||||
// Configure de-bounce clock source and sampling cycle time
|
||||
GPIO_SET_DEBOUNCE_TIME(MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE);
|
||||
GPIO_SET_DEBOUNCE_TIME(MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE);
|
||||
GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index);
|
||||
#else
|
||||
// Enable de-bounce if the pin is in the de-bounce enable list
|
||||
|
@ -112,7 +112,7 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
|
|||
if (pin_index == pin_index_debunce &&
|
||||
port_index == port_index_debounce) {
|
||||
// Configure de-bounce clock source and sampling cycle time
|
||||
GPIO_SET_DEBOUNCE_TIME(MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE);
|
||||
GPIO_SET_DEBOUNCE_TIME(MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE);
|
||||
GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -358,25 +358,6 @@ static int i2c_set_int(i2c_t *obj, int inten)
|
|||
return inten_back;
|
||||
}
|
||||
|
||||
int i2c_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = i2c_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int i2c_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = i2c_modinit_tab + i2c_idx;
|
||||
struct nu_i2c_var *var = (struct nu_i2c_var *) modinit->var;
|
||||
if (var->obj) {
|
||||
// Disallow entering power-down mode if I2C transfer is enabled.
|
||||
if (i2c_active(var->obj)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << i2c_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastdata)
|
||||
{
|
||||
if (! buf || ! length) {
|
||||
|
|
|
@ -141,7 +141,7 @@ timestamp_t lp_ticker_read()
|
|||
while (minor_clks == 0 || minor_clks == TMR2_CLK_PER_TMR2_INT);
|
||||
|
||||
// Add power-down compensation
|
||||
return ((uint64_t) major_minor_clks * US_PER_SEC / TMR3_CLK_PER_SEC / US_PER_TICK);
|
||||
return ((uint64_t) major_minor_clks * US_PER_SEC / TMR2_CLK_PER_SEC / US_PER_TICK);
|
||||
}
|
||||
while (0);
|
||||
}
|
||||
|
@ -222,6 +222,6 @@ static void lp_ticker_arm_cd(void)
|
|||
TIMER_EnableWakeup((TIMER_T *) NU_MODBASE(timer3_modinit.modname));
|
||||
// Wait 2 cycles of engine clock to ensure previous CTL write action is finish
|
||||
wait_us(30 * 2);
|
||||
timer3_base->CTL = ctl_timer3 | TIMER_CTL_TMR_EN_Msk;
|
||||
timer3_base->CTL |= ctl_timer3 | TIMER_CTL_TMR_EN_Msk;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"name": "NANO100",
|
||||
"config": {
|
||||
"gpio-irq-debounce-enable": {
|
||||
"help": "Enable GPIO IRQ debounce",
|
||||
"value": 0
|
||||
},
|
||||
"gpio-irq-debounce-enable-list": {
|
||||
"help": "Comma separated pin list to enable GPIO IRQ debounce",
|
||||
"value": "NC"
|
||||
},
|
||||
"gpio-irq-debounce-clock-source": {
|
||||
"help": "Select GPIO IRQ debounce clock source: GPIO_DBCLKSRC_HCLK or GPIO_DBCLKSRC_IRC10K",
|
||||
"value": "GPIO_DBCLKSRC_IRC10K"
|
||||
},
|
||||
|
||||
"gpio-irq-debounce-sample-rate": {
|
||||
"help": "Select GPIO IRQ debounce sample rate: GPIO_DBCLKSEL_1, GPIO_DBCLKSEL_2, GPIO_DBCLKSEL_4, ..., or GPIO_DBCLKSEL_32768",
|
||||
"value": "GPIO_DBCLKSEL_16"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -176,26 +176,6 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
pwmout_config(obj);
|
||||
}
|
||||
|
||||
int pwmout_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = pwm_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int pwm_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = pwm_modinit_tab + pwm_idx;
|
||||
if (modinit->modname != NC) {
|
||||
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(modinit->modname);
|
||||
uint32_t chn = NU_MODSUBINDEX(modinit->modname);
|
||||
// Disallow entering power-down mode if PWM counter is enabled.
|
||||
if (pwm_base->OE & (1 << chn)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << pwm_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t* obj)
|
||||
{
|
||||
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
|
||||
|
|
|
@ -87,6 +87,9 @@ time_t rtc_read(void)
|
|||
timeinfo.tm_mday = rtc_datetime.u32Day;
|
||||
timeinfo.tm_wday = rtc_datetime.u32DayOfWeek;
|
||||
timeinfo.tm_hour = rtc_datetime.u32Hour;
|
||||
if (rtc_datetime.u32TimeScale == RTC_CLOCK_12 && rtc_datetime.u32AmPm == RTC_PM) {
|
||||
timeinfo.tm_hour += 12;
|
||||
}
|
||||
timeinfo.tm_min = rtc_datetime.u32Minute;
|
||||
timeinfo.tm_sec = rtc_datetime.u32Second;
|
||||
|
||||
|
|
|
@ -597,33 +597,6 @@ int serial_irq_handler_asynch(serial_t *obj)
|
|||
return (obj->serial.event & (event_rx | event_tx));
|
||||
}
|
||||
|
||||
int serial_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = uart_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int uart_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = uart_modinit_tab + uart_idx;
|
||||
if (modinit->modname != NC) {
|
||||
UART_T *uart_base = (UART_T *) NU_MODBASE(modinit->modname);
|
||||
// Disallow entering power-down mode if Tx FIFO has data to flush
|
||||
if (! UART_IS_TX_EMPTY((uart_base))) {
|
||||
return 0;
|
||||
}
|
||||
// Disallow entering power-down mode if async Rx transfer (not PDMA) is on-going
|
||||
if (uart_base->IER & (UART_IER_RDA_IE_Msk | UART_IER_RTO_IE_Msk)) {
|
||||
return 0;
|
||||
}
|
||||
// Disallow entering power-down mode if async Rx transfer (PDMA) is on-going
|
||||
if (uart_base->CTL & UART_CTL_DMA_RX_EN_Msk) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << uart_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void uart_irq_async(serial_t *obj)
|
||||
{
|
||||
if (serial_is_irq_en(obj, RxIrq)) {
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
*/
|
||||
|
||||
#include "sleep_api.h"
|
||||
#include "serial_api.h"
|
||||
#include "lp_ticker_api.h"
|
||||
|
||||
#if DEVICE_SLEEP
|
||||
|
||||
|
@ -25,74 +23,24 @@
|
|||
#include "objects.h"
|
||||
#include "PeripheralPins.h"
|
||||
|
||||
static void mbed_enter_sleep(struct sleep_s *obj);
|
||||
static void mbed_exit_sleep(struct sleep_s *obj);
|
||||
|
||||
int serial_allow_powerdown(void);
|
||||
int spi_allow_powerdown(void);
|
||||
int i2c_allow_powerdown(void);
|
||||
int pwmout_allow_powerdown(void);
|
||||
|
||||
/**
|
||||
* Enter Idle mode.
|
||||
* Enter idle mode, in which just CPU is halted.
|
||||
*/
|
||||
void hal_sleep(void)
|
||||
{
|
||||
struct sleep_s sleep_obj;
|
||||
sleep_obj.powerdown = 0;
|
||||
mbed_enter_sleep(&sleep_obj);
|
||||
mbed_exit_sleep(&sleep_obj);
|
||||
SYS_UnlockReg();
|
||||
CLK_Idle();
|
||||
SYS_LockReg();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter Power-down mode while no peripheral is active; otherwise, enter Idle mode.
|
||||
* Enter power-down mode, in which HXT/HIRC are halted.
|
||||
*/
|
||||
void hal_deepsleep(void)
|
||||
{
|
||||
struct sleep_s sleep_obj;
|
||||
sleep_obj.powerdown = 1;
|
||||
mbed_enter_sleep(&sleep_obj);
|
||||
mbed_exit_sleep(&sleep_obj);
|
||||
}
|
||||
|
||||
static void mbed_enter_sleep(struct sleep_s *obj)
|
||||
{
|
||||
// Check if serial allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = serial_allow_powerdown();
|
||||
}
|
||||
// Check if spi allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = spi_allow_powerdown();
|
||||
}
|
||||
// Check if i2c allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = i2c_allow_powerdown();
|
||||
}
|
||||
// Check if pwmout allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = pwmout_allow_powerdown();
|
||||
}
|
||||
// TODO: Check if other peripherals allow entering power-down mode
|
||||
|
||||
if (obj->powerdown) { // Power-down mode (HIRC/HXT disabled, LIRC/LXT enabled)
|
||||
SYS_UnlockReg();
|
||||
CLK_PowerDown();
|
||||
SYS_LockReg();
|
||||
} else { // CPU halt mode (HIRC/HXT enabled, LIRC/LXT enabled)
|
||||
SYS_UnlockReg();
|
||||
CLK_Idle();
|
||||
SYS_LockReg();
|
||||
}
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
}
|
||||
|
||||
static void mbed_exit_sleep(struct sleep_s *obj)
|
||||
{
|
||||
(void)obj;
|
||||
SYS_UnlockReg();
|
||||
CLK_PowerDown();
|
||||
SYS_LockReg();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -505,24 +505,6 @@ uint8_t spi_active(spi_t *obj)
|
|||
return SPI_IS_BUSY(spi_base);
|
||||
}
|
||||
|
||||
int spi_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = spi_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int spi_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = spi_modinit_tab + spi_idx;
|
||||
if (modinit->modname != NC) {
|
||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(modinit->modname);
|
||||
if (SPI_IS_BUSY(spi_base)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << spi_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SPI0_IRQHandler(void)
|
||||
{
|
||||
spi_irq(spi0_var.obj);
|
||||
|
|
|
@ -118,10 +118,6 @@ struct pwmout_s {
|
|||
uint32_t pulsewidth_us;
|
||||
};
|
||||
|
||||
struct sleep_s {
|
||||
int powerdown;
|
||||
};
|
||||
|
||||
struct trng_s {
|
||||
uint8_t dummy;
|
||||
};
|
||||
|
|
|
@ -129,7 +129,7 @@ typedef struct {
|
|||
* 1 = This year is a leap year.
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define RTC_IS_LEAP_YEAR ((RTC->LEAPYEAR & (RTC_LEAPYEAR_LEAPYEAR_Msk))?1:0)
|
||||
#define RTC_IS_LEAP_YEAR() ((RTC->LEAPYEAR & (RTC_LEAPYEAR_LEAPYEAR_Msk))?1:0)
|
||||
|
||||
/**
|
||||
* @brief Clear alarm interrupt status.
|
||||
|
@ -139,7 +139,7 @@ typedef struct {
|
|||
* @return None
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define RTC_CLEAR_ALARM_INT_FLAG (RTC->INTSTS = RTC_INTSTS_ALMIF_Msk)
|
||||
#define RTC_CLEAR_ALARM_INT_FLAG() (RTC->INTSTS = RTC_INTSTS_ALMIF_Msk)
|
||||
|
||||
/**
|
||||
* @brief Clear tick interrupt status.
|
||||
|
@ -149,7 +149,7 @@ typedef struct {
|
|||
* @return None
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define RTC_CLEAR_TICK_INT_FLAG (RTC->INTSTS = RTC_INTSTS_TICKIF_Msk)
|
||||
#define RTC_CLEAR_TICK_INT_FLAG() (RTC->INTSTS = RTC_INTSTS_TICKIF_Msk)
|
||||
|
||||
/**
|
||||
* @brief Clear tamper detect pin status.
|
||||
|
@ -169,7 +169,7 @@ typedef struct {
|
|||
* @return Alarm interrupt status
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define RTC_GET_ALARM_INT_FLAG ((RTC->INTSTS & RTC_INTSTS_ALMIF_Msk) >> RTC_INTSTS_ALMIF_Pos)
|
||||
#define RTC_GET_ALARM_INT_FLAG() ((RTC->INTSTS & RTC_INTSTS_ALMIF_Msk) >> RTC_INTSTS_ALMIF_Pos)
|
||||
|
||||
/**
|
||||
* @brief Get alarm interrupt status.
|
||||
|
@ -179,7 +179,7 @@ typedef struct {
|
|||
* @return Alarm interrupt status
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define RTC_GET_TICK_INT_FLAG ((RTC->INTSTS & RTC_INTSTS_TICKIF_Msk) >> RTC_INTSTS_TICKIF_Pos)
|
||||
#define RTC_GET_TICK_INT_FLAG() ((RTC->INTSTS & RTC_INTSTS_TICKIF_Msk) >> RTC_INTSTS_TICKIF_Pos)
|
||||
|
||||
/**
|
||||
* @brief Get tamper detect pin status.
|
||||
|
|
|
@ -356,25 +356,6 @@ static int i2c_set_int(i2c_t *obj, int inten)
|
|||
return inten_back;
|
||||
}
|
||||
|
||||
int i2c_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = i2c_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int i2c_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = i2c_modinit_tab + i2c_idx;
|
||||
struct nu_i2c_var *var = (struct nu_i2c_var *) modinit->var;
|
||||
if (var->obj) {
|
||||
// Disallow entering power-down mode if I2C transfer is enabled.
|
||||
if (i2c_active(var->obj)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << i2c_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastdata)
|
||||
{
|
||||
if (! buf || ! length) {
|
||||
|
|
|
@ -195,26 +195,6 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
pwmout_config(obj);
|
||||
}
|
||||
|
||||
int pwmout_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = pwm_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int pwm_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = pwm_modinit_tab + pwm_idx;
|
||||
if (modinit->modname != NC) {
|
||||
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(modinit->modname);
|
||||
uint32_t chn = NU_MODSUBINDEX(modinit->modname);
|
||||
// Disallow entering power-down mode if PWM counter is enabled.
|
||||
if ((pwm_base->CNTEN & (1 << chn)) && pwm_base->CMPDAT[chn]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << pwm_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t* obj)
|
||||
{
|
||||
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
|
||||
|
|
|
@ -87,6 +87,9 @@ time_t rtc_read(void)
|
|||
timeinfo.tm_mday = rtc_datetime.u32Day;
|
||||
timeinfo.tm_wday = rtc_datetime.u32DayOfWeek;
|
||||
timeinfo.tm_hour = rtc_datetime.u32Hour;
|
||||
if (rtc_datetime.u32TimeScale == RTC_CLOCK_12 && rtc_datetime.u32AmPm == RTC_PM) {
|
||||
timeinfo.tm_hour += 12;
|
||||
}
|
||||
timeinfo.tm_min = rtc_datetime.u32Minute;
|
||||
timeinfo.tm_sec = rtc_datetime.u32Second;
|
||||
|
||||
|
|
|
@ -694,33 +694,6 @@ int serial_irq_handler_asynch(serial_t *obj)
|
|||
return (obj->serial.event & (event_rx | event_tx));
|
||||
}
|
||||
|
||||
int serial_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = uart_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int uart_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = uart_modinit_tab + uart_idx;
|
||||
if (modinit->modname != NC) {
|
||||
UART_T *uart_base = (UART_T *) NU_MODBASE(modinit->modname);
|
||||
// Disallow entering power-down mode if Tx FIFO has data to flush
|
||||
if (! UART_IS_TX_EMPTY((uart_base))) {
|
||||
return 0;
|
||||
}
|
||||
// Disallow entering power-down mode if async Rx transfer (not PDMA) is on-going
|
||||
if (uart_base->INTEN & (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk)) {
|
||||
return 0;
|
||||
}
|
||||
// Disallow entering power-down mode if async Rx transfer (PDMA) is on-going
|
||||
if (uart_base->INTEN & UART_INTEN_RXPDMAEN_Msk) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << uart_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void uart0_vec_async(void)
|
||||
{
|
||||
uart_irq_async(uart0_var.obj);
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
*/
|
||||
|
||||
#include "sleep_api.h"
|
||||
#include "serial_api.h"
|
||||
#include "lp_ticker_api.h"
|
||||
|
||||
#if DEVICE_SLEEP
|
||||
|
||||
|
@ -25,80 +23,24 @@
|
|||
#include "objects.h"
|
||||
#include "PeripheralPins.h"
|
||||
|
||||
static void mbed_enter_sleep(struct sleep_s *obj);
|
||||
static void mbed_exit_sleep(struct sleep_s *obj);
|
||||
|
||||
int serial_allow_powerdown(void);
|
||||
int spi_allow_powerdown(void);
|
||||
int i2c_allow_powerdown(void);
|
||||
int pwmout_allow_powerdown(void);
|
||||
|
||||
/**
|
||||
* Enter Idle mode.
|
||||
* Enter idle mode, in which just CPU is halted.
|
||||
*/
|
||||
void hal_sleep(void)
|
||||
{
|
||||
struct sleep_s sleep_obj;
|
||||
sleep_obj.powerdown = 0;
|
||||
mbed_enter_sleep(&sleep_obj);
|
||||
mbed_exit_sleep(&sleep_obj);
|
||||
SYS_UnlockReg();
|
||||
CLK_Idle();
|
||||
SYS_LockReg();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter Power-down mode while no peripheral is active; otherwise, enter Idle mode.
|
||||
* Enter power-down mode, in which HXT/HIRC are halted.
|
||||
*/
|
||||
void hal_deepsleep(void)
|
||||
{
|
||||
struct sleep_s sleep_obj;
|
||||
sleep_obj.powerdown = 1;
|
||||
mbed_enter_sleep(&sleep_obj);
|
||||
mbed_exit_sleep(&sleep_obj);
|
||||
}
|
||||
|
||||
static void mbed_enter_sleep(struct sleep_s *obj)
|
||||
{
|
||||
// Check if serial allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = serial_allow_powerdown();
|
||||
}
|
||||
// Check if spi allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = spi_allow_powerdown();
|
||||
}
|
||||
// Check if i2c allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = i2c_allow_powerdown();
|
||||
}
|
||||
// Check if pwmout allows entering power-down mode
|
||||
if (obj->powerdown) {
|
||||
obj->powerdown = pwmout_allow_powerdown();
|
||||
}
|
||||
// TODO: Check if other peripherals allow entering power-down mode
|
||||
|
||||
if (obj->powerdown) { // Power-down mode (HIRC/HXT disabled, LIRC/LXT enabled)
|
||||
SYS_UnlockReg();
|
||||
CLK_PowerDown();
|
||||
SYS_LockReg();
|
||||
}
|
||||
else { // CPU halt mode (HIRC/HXT enabled, LIRC/LXT enabled)
|
||||
// NOTE: NUC472's CLK_Idle() will also disable HIRC/HXT.
|
||||
SYS_UnlockReg();
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
CLK->PWRCTL &= ~CLK_PWRCTL_PDEN_Msk;
|
||||
__WFI();
|
||||
SYS_LockReg();
|
||||
}
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
}
|
||||
|
||||
static void mbed_exit_sleep(struct sleep_s *obj)
|
||||
{
|
||||
// TODO: TO BE CONTINUED
|
||||
|
||||
(void)obj;
|
||||
SYS_UnlockReg();
|
||||
CLK_PowerDown();
|
||||
SYS_LockReg();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -469,25 +469,6 @@ uint8_t spi_active(spi_t *obj)
|
|||
return (spi_base->CTL & SPI_CTL_SPIEN_Msk);
|
||||
}
|
||||
|
||||
int spi_allow_powerdown(void)
|
||||
{
|
||||
uint32_t modinit_mask = spi_modinit_mask;
|
||||
while (modinit_mask) {
|
||||
int spi_idx = nu_ctz(modinit_mask);
|
||||
const struct nu_modinit_s *modinit = spi_modinit_tab + spi_idx;
|
||||
if (modinit->modname != NC) {
|
||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(modinit->modname);
|
||||
// Disallow entering power-down mode if SPI transfer is enabled.
|
||||
if (spi_base->CTL & SPI_CTL_SPIEN_Msk) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
modinit_mask &= ~(1 << spi_idx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int spi_writeable(spi_t * obj)
|
||||
{
|
||||
// Receive FIFO must not be full to avoid receive FIFO overflow on next transmit/receive
|
||||
|
|
|
@ -3247,6 +3247,24 @@
|
|||
"extra_labels": ["NUVOTON", "NANO100", "NANO130KE3BN"],
|
||||
"is_disk_virtual": true,
|
||||
"supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"],
|
||||
"config": {
|
||||
"gpio-irq-debounce-enable": {
|
||||
"help": "Enable GPIO IRQ debounce",
|
||||
"value": 0
|
||||
},
|
||||
"gpio-irq-debounce-enable-list": {
|
||||
"help": "Comma separated pin list to enable GPIO IRQ debounce",
|
||||
"value": "NC"
|
||||
},
|
||||
"gpio-irq-debounce-clock-source": {
|
||||
"help": "Select GPIO IRQ debounce clock source: GPIO_DBCLKSRC_HCLK or GPIO_DBCLKSRC_IRC10K",
|
||||
"value": "GPIO_DBCLKSRC_IRC10K"
|
||||
},
|
||||
"gpio-irq-debounce-sample-rate": {
|
||||
"help": "Select GPIO IRQ debounce sample rate: GPIO_DBCLKSEL_1, GPIO_DBCLKSEL_2, GPIO_DBCLKSEL_4, ..., or GPIO_DBCLKSEL_32768",
|
||||
"value": "GPIO_DBCLKSEL_16"
|
||||
}
|
||||
},
|
||||
"inherits": ["Target"],
|
||||
"macros": ["CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\""],
|
||||
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH"],
|
||||
|
|
Loading…
Reference in New Issue