Skip to content

NUC472/M453/M487/NANO130: Add updates for Nuvoton targets #5157

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

Merged
merged 12 commits into from
Oct 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -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;

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,6 @@ struct pwmout_s {
uint32_t pulsewidth_us;
};

struct sleep_s {
int powerdown;
};

struct can_s {
CANName can;
char index;
Expand Down
19 changes: 0 additions & 19 deletions targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
20 changes: 0 additions & 20 deletions targets/TARGET_NUVOTON/TARGET_M451/pwmout_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_NUVOTON/TARGET_M451/rtc_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
27 changes: 0 additions & 27 deletions targets/TARGET_NUVOTON/TARGET_M451/serial_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
71 changes: 8 additions & 63 deletions targets/TARGET_NUVOTON/TARGET_M451/sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
*/

#include "sleep_api.h"
#include "serial_api.h"
#include "lp_ticker_api.h"

#if DEVICE_SLEEP

Expand All @@ -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
19 changes: 0 additions & 19 deletions targets/TARGET_NUVOTON/TARGET_M451/spi_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,6 @@ struct pwmout_s {
uint32_t pulsewidth_us;
};

struct sleep_s {
int powerdown;
};

struct trng_s {
uint8_t dummy;
};
Expand Down
19 changes: 0 additions & 19 deletions targets/TARGET_NUVOTON/TARGET_M480/i2c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
20 changes: 0 additions & 20 deletions targets/TARGET_NUVOTON/TARGET_M480/pwmout_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
25 changes: 16 additions & 9 deletions targets/TARGET_NUVOTON/TARGET_M480/rtc_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand All @@ -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.
Expand Down
Loading