Merge pull request #5157 from OpenNuvoton/nuvoton

NUC472/M453/M487/NANO130: Add updates for Nuvoton targets
pull/5283/merge
Jimmy Brisson 2017-10-09 11:12:43 -05:00 committed by GitHub
commit d6136b9790
36 changed files with 110 additions and 660 deletions

View File

@ -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 |

View File

@ -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;
}

View File

@ -117,10 +117,6 @@ struct pwmout_s {
uint32_t pulsewidth_us;
};
struct sleep_s {
int powerdown;
};
struct can_s {
CANName can;
char index;

View File

@ -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) {

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -118,10 +118,6 @@ struct pwmout_s {
uint32_t pulsewidth_us;
};
struct sleep_s {
int powerdown;
};
struct trng_s {
uint8_t dummy;
};

View File

@ -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) {

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -110,9 +110,6 @@ struct pwmout_s {
uint32_t pulsewidth_us;
};
struct sleep_s {
int powerdown;
};
#ifdef __cplusplus
}
#endif

View File

@ -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;
}

View File

@ -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) {

View File

@ -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

View File

@ -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"
}
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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)) {

View File

@ -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

View File

@ -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);

View File

@ -118,10 +118,6 @@ struct pwmout_s {
uint32_t pulsewidth_us;
};
struct sleep_s {
int powerdown;
};
struct trng_s {
uint8_t dummy;
};

View File

@ -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.

View File

@ -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) {

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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"],