From 657d90db2cda00f034940ba9495136592b781ddc Mon Sep 17 00:00:00 2001 From: ccli8 Date: Thu, 10 Nov 2016 16:19:47 +0800 Subject: [PATCH 01/12] [NUC472/M453] Fix I2C issues 1. Fix error on return of i2c_byte_write(). 2. Fix error in zero-length transfer corner case. --- targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c | 6 +++++- targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c b/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c index 02808b49331..bf1ee28ef63 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c @@ -221,7 +221,7 @@ int i2c_byte_read(i2c_t *obj, int last) int i2c_byte_write(i2c_t *obj, int data) { - return i2c_do_write(obj, (data & 0xFF), 0); + return i2c_do_write(obj, (data & 0xFF), 0) == 0 ? 1 : 0; } #if DEVICE_I2CSLAVE @@ -352,6 +352,10 @@ int i2c_allow_powerdown(void) static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastdata) { + if (! buf || ! length) { + return 0; + } + int tran_len = 0; i2c_disable_int(obj); diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c index 2bc453cc60d..73fd4f646ee 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c @@ -238,7 +238,7 @@ int i2c_byte_read(i2c_t *obj, int last) int i2c_byte_write(i2c_t *obj, int data) { - return i2c_do_write(obj, (data & 0xFF), 0); + return i2c_do_write(obj, (data & 0xFF), 0) == 0 ? 1 : 0; } #if DEVICE_I2CSLAVE @@ -369,6 +369,10 @@ int i2c_allow_powerdown(void) static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastdata) { + if (! buf || ! length) { + return 0; + } + int tran_len = 0; i2c_disable_int(obj); From e0f97e5c80797751f5580bf7f9fdc29634d8de19 Mon Sep 17 00:00:00 2001 From: ccli8 Date: Mon, 14 Nov 2016 16:57:49 +0800 Subject: [PATCH 02/12] [NUC472/M453] Support separate enable of GPIO IRQ de-bounce --- .../TARGET_NUVOTON/TARGET_M451/gpio_irq_api.c | 58 +++++++++++++------ .../TARGET_NUVOTON/TARGET_M451/mbed_lib.json | 4 ++ .../TARGET_NUC472/gpio_irq_api.c | 58 +++++++++++++------ .../TARGET_NUC472/mbed_lib.json | 4 ++ 4 files changed, 90 insertions(+), 34 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/gpio_irq_api.c b/targets/TARGET_NUVOTON/TARGET_M451/gpio_irq_api.c index f08a6b01914..7ced1ebf828 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/gpio_irq_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/gpio_irq_api.c @@ -52,22 +52,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])) -#ifdef MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE -#define M451_GPIO_IRQ_DEBOUNCE_ENABLE MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE -#else -#define M451_GPIO_IRQ_DEBOUNCE_ENABLE 0 +#ifndef MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE +#define MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE 0 #endif -#ifdef MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE -#define M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE -#else -#define M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE GPIO_DBCTL_DBCLKSRC_LIRC +#ifndef MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE_LIST +#define MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE_LIST NC +#endif +static PinName gpio_irq_debounce_arr[] = { + MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE_LIST +}; + +#ifndef MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE +#define MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE GPIO_DBCTL_DBCLKSRC_LIRC #endif -#ifdef MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE -#define M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE -#else -#define M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE GPIO_DBCTL_DBCLKSEL_16 +#ifndef MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE +#define MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE GPIO_DBCTL_DBCLKSEL_16 #endif int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) @@ -89,13 +90,36 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 GPIO_T *gpio_base = NU_PORT_BASE(port_index); //gpio_set(pin); -#if M451_GPIO_IRQ_DEBOUNCE_ENABLE - // Configure de-bounce clock source and sampling cycle time - GPIO_SET_DEBOUNCE_TIME(M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE); - GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); + { +#if MBED_CONF_M451_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_M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE); + GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); #else - GPIO_DISABLE_DEBOUNCE(gpio_base, 1 << pin_index); + // Enable de-bounce if the pin is in the de-bounce enable list + + // De-bounce defaults to disabled. + GPIO_DISABLE_DEBOUNCE(gpio_base, 1 << pin_index); + + PinName *debounce_pos = gpio_irq_debounce_arr; + PinName *debounce_end = gpio_irq_debounce_arr + sizeof (gpio_irq_debounce_arr) / sizeof (gpio_irq_debounce_arr[0]); + for (; debounce_pos != debounce_end && *debounce_pos != NC; debounce_pos ++) { + uint32_t pin_index_debunce = NU_PINNAME_TO_PIN(*debounce_pos); + uint32_t port_index_debounce = NU_PINNAME_TO_PORT(*debounce_pos); + + 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_M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE); + GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); + break; + } + } #endif + } struct nu_gpio_irq_var *var = gpio_irq_var_arr + port_index; diff --git a/targets/TARGET_NUVOTON/TARGET_M451/mbed_lib.json b/targets/TARGET_NUVOTON/TARGET_M451/mbed_lib.json index 3832d8f9ec2..cfa14e99b08 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/mbed_lib.json +++ b/targets/TARGET_NUVOTON/TARGET_M451/mbed_lib.json @@ -5,6 +5,10 @@ "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_DBCTL_DBCLKSRC_HCLK or GPIO_DBCTL_DBCLKSRC_LIRC", "value": "GPIO_DBCTL_DBCLKSRC_LIRC" diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/gpio_irq_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/gpio_irq_api.c index 62e036593c9..754a24e6f12 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/gpio_irq_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/gpio_irq_api.c @@ -58,22 +58,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])) -#ifdef MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_ENABLE -#define NUC472_GPIO_IRQ_DEBOUNCE_ENABLE MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_ENABLE -#else -#define NUC472_GPIO_IRQ_DEBOUNCE_ENABLE 0 +#ifndef MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_ENABLE +#define MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_ENABLE 0 #endif -#ifdef MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE -#define NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE -#else -#define NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE GPIO_DBCTL_DBCLKSRC_IRC10K +#ifndef MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_ENABLE_LIST +#define MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_ENABLE_LIST NC +#endif +static PinName gpio_irq_debounce_arr[] = { + MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_ENABLE_LIST +}; + +#ifndef MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE +#define MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE GPIO_DBCTL_DBCLKSRC_IRC10K #endif -#ifdef MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE -#define NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE -#else -#define NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE GPIO_DBCTL_DBCLKSEL_16 +#ifndef MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE +#define MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE GPIO_DBCTL_DBCLKSEL_16 #endif int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) @@ -95,13 +96,36 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 GPIO_T *gpio_base = NU_PORT_BASE(port_index); //gpio_set(pin); -#if NUC472_GPIO_IRQ_DEBOUNCE_ENABLE - // Configure de-bounce clock source and sampling cycle time - GPIO_SET_DEBOUNCE_TIME(NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE); - GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); + { +#if MBED_CONF_NUC472_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_NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE); + GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); #else - GPIO_DISABLE_DEBOUNCE(gpio_base, 1 << pin_index); + // Enable de-bounce if the pin is in the de-bounce enable list + + // De-bounce defaults to disabled. + GPIO_DISABLE_DEBOUNCE(gpio_base, 1 << pin_index); + + PinName *debounce_pos = gpio_irq_debounce_arr; + PinName *debounce_end = gpio_irq_debounce_arr + sizeof (gpio_irq_debounce_arr) / sizeof (gpio_irq_debounce_arr[0]); + for (; debounce_pos != debounce_end && *debounce_pos != NC; debounce_pos ++) { + uint32_t pin_index_debunce = NU_PINNAME_TO_PIN(*debounce_pos); + uint32_t port_index_debounce = NU_PINNAME_TO_PORT(*debounce_pos); + + 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_NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE); + GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); + break; + } + } #endif + } struct nu_gpio_irq_var *var = gpio_irq_var_arr + port_index; diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/mbed_lib.json b/targets/TARGET_NUVOTON/TARGET_NUC472/mbed_lib.json index 533c883f100..698dea779c9 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/mbed_lib.json +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/mbed_lib.json @@ -5,6 +5,10 @@ "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_DBCTL_DBCLKSRC_HCLK or GPIO_DBCTL_DBCLKSRC_IRC10K", "value": "GPIO_DBCTL_DBCLKSRC_IRC10K" From fe883d42ab091f6a148cd232ade1f3c263a34944 Mon Sep 17 00:00:00 2001 From: ccli8 Date: Tue, 15 Nov 2016 16:31:33 +0800 Subject: [PATCH 03/12] [M453] Fix CI tests-api-analogin failed 1. Fix ADC convert finish check error. 2. Set ADC Vref to internal by default. --- .../TARGET_M451/TARGET_NUMAKER_PFM_M453/mbed_overrides.c | 5 ++--- targets/TARGET_NUVOTON/TARGET_M451/analogin_api.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/mbed_overrides.c b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/mbed_overrides.c index 67f7b9dbb89..af1e63fbe41 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/mbed_overrides.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/mbed_overrides.c @@ -64,9 +64,8 @@ void mbed_sdk_init(void) CLK_SetCoreClock(72000000); #if DEVICE_ANALOGIN - // FIXME: Check voltage reference for EADC - /* Vref connect to AVDD */ - //SYS->VREFCTL = (SYS->VREFCTL & ~SYS_VREFCTL_VREFCTL_Msk) | SYS_VREFCTL_VREF_AVDD; + /* Vref connect to internal */ + SYS->VREFCTL = (SYS->VREFCTL & ~SYS_VREFCTL_VREFCTL_Msk) | SYS_VREFCTL_VREF_3_072V; #endif /* Update System Core Clock */ diff --git a/targets/TARGET_NUVOTON/TARGET_M451/analogin_api.c b/targets/TARGET_NUVOTON/TARGET_M451/analogin_api.c index 6ea0173958c..630de602cf2 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/analogin_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/analogin_api.c @@ -141,7 +141,7 @@ uint16_t analogin_read_u16(analogin_t *obj) uint32_t chn = NU_MODSUBINDEX(obj->adc); EADC_START_CONV(eadc_base, 1 << chn); - while (EADC_GET_PENDING_CONV(eadc_base) & (1 << chn)); + while (EADC_GET_DATA_VALID_FLAG(eadc_base, 1 << chn) != (1 << chn)); uint16_t conv_res_12 = EADC_GET_CONV_DATA(eadc_base, chn); // Just 12 bits are effective. Convert to 16 bits. // conv_res_12: 0000 b11b10b9b8 b7b6b5b4 b3b2b1b0 From 35b2ad5a2c5df6c898d271885c717642e6aaeb61 Mon Sep 17 00:00:00 2001 From: ccli8 Date: Fri, 18 Nov 2016 11:23:49 +0800 Subject: [PATCH 04/12] [NUC472] Fix CI tests-api-analogin failed 1. Fix UNO pins A5-A7 don't support analog-in by replacing ADC with EADC to implement analog-in HAL. 2. Update CLK driver to fix EADC clock divider setting error. Also fix CLK_Idle() together. --- .../PeripheralNames.h | 29 ++- .../PeripheralPins.c | 12 +- .../mbed_overrides.c | 2 + .../TARGET_NUC472/analogin_api.c | 96 +++----- .../device/StdDriver/nuc472_clk.c | 216 ++++++++++++++---- .../device/StdDriver/nuc472_clk.h | 74 ++++-- 6 files changed, 277 insertions(+), 152 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralNames.h b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralNames.h index 66621e43b07..217d66d9019 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralNames.h +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralNames.h @@ -44,18 +44,23 @@ typedef enum { #endif typedef enum { - ADC_0_0 = (int) NU_MODNAME(ADC_BASE, 0), - ADC_0_1 = (int) NU_MODNAME(ADC_BASE, 1), - ADC_0_2 = (int) NU_MODNAME(ADC_BASE, 2), - ADC_0_3 = (int) NU_MODNAME(ADC_BASE, 3), - ADC_0_4 = (int) NU_MODNAME(ADC_BASE, 4), - ADC_0_5 = (int) NU_MODNAME(ADC_BASE, 5), - ADC_0_6 = (int) NU_MODNAME(ADC_BASE, 6), - ADC_0_7 = (int) NU_MODNAME(ADC_BASE, 7), - ADC_0_8 = (int) NU_MODNAME(ADC_BASE, 8), - ADC_0_9 = (int) NU_MODNAME(ADC_BASE, 9), - ADC_0_10 = (int) NU_MODNAME(ADC_BASE, 10), - ADC_0_11 = (int) NU_MODNAME(ADC_BASE, 11) + ADC_0_0 = (int) NU_MODNAME(EADC_BASE, 0), + ADC_0_1 = (int) NU_MODNAME(EADC_BASE, 1), + ADC_0_2 = (int) NU_MODNAME(EADC_BASE, 2), + ADC_0_3 = (int) NU_MODNAME(EADC_BASE, 3), + ADC_0_4 = (int) NU_MODNAME(EADC_BASE, 4), + ADC_0_5 = (int) NU_MODNAME(EADC_BASE, 5), + ADC_0_6 = (int) NU_MODNAME(EADC_BASE, 6), + ADC_0_7 = (int) NU_MODNAME(EADC_BASE, 7), + + ADC_1_0 = (int) NU_MODNAME(EADC_BASE, 8), + ADC_1_1 = (int) NU_MODNAME(EADC_BASE, 9), + ADC_1_2 = (int) NU_MODNAME(EADC_BASE, 10), + ADC_1_3 = (int) NU_MODNAME(EADC_BASE, 11), + ADC_1_4 = (int) NU_MODNAME(EADC_BASE, 12), + ADC_1_5 = (int) NU_MODNAME(EADC_BASE, 13), + ADC_1_6 = (int) NU_MODNAME(EADC_BASE, 14), + ADC_1_7 = (int) NU_MODNAME(EADC_BASE, 15), } ADCName; typedef enum { diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c index a609071396f..b1ad6b92a4f 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c @@ -210,10 +210,14 @@ const PinMap PinMap_ADC[] = { {PE_6, ADC_0_6, SYS_GPE_MFPL_PE6MFP_ADC0_6}, // ADC0_6 {PE_7, ADC_0_7, SYS_GPE_MFPL_PE7MFP_ADC0_7}, // ADC0_7 - {PE_8, ADC_0_8, SYS_GPE_MFPH_PE8MFP_ADC1_0}, // ADC0_8/ADC1_0 - {PE_9, ADC_0_9, SYS_GPE_MFPH_PE9MFP_ADC1_1}, // ADC0_9/ADC1_1 - {PE_10, ADC_0_10, SYS_GPE_MFPH_PE10MFP_ADC1_2}, // ADC0_10/ADC1_2 - {PE_11, ADC_0_11, SYS_GPE_MFPH_PE11MFP_ADC1_3}, // ADC0_11/ADC1_3 + {PE_8, ADC_1_0, SYS_GPE_MFPH_PE8MFP_ADC1_0}, // ADC1_0 + {PE_9, ADC_1_1, SYS_GPE_MFPH_PE9MFP_ADC1_1}, // ADC1_1 + {PE_10, ADC_1_2, SYS_GPE_MFPH_PE10MFP_ADC1_2}, // ADC1_2 + {PE_11, ADC_1_3, SYS_GPE_MFPH_PE11MFP_ADC1_3}, // ADC1_3 + {PE_12, ADC_1_4, SYS_GPE_MFPH_PE12MFP_ADC1_4}, // ADC1_4 + {PE_13, ADC_1_5, SYS_GPE_MFPH_PE13MFP_ADC1_5}, // ADC1_5 + {PE_14, ADC_1_6, SYS_GPE_MFPH_PE14MFP_ADC1_6}, // ADC1_6 + {PE_15, ADC_1_7, SYS_GPE_MFPH_PE15MFP_ADC1_7}, // ADC1_7 {NC, NC, 0} }; diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/mbed_overrides.c b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/mbed_overrides.c index c9a971055c0..3316802238b 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/mbed_overrides.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/mbed_overrides.c @@ -77,6 +77,8 @@ void mbed_sdk_init(void) #if DEVICE_ANALOGIN /* Vref connect to AVDD */ SYS->VREFCTL = (SYS->VREFCTL & ~SYS_VREFCTL_VREFCTL_Msk) | SYS_VREFCTL_VREF_AVDD; + /* Switch ADC0 to EADC mode */ + SYS->VREFCTL = (SYS->VREFCTL & ~SYS_VREFCTL_ADCMODESEL_Msk) | SYS_VREFCTL_ADCMODESEL_EADC; #endif /* Update System Core Clock */ diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/analogin_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/analogin_api.c index 11365b1de42..4ea8bd4c409 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/analogin_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/analogin_api.c @@ -23,60 +23,26 @@ #include "PeripheralPins.h" #include "nu_modutil.h" -struct nu_adc_var { - uint32_t en_msk; -}; - -static struct nu_adc_var adc0_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc1_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc2_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc3_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc4_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc5_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc6_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc7_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc8_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc9_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc10_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc11_var = { - .en_msk = 0 -}; +static uint32_t adc_modinit_mask = 0; static const struct nu_modinit_s adc_modinit_tab[] = { - {ADC_0_0, ADC_MODULE, CLK_CLKSEL1_ADCSEL_HIRC, CLK_CLKDIV0_ADC(1), ADC_RST, ADC_IRQn, &adc0_var}, - {ADC_0_1, ADC_MODULE, CLK_CLKSEL1_ADCSEL_HIRC, CLK_CLKDIV0_ADC(1), ADC_RST, ADC_IRQn, &adc1_var}, - {ADC_0_2, ADC_MODULE, CLK_CLKSEL1_ADCSEL_HIRC, CLK_CLKDIV0_ADC(1), ADC_RST, ADC_IRQn, &adc2_var}, - {ADC_0_3, ADC_MODULE, CLK_CLKSEL1_ADCSEL_HIRC, CLK_CLKDIV0_ADC(1), ADC_RST, ADC_IRQn, &adc3_var}, - {ADC_0_4, ADC_MODULE, CLK_CLKSEL1_ADCSEL_HIRC, CLK_CLKDIV0_ADC(1), ADC_RST, ADC_IRQn, &adc4_var}, - {ADC_0_5, ADC_MODULE, CLK_CLKSEL1_ADCSEL_HIRC, CLK_CLKDIV0_ADC(1), ADC_RST, ADC_IRQn, &adc5_var}, - {ADC_0_6, ADC_MODULE, CLK_CLKSEL1_ADCSEL_HIRC, CLK_CLKDIV0_ADC(1), ADC_RST, ADC_IRQn, &adc6_var}, - {ADC_0_7, ADC_MODULE, CLK_CLKSEL1_ADCSEL_HIRC, CLK_CLKDIV0_ADC(1), ADC_RST, ADC_IRQn, &adc7_var}, - {ADC_0_8, ADC_MODULE, CLK_CLKSEL1_ADCSEL_HIRC, CLK_CLKDIV0_ADC(1), ADC_RST, ADC_IRQn, &adc8_var}, - {ADC_0_9, ADC_MODULE, CLK_CLKSEL1_ADCSEL_HIRC, CLK_CLKDIV0_ADC(1), ADC_RST, ADC_IRQn, &adc9_var}, - {ADC_0_10, ADC_MODULE, CLK_CLKSEL1_ADCSEL_HIRC, CLK_CLKDIV0_ADC(1), ADC_RST, ADC_IRQn, &adc10_var}, - {ADC_0_11, ADC_MODULE, CLK_CLKSEL1_ADCSEL_HIRC, CLK_CLKDIV0_ADC(1), ADC_RST, ADC_IRQn, &adc11_var} + {ADC_0_0, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + {ADC_0_1, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + {ADC_0_2, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + {ADC_0_3, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + {ADC_0_4, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + {ADC_0_5, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + {ADC_0_6, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + {ADC_0_7, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + + {ADC_1_0, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + {ADC_1_1, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + {ADC_1_2, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + {ADC_1_3, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + {ADC_1_4, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + {ADC_1_5, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + {ADC_1_6, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, + {ADC_1_7, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL} }; void analogin_init(analogin_t *obj, PinName pin) @@ -88,8 +54,10 @@ void analogin_init(analogin_t *obj, PinName pin) MBED_ASSERT(modinit != NULL); MBED_ASSERT(modinit->modname == obj->adc); + EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc); + // NOTE: All channels (identified by ADCName) share a ADC module. This reset will also affect other channels of the same ADC module. - if (! ((struct nu_adc_var *) modinit->var)->en_msk) { + if (! adc_modinit_mask) { // Reset this module if no channel enabled SYS_ResetModule(modinit->rsetidx); @@ -98,33 +66,29 @@ void analogin_init(analogin_t *obj, PinName pin) // Enable clock of paired channels CLK_EnableModuleClock(modinit->clkidx); - // Power on ADC - ADC_POWER_ON(ADC); + // Make EADC_module ready to convert + EADC_Open(eadc_base, 0); } - ADC_T *adc_base = (ADC_T *) NU_MODBASE(obj->adc); uint32_t chn = NU_MODSUBINDEX(obj->adc); // Wire pinout pinmap_pinout(pin, PinMap_ADC); - // Enable channel 0 - ADC_Open(adc_base, - ADC_INPUT_MODE_SINGLE_END, - ADC_OPERATION_MODE_SINGLE, - 1 << chn); // ADC_CH_0_MASK~ADC_CH_11_MASK + // Configure the sample module Nmod for analog input channel Nch and software trigger source + EADC_ConfigSampleModule(eadc_base, chn, EADC_SOFTWARE_TRIGGER, chn % 8); - ((struct nu_adc_var *) modinit->var)->en_msk |= 1 << chn; + adc_modinit_mask |= 1 << chn; } uint16_t analogin_read_u16(analogin_t *obj) { - ADC_T *adc_base = (ADC_T *) NU_MODBASE(obj->adc); + EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc); uint32_t chn = NU_MODSUBINDEX(obj->adc); - ADC_START_CONV(adc_base); - while (adc_base->CTL & ADC_CTL_SWTRG_Msk); - uint16_t conv_res_12 = ADC_GET_CONVERSION_DATA(adc_base, chn); + EADC_START_CONV(eadc_base, 1 << chn); + while (EADC_GET_DATA_VALID_FLAG(eadc_base, 1 << chn) != (1 << chn)); + uint16_t conv_res_12 = EADC_GET_CONV_DATA(eadc_base, chn); // Just 12 bits are effective. Convert to 16 bits. // conv_res_12: 0000 b11b10b9b8 b7b6b5b4 b3b2b1b0 // conv_res_16: b11b10b9b8 b7b6b5b4 b3b2b1b0 b11b10b9b8 diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_clk.c b/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_clk.c index 94ebbe68351..2262de8dfa9 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_clk.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_clk.c @@ -1,8 +1,8 @@ /**************************************************************************//** * @file clk.c * @version V1.00 - * $Revision: 29 $ - * $Date: 14/09/26 2:10p $ + * $Revision: 35 $ + * $Date: 16/03/04 3:42p $ * @brief NUC472/NUC442 CLK driver source file * * @note @@ -84,7 +84,13 @@ void CLK_PowerDown(void) */ void CLK_Idle(void) { - CLK->PWRCTL |= (CLK_PWRCTL_PDEN_Msk ); + /* Set the processor uses sleep as its low power mode */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + /* Set chip in idle mode because of WFI command */ + CLK->PWRCTL &= ~(CLK_PWRCTL_PDEN_Msk ); + + /* Chip enter idle mode after CPU run WFI instruction */ __WFI(); } @@ -162,8 +168,8 @@ uint32_t CLK_GetPLLClockFreq(void) u32PllReg = CLK->PLLCTL; - if((u32PllReg & CLK_PLLCTL_PLLREMAP_Msk)) - return 0; + if(u32PllReg & (CLK_PLLCTL_PD_Msk | CLK_PLLCTL_OE_Msk)) + return 0; /* PLL is in power down mode or fix low */ if(u32PllReg & CLK_PLLCTL_PLLSRC_Msk) u32PLLSrc = __HIRC; @@ -187,8 +193,8 @@ uint32_t CLK_GetPLLClockFreq(void) u32NF = (u32PllReg & CLK_PLLCTL_FBDIV_Msk) + 2; u32NR = ( (u32PllReg & CLK_PLLCTL_INDIV_Msk)>>CLK_PLLCTL_INDIV_Pos ) + 2; - u32Freq = u32PLLSrc * u32NF / u32NR / u32NO ; - + /* u32PLLSrc is shifted 2 bits to avoid overflow */ + u32Freq = (((u32PLLSrc >> 2) * u32NF) / (u32NR * u32NO) << 2); return u32Freq; } @@ -272,7 +278,7 @@ void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv) * |\ref EBI_MODULE | x | x | * |\ref USBH_MODULE |\ref CLK_CLKSEL0_USBHSEL_PLL |\ref CLK_CLKDIV0_USB(x) | * |\ref USBH_MODULE |\ref CLK_CLKSEL0_USBHSEL_PLL2 |\ref CLK_CLKDIV0_USB(x) | - * |\ref EMAC_MODULE |\ref CLK_CLKSEL0_EMACSEL_PLL |\ref CLK_CLKDIV3_EMAC(x) | + * |\ref EMAC_MODULE | x |\ref CLK_CLKDIV3_EMAC(x) | * |\ref SDH_MODULE |\ref CLK_CLKSEL0_SDHSEL_HXT |\ref CLK_CLKDIV0_SDH(x) | * |\ref SDH_MODULE |\ref CLK_CLKSEL0_SDHSEL_PLL |\ref CLK_CLKDIV0_SDH(x) | * |\ref SDH_MODULE |\ref CLK_CLKSEL0_SDHSEL_HCLK |\ref CLK_CLKDIV0_SDH(x) | @@ -282,15 +288,16 @@ void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv) * |\ref CAP_MODULE |\ref CLK_CLKSEL0_CAPSEL_PLL2 |\ref CLK_CLKDIV3_CAP(x) | * |\ref CAP_MODULE |\ref CLK_CLKSEL0_CAPSEL_HCLK |\ref CLK_CLKDIV3_CAP(x) | * |\ref CAP_MODULE |\ref CLK_CLKSEL0_CAPSEL_HIRC |\ref CLK_CLKDIV3_CAP(x) | - * |\ref SENCLK_MODULE | x | x | + * |\ref SEN_MODULE | x | x | * |\ref USBD_MODULE | x | x | * |\ref CRPT_MODULE | x | x | * |\ref ECAP1_MODULE | x | x | * |\ref ECAP0_MODULE | x | x | - * |\ref EADC_MODULE | x | x | + * |\ref EADC_MODULE |\ref CLK_CLKSEL1_ADCSEL_HXT |\ref CLK_CLKDIV0_ADC(x) | + * |\ref EADC_MODULE |\ref CLK_CLKSEL1_ADCSEL_PLL |\ref CLK_CLKDIV0_ADC(x) | + * |\ref EADC_MODULE |\ref CLK_CLKSEL1_ADCSEL_PCLK |\ref CLK_CLKDIV0_ADC(x) | + * |\ref EADC_MODULE |\ref CLK_CLKSEL1_ADCSEL_HIRC |\ref CLK_CLKDIV0_ADC(x) | * |\ref OPA_MODULE | x | x | - * |\ref TAMPER_MODULE | x | x | - * |\ref TAMPER_MODULE | x | x | * |\ref QEI1_MODULE | x | x | * |\ref QEI0_MODULE | x | x | * |\ref PWM1CH45_MODULE |\ref CLK_CLKSEL2_PWM1CH45SEL_HXT | x | @@ -352,9 +359,15 @@ void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv) * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_PLL |\ref CLK_CLKDIV1_SC0(x) | * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_PCLK |\ref CLK_CLKDIV1_SC0(x) | * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_HIRC |\ref CLK_CLKDIV1_SC0(x) | - * |\ref PS2_MODULE | x | x | - * |\ref I2S1_MODULE | x | x | - * |\ref I2S0_MODULE | x | x | + * |\ref PS2_MODULE |\ref CLK_CLKSEL3_I2S1SEL_HXT | x | + * |\ref I2S1_MODULE |\ref CLK_CLKSEL3_I2S1SEL_HXT | x | + * |\ref I2S1_MODULE |\ref CLK_CLKSEL3_I2S1SEL_PLL | x | + * |\ref I2S1_MODULE |\ref CLK_CLKSEL3_I2S1SEL_PCLK | x | + * |\ref I2S1_MODULE |\ref CLK_CLKSEL3_I2S1SEL_HIRC | x | + * |\ref I2S0_MODULE |\ref CLK_CLKSEL3_I2S0SEL_HXT | x | + * |\ref I2S0_MODULE |\ref CLK_CLKSEL3_I2S0SEL_PLL | x | + * |\ref I2S0_MODULE |\ref CLK_CLKSEL3_I2S0SEL_PCLK | x | + * |\ref I2S0_MODULE |\ref CLK_CLKSEL3_I2S0SEL_HIRC | x | * |\ref ADC_MODULE |\ref CLK_CLKSEL1_ADCSEL_HXT |\ref CLK_CLKDIV0_ADC(x) | * |\ref ADC_MODULE |\ref CLK_CLKSEL1_ADCSEL_PLL |\ref CLK_CLKDIV0_ADC(x) | * |\ref ADC_MODULE |\ref CLK_CLKSEL1_ADCSEL_PCLK |\ref CLK_CLKDIV0_ADC(x) | @@ -488,7 +501,6 @@ void CLK_DisableXtalRC(uint32_t u32ClkMask) * - \ref SDH_MODULE * - \ref CRC_MODULE * - \ref CAP_MODULE - * - \ref SENCLK_MODULE * - \ref USBD_MODULE * - \ref CRPT_MODULE * - \ref WDT_MODULE @@ -536,7 +548,6 @@ void CLK_DisableXtalRC(uint32_t u32ClkMask) * - \ref PWM1CH45_MODULE * - \ref QEI0_MODULE * - \ref QEI1_MODULE - * - \ref TAMPER_MODULE * - \ref ECAP0_MODULE * - \ref ECAP1_MODULE * - \ref EPWM0_MODULE @@ -547,7 +558,7 @@ void CLK_DisableXtalRC(uint32_t u32ClkMask) */ void CLK_EnableModuleClock(uint32_t u32ModuleIdx) { - *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK+(MODULE_AHPBCLK(u32ModuleIdx)*4)) |= 1<AHBCLK+(MODULE_APBCLK(u32ModuleIdx)*4)) |= 1<AHBCLK+(MODULE_AHPBCLK(u32ModuleIdx)*4)) &= ~(1<AHBCLK+(MODULE_APBCLK(u32ModuleIdx)*4)) &= ~(1<PLLCTL = (CLK->PLLCTL & ~CLK_PLLCTL_PD_Msk) | (CLK_PLLCTL_PLLSRC_HIRC); - u32Register = 1<PLLCTL = (CLK->PLLCTL & ~CLK_PLLCTL_PD_Msk); - u32Register = 0<PWRCTL |= CLK_PWRCTL_HXTEN_Msk; + + /* Wait for HXT clock ready */ + CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk); + + /* Select PLL source clock from HXT */ + u32CLK_SRC = CLK_PLLCTL_PLLSRC_HXT; + u32PllSrcClk = __HXT; + + /* u32NR start from 2 */ + u32NR = 2; } - if(u32PllFreqPWRCTL |= CLK_PWRCTL_HIRCEN_Msk; + + /* Wait for HIRC clock ready */ + CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk); + + /* Select PLL source clock from HIRC */ + u32CLK_SRC = CLK_PLLCTL_PLLSRC_HIRC; + u32PllSrcClk = __HIRC; + + /* u32NR start from 4 when FIN = 22.1184MHz to avoid calculation overflow */ + u32NR = 4; + } + + /* Select "NO" according to request frequency */ + if((u32PllFreq <= FREQ_500MHZ) && (u32PllFreq > FREQ_250MHZ)) { + u32NO = 0; + } else if((u32PllFreq <= FREQ_250MHZ) && (u32PllFreq > FREQ_125MHZ)) { + u32NO = 1; + u32PllFreq = u32PllFreq << 1; + } else if((u32PllFreq <= FREQ_125MHZ) && (u32PllFreq >= FREQ_50MHZ)) { + u32NO = 3; + u32PllFreq = u32PllFreq << 2; } else { - u32PllFreq <<=1; - u32Register |= (0x1<(0xF+2) || u32NF>(0xFF+2) ) { - u32NR = u32NR>>1; - u32NF = u32NF>>1; + + /* Find best solution */ + u32Min = (uint32_t) - 1; + u32MinNR = 0; + u32MinNF = 0; + for(; u32NR <= 33; u32NR++) { + u32Tmp = u32PllSrcClk / u32NR; + if((u32Tmp > 1600000) && (u32Tmp < 16000000)) { + for(u32NF = 2; u32NF <= 513; u32NF++) { + u32Tmp2 = u32Tmp * u32NF; + if((u32Tmp2 >= 200000000) && (u32Tmp2 <= 500000000)) { + u32Tmp3 = (u32Tmp2 > u32PllFreq) ? u32Tmp2 - u32PllFreq : u32PllFreq - u32Tmp2; + if(u32Tmp3 < u32Min) { + u32Min = u32Tmp3; + u32MinNR = u32NR; + u32MinNF = u32NF; + + /* Break when get good results */ + if(u32Min == 0) + break; + } + } + } + } } - CLK->PLLCTL = u32Register | ((u32NR - 2)<<9) | (u32NF - 2) ; + + /* Enable and apply new PLL setting. */ + CLK->PLLCTL = u32CLK_SRC | (u32NO << 14) | ((u32MinNR - 2) << 9) | (u32MinNF - 2); + + /* Wait for PLL clock stable */ + CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk); + + /* Return actual PLL output clock frequency */ + return u32PllSrcClk / ((u32NO + 1) * u32MinNR) * u32MinNF; + +lexit: + + /* Apply default PLL setting and return */ + if(u32PllClkSrc == CLK_PLLCTL_PLLSRC_HXT) + CLK->PLLCTL = CLK_PLLCTL_84MHz_HXT; /* 84MHz */ + else + CLK->PLLCTL = CLK_PLLCTL_50MHz_HIRC; /* 50MHz */ + + /* Wait for PLL clock stable */ CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk); return CLK_GetPLLClockFreq(); @@ -670,7 +748,7 @@ uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq) */ void CLK_DisablePLL(void) { - CLK->PLLCTL &= ~CLK_PLLCTL_PD_Msk; + CLK->PLLCTL |= CLK_PLLCTL_PD_Msk; } /** @@ -703,6 +781,7 @@ void CLK_SysTickDelay(uint32_t us) /* Waiting for down-count to zero */ while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0); + SysTick->CTRL = 0 ; } /** @@ -718,21 +797,66 @@ void CLK_SysTickDelay(uint32_t us) * @return 0 clock is not stable * 1 clock is stable * - * @details To wait for clock ready by specified CLKSTATUS bit or timeout (~5ms) + * @details To wait for clock ready by specified CLKSTATUS bit or timeout (~300ms) */ uint32_t CLK_WaitClockReady(uint32_t u32ClkMask) { - int32_t i32TimeOutCnt; - - i32TimeOutCnt = __HSI / 200; /* About 5ms */ + int32_t i32TimeOutCnt = 2160000; while((CLK->STATUS & u32ClkMask) != u32ClkMask) { if(i32TimeOutCnt-- <= 0) return 0; } + return 1; } +/** + * @brief Enable System Tick counter + * @param[in] u32ClkSrc is System Tick clock source. Including: + * - \ref CLK_CLKSEL0_STCLKSEL_HXT + * - \ref CLK_CLKSEL0_STCLKSEL_LXT + * - \ref CLK_CLKSEL0_STCLKSEL_HXT_DIV2 + * - \ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV2 + * - \ref CLK_CLKSEL0_STCLKSEL_HIRC_DIV2 + * - \ref CLK_CLKSEL0_STCLKSEL_HCLK + * @param[in] u32Count is System Tick reload value. It could be 0~0xFFFFFF. + * @return None + * @details This function set System Tick clock source, reload value, enable System Tick counter and interrupt. \n + * The register write-protection function should be disabled before using this function. + */ +void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count) +{ + /* Set System Tick counter disabled */ + SysTick->CTRL = 0; + + /* Set System Tick clock source */ + if( u32ClkSrc == CLK_CLKSEL0_STCLKSEL_HCLK ) + SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk; + else + CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc; + + /* Set System Tick reload value */ + SysTick->LOAD = u32Count; + + /* Clear System Tick current value and counter flag */ + SysTick->VAL = 0; + + /* Set System Tick interrupt enabled and counter enabled */ + SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; +} + +/** + * @brief Disable System Tick counter + * @param None + * @return None + * @details This function disable System Tick counter. + */ +void CLK_DisableSysTick(void) +{ + /* Set System Tick counter disabled */ + SysTick->CTRL = 0; +} /*@}*/ /* end of group NUC472_442_CLK_EXPORTED_FUNCTIONS */ diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_clk.h b/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_clk.h index 23ccf398226..bdb19ded092 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_clk.h +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_clk.h @@ -2,7 +2,7 @@ * @file CLK.h * @version V1.0 * $Revision 1 $ - * $Date: 14/10/06 1:50p $ + * $Date: 15/11/19 10:06a $ * @brief NUC472/NUC442 CLK Header File * * @note @@ -30,11 +30,18 @@ extern "C" @{ */ -#define FREQ_50MHZ 50000000 -#define FREQ_24MHZ 24000000 -#define FREQ_22MHZ 22000000 -#define FREQ_32KHZ 32767 -#define FREQ_10KHZ 10000 +#define FREQ_500MHZ 500000000 +#define FREQ_250MHZ 250000000 +#define FREQ_200MHZ 200000000 +#define FREQ_125MHZ 125000000 +#define FREQ_72MHZ 72000000 +#define FREQ_50MHZ 50000000 +#define FREQ_25MHZ 25000000 +#define FREQ_24MHZ 24000000 +#define FREQ_22MHZ 22000000 +#define FREQ_32KHZ 32000 +#define FREQ_10KHZ 10000 + /*---------------------------------------------------------------------------------------------------------*/ /* PLLCTL constant definitions. PLL = FIN * NF / NR / NO */ /*---------------------------------------------------------------------------------------------------------*/ @@ -69,9 +76,7 @@ extern "C" /*---------------------------------------------------------------------------------------------------------*/ /* PLL2CTL constant definitions. */ /*---------------------------------------------------------------------------------------------------------*/ -#define CLK_PLL2CTL_USPLL(x) (((x)-1) << CLK_PLL2CTL_PLL2DIV_Pos) /*!< USBPLL clock frequency = (480 MHz) / 2 / (USB_N + 1). It could be 1~256, Max. PLL frequency :480MHz / 2 when XTL12M. \hideinitializer */ -#define CLK_PLL2CTL_USBPLL_DIS (0x00UL<>30) & 0x3) /*!< Calculate AHBCLK/APBCLK offset on MODULE index \hideinitializer */ +#define MODULE_APBCLK(x) ((x >>30) & 0x3) /*!< Calculate AHBCLK/APBCLK offset on MODULE index \hideinitializer */ #define MODULE_CLKSEL(x) ((x >>28) & 0x3) /*!< Calculate CLKSEL offset on MODULE index \hideinitializer */ #define MODULE_CLKSEL_Msk(x) ((x >>25) & 0x7) /*!< Calculate CLKSEL mask offset on MODULE index \hideinitializer */ #define MODULE_CLKSEL_Pos(x) ((x >>20) & 0x1f) /*!< Calculate CLKSEL position offset on MODULE index \hideinitializer */ @@ -297,6 +312,16 @@ extern "C" #define MODULE_CLKDIV_Pos(x) ((x >>5 ) & 0x1f) /*!< Calculate CLKDIV position offset on MODULE index \hideinitializer */ #define MODULE_IP_EN_Pos(x) ((x >>0 ) & 0x1f) /*!< Calculate APBCLK offset on MODULE index \hideinitializer */ #define MODULE_NoMsk 0x0 /*!< Not mask on MODULE index \hideinitializer */ +#define NA MODULE_NoMsk /*!< Not Available \hideinitializer */ + +#define MODULE_APBCLK_ENC(x) (((x) & 0x03) << 30) /*!< MODULE index, 0x0:AHBCLK, 0x1:APBCLK0, 0x2:APBCLK1 */ +#define MODULE_CLKSEL_ENC(x) (((x) & 0x03) << 28) /*!< CLKSEL offset on MODULE index, 0x0:CLKSEL0, 0x1:CLKSEL1, 0x2:CLKSEL2, 0x3:CLKSEL3 */ +#define MODULE_CLKSEL_Msk_ENC(x) (((x) & 0x07) << 25) /*!< CLKSEL mask offset on MODULE index */ +#define MODULE_CLKSEL_Pos_ENC(x) (((x) & 0x1f) << 20) /*!< CLKSEL position offset on MODULE index */ +#define MODULE_CLKDIV_ENC(x) (((x) & 0x03) << 18) /*!< APBCLK CLKDIV on MODULE index, 0x0:CLKDIV, 0x1:CLKDIV1 */ +#define MODULE_CLKDIV_Msk_ENC(x) (((x) & 0xff) << 10) /*!< CLKDIV mask offset on MODULE index */ +#define MODULE_CLKDIV_Pos_ENC(x) (((x) & 0x1f) << 5) /*!< CLKDIV position offset on MODULE index */ +#define MODULE_IP_EN_Pos_ENC(x) (((x) & 0x1f) << 0) /*!< AHBCLK/APBCLK offset on MODULE index */ /*--------------------------------------------------------------------------------------------------------------------------------------*/ /* AHBCLK/APBCLK(2) | CLKSEL(2) | CLKSEL_Msk(3) | CLKSEL_Pos(5) | CLKDIV(2) | CLKDIV_Msk(8) | CLKDIV_Pos(5) | IP_EN_Pos(5)*/ /*--------------------------------------------------------------------------------------------------------------------------------------*/ @@ -304,15 +329,15 @@ extern "C" #define ISP_MODULE ((0UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_AHBCLK_ISPCKEN_Pos) /*!< ISP Module \hideinitializer */ #define EBI_MODULE ((0UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_AHBCLK_EBICKEN_Pos) /*!< EBI Module \hideinitializer */ #define USBH_MODULE ((0UL<<30)|(0<<28)|(1<<25) |( 8<<20)|(0<<18)|(0xF<<10) |( 4<<5)|CLK_AHBCLK_USBHCKEN_Pos) /*!< USBH Module \hideinitializer */ -#define EMAC_MODULE ((0UL<<30)|(0<<28)|(1<<25) |(10<<20)|(3<<18)|(0xFF<<10) |(16<<5)|CLK_AHBCLK_EMACCKEN_Pos) /*!< EMAC Module \hideinitializer */ +#define EMAC_MODULE ((0UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|(10<<20)|(3<<18)|(0xFF<<10) |(16<<5)|CLK_AHBCLK_EMACCKEN_Pos) /*!< EMAC Module \hideinitializer */ #define SDH_MODULE ((0UL<<30)|(0<<28)|(3<<25) |(20<<20)|(0<<18)|(0xFF<<10) |(24<<5)|CLK_AHBCLK_SDHCKEN_Pos) /*!< SDH Module \hideinitializer */ #define CRC_MODULE ((0UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_AHBCLK_CRCCKEN_Pos) /*!< CRC Module \hideinitializer */ -#define CAP_MODULE ((0UL<<30)|(0<<28)|(3<<25) |(16<<20)|(3<<18)|(0xFF<<10) |( 0<<5)|CLK_AHBCLK_ICAPCKEN_Pos) /*!< CAP Module \hideinitializer */ -#define SENCLK_MODULE ((0UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(3<<18)|(0xFF<<10) |( 8<<5)|CLK_AHBCLK_SENCLKCKEN_Pos) /*!< Sensor Clock Module \hideinitializer */ +#define CAP_MODULE ((0UL<<30)|(0<<28)|(3<<25) |(16<<20)|(3<<18)|(0xFF<<10) |( 0<<5)|CLK_AHBCLK_CAPCKEN_Pos) /*!< CAP Module \hideinitializer */ +#define SEN_MODULE ((0UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(3<<18)|(0xFF<<10) |( 8<<5)|CLK_AHBCLK_SENCKEN_Pos) /*!< Sensor Clock Module \hideinitializer */ #define USBD_MODULE ((0UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_AHBCLK_USBDCKEN_Pos) /*!< USBD Module \hideinitializer */ #define CRPT_MODULE ((0UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_AHBCLK_CRPTCKEN_Pos) /*!< CRYPTO Module \hideinitializer */ -#define WDT_MODULE ((1UL<<30)|(3<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK0_WDTCKEN_Pos) /*!< Watchdog Timer Module \hideinitializer */ +#define WDT_MODULE ((1UL<<30)|(1<<28)|(3<<25) |( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK0_WDTCKEN_Pos) /*!< Watchdog Timer Module \hideinitializer */ #define WWDT_MODULE ((1UL<<30)|(1<<28)|(3<<25) |(30<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK0_WDTCKEN_Pos) /*!< Window Watchdog Timer Module \hideinitializer */ #define RTC_MODULE ((1UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK0_RTCCKEN_Pos) /*!< RTC Module \hideinitializer */ #define TMR0_MODULE ((1UL<<30)|(1<<28)|(7<<25) |( 8<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK0_TMR0CKEN_Pos) /*!< Timer0 Module \hideinitializer */ @@ -358,13 +383,12 @@ extern "C" #define PWM1CH45_MODULE ((2UL<<30)|(2<<28)|(7<<25) |(20<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK1_PWM1CH45CKEN_Pos) /*!< PWM1CH45 Module \hideinitializer */ #define QEI0_MODULE ((2UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK1_QEI0CKEN_Pos) /*!< QEI0 Module \hideinitializer */ #define QEI1_MODULE ((2UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK1_QEI1CKEN_Pos) /*!< QEI1 Module \hideinitializer */ -#define TAMPER_MODULE ((2UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK1_TAMPERCKEN_Pos) /*!< TAMPER Module \hideinitializer */ #define ECAP0_MODULE ((2UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK1_ECAP0CKEN_Pos) /*!< ECAP0 Module \hideinitializer */ #define ECAP1_MODULE ((2UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK1_ECAP1CKEN_Pos) /*!< ECAP1 Module \hideinitializer */ #define EPWM0_MODULE ((2UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK1_EPWM0CKEN_Pos) /*!< EPWM0 Module \hideinitializer */ #define EPWM1_MODULE ((2UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK1_EPWM1CKEN_Pos) /*!< EPWM1 Module \hideinitializer */ #define OPA_MODULE ((2UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK1_OPACKEN_Pos) /*!< OPA Module \hideinitializer */ -#define EADC_MODULE ((2UL<<30)|(0<<28)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK1_EADCCKEN_Pos) /*!< EADC Module \hideinitializer */ +#define EADC_MODULE ((2UL<<30)|(1<<28)|(3<<25) |( 2<<20)|(0<<18)|(0xFF<<10) |(16<<5)|CLK_APBCLK1_EADCCKEN_Pos) /*!< EADC Module \hideinitializer */ /*@}*/ /* end of group NUC472_442_CLK_EXPORTED_CONSTANTS */ @@ -395,6 +419,8 @@ uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq); void CLK_DisablePLL(void); void CLK_SysTickDelay(uint32_t us); uint32_t CLK_WaitClockReady(uint32_t u32ClkMask); +void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count); +void CLK_DisableSysTick(void); /*@}*/ /* end of group NUC472_442_CLK_EXPORTED_FUNCTIONS */ From bb1617c5f892f13bbd52b32f3b993eb97975a7be Mon Sep 17 00:00:00 2001 From: ccli8 Date: Fri, 18 Nov 2016 14:07:47 +0800 Subject: [PATCH 05/12] [M453] Fix EADC module is initialized multiple times Also fix EADC module name EADC is hardcoded. --- .../TARGET_NUVOTON/TARGET_M451/analogin_api.c | 94 ++++--------------- 1 file changed, 20 insertions(+), 74 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/analogin_api.c b/targets/TARGET_NUVOTON/TARGET_M451/analogin_api.c index 630de602cf2..1435e409898 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/analogin_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/analogin_api.c @@ -23,76 +23,25 @@ #include "PeripheralPins.h" #include "nu_modutil.h" -struct nu_adc_var { - uint32_t en_msk; -}; - -static struct nu_adc_var adc0_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc1_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc2_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc3_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc4_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc5_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc6_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc7_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc8_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc9_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc10_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc11_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc12_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc13_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc14_var = { - .en_msk = 0 -}; -static struct nu_adc_var adc15_var = { - .en_msk = 0 -}; +static uint32_t eadc_modinit_mask = 0; static const struct nu_modinit_s adc_modinit_tab[] = { - {ADC_0_0, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc0_var}, - {ADC_0_1, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc1_var}, - {ADC_0_2, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc2_var}, - {ADC_0_3, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc3_var}, - {ADC_0_4, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc4_var}, - {ADC_0_5, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc5_var}, - {ADC_0_6, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc6_var}, - {ADC_0_7, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc7_var}, - {ADC_0_8, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc8_var}, - {ADC_0_9, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc9_var}, - {ADC_0_10, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc10_var}, - {ADC_0_11, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc11_var}, - {ADC_0_12, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc12_var}, - {ADC_0_13, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc13_var}, - {ADC_0_14, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc14_var}, - {ADC_0_15, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, &adc15_var}, + {ADC_0_0, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_1, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_2, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_3, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_4, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_5, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_6, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_7, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_8, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_9, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_10, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_11, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_12, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_13, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_14, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, + {ADC_0_15, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC00_IRQn, NULL}, }; void analogin_init(analogin_t *obj, PinName pin) @@ -107,7 +56,7 @@ void analogin_init(analogin_t *obj, PinName pin) EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc); // NOTE: All channels (identified by ADCName) share a ADC module. This reset will also affect other channels of the same ADC module. - if (! ((struct nu_adc_var *) modinit->var)->en_msk) { + if (! eadc_modinit_mask) { // Reset this module if no channel enabled SYS_ResetModule(modinit->rsetidx); @@ -116,9 +65,6 @@ void analogin_init(analogin_t *obj, PinName pin) // Enable clock of paired channels CLK_EnableModuleClock(modinit->clkidx); - // Power on ADC - //ADC_POWER_ON(ADC); - // Set the ADC internal sampling time, input mode as single-end and enable the A/D converter EADC_Open(eadc_base, EADC_CTL_DIFFEN_SINGLE_END); EADC_SetInternalSampleTime(eadc_base, 6); @@ -130,9 +76,9 @@ void analogin_init(analogin_t *obj, PinName pin) pinmap_pinout(pin, PinMap_ADC); // Configure the sample module Nmod for analog input channel Nch and software trigger source - EADC_ConfigSampleModule(EADC, chn, EADC_SOFTWARE_TRIGGER, chn); + EADC_ConfigSampleModule(eadc_base, chn, EADC_SOFTWARE_TRIGGER, chn); - ((struct nu_adc_var *) modinit->var)->en_msk |= 1 << chn; + eadc_modinit_mask |= 1 << chn; } uint16_t analogin_read_u16(analogin_t *obj) From e1acb06d0568972666e4bc6cb0d0a627930030d8 Mon Sep 17 00:00:00 2001 From: ccli8 Date: Fri, 18 Nov 2016 14:16:12 +0800 Subject: [PATCH 06/12] [NUC472] Rename variable name in analog-in --- targets/TARGET_NUVOTON/TARGET_NUC472/analogin_api.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/analogin_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/analogin_api.c index 4ea8bd4c409..a3039cb1509 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/analogin_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/analogin_api.c @@ -23,7 +23,7 @@ #include "PeripheralPins.h" #include "nu_modutil.h" -static uint32_t adc_modinit_mask = 0; +static uint32_t eadc_modinit_mask = 0; static const struct nu_modinit_s adc_modinit_tab[] = { {ADC_0_0, EADC_MODULE, CLK_CLKSEL1_ADCSEL_PLL, CLK_CLKDIV0_ADC(5), ADC_RST, EADC0_IRQn, NULL}, @@ -57,7 +57,7 @@ void analogin_init(analogin_t *obj, PinName pin) EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc); // NOTE: All channels (identified by ADCName) share a ADC module. This reset will also affect other channels of the same ADC module. - if (! adc_modinit_mask) { + if (! eadc_modinit_mask) { // Reset this module if no channel enabled SYS_ResetModule(modinit->rsetidx); @@ -78,7 +78,7 @@ void analogin_init(analogin_t *obj, PinName pin) // Configure the sample module Nmod for analog input channel Nch and software trigger source EADC_ConfigSampleModule(eadc_base, chn, EADC_SOFTWARE_TRIGGER, chn % 8); - adc_modinit_mask |= 1 << chn; + eadc_modinit_mask |= 1 << chn; } uint16_t analogin_read_u16(analogin_t *obj) From 6c1fca60a54fa8c7cdf63e7c62f52e2fec3f0504 Mon Sep 17 00:00:00 2001 From: ccli8 Date: Fri, 18 Nov 2016 14:26:52 +0800 Subject: [PATCH 07/12] [M453] Remove SPI MOSI1 and MISO1 pins from pinmap These pins are for SPI 2-bit mode (not dual mode) and cannot be for SPI standard use. --- .../TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.c b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.c index 1992ecf8762..e236cffb112 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.c @@ -297,14 +297,12 @@ const PinMap PinMap_UART_CTS[] = { const PinMap PinMap_SPI_MOSI[] = { {PA_5, SPI_1, SYS_GPA_MFPL_PA5MFP_SPI1_MOSI}, - {PB_0, SPI_0, SYS_GPB_MFPL_PB0MFP_SPI0_MOSI1}, {PB_5, SPI_0, SYS_GPB_MFPL_PB5MFP_SPI0_MOSI0}, {PB_5, SPI_1, SYS_GPB_MFPL_PB5MFP_SPI1_MOSI}, {PC_3, SPI_2, SYS_GPC_MFPL_PC3MFP_SPI2_MOSI}, {PC_10, SPI_2, SYS_GPC_MFPH_PC10MFP_SPI2_MOSI}, {PD_13, SPI_2, SYS_GPD_MFPH_PD13MFP_SPI2_MOSI}, {PE_3, SPI_1, SYS_GPE_MFPL_PE3MFP_SPI1_MOSI}, - {PE_9, SPI_0, SYS_GPE_MFPH_PE9MFP_SPI0_MOSI1}, {PE_11, SPI_1, SYS_GPE_MFPH_PE11MFP_SPI1_MOSI}, {PE_11, SPI_0, SYS_GPE_MFPH_PE11MFP_SPI0_MOSI0}, @@ -313,7 +311,6 @@ const PinMap PinMap_SPI_MOSI[] = { const PinMap PinMap_SPI_MISO[] = { {PA_6, SPI_1, SYS_GPA_MFPL_PA6MFP_SPI1_MISO}, - {PB_1, SPI_0, SYS_GPB_MFPL_PB1MFP_SPI0_MISO1}, {PB_3, SPI_0, SYS_GPB_MFPL_PB3MFP_SPI0_MISO0}, {PB_3, SPI_1, SYS_GPB_MFPL_PB3MFP_SPI1_MISO}, {PB_6, SPI_0, SYS_GPB_MFPL_PB6MFP_SPI0_MISO0}, @@ -322,7 +319,6 @@ const PinMap PinMap_SPI_MISO[] = { {PC_11, SPI_2, SYS_GPC_MFPH_PC11MFP_SPI2_MISO}, {PD_5, SPI_1, SYS_GPD_MFPL_PD5MFP_SPI1_MISO}, {PD_14, SPI_2, SYS_GPD_MFPH_PD14MFP_SPI2_MISO}, - {PE_8, SPI_0, SYS_GPE_MFPH_PE8MFP_SPI0_MISO1}, {PE_10, SPI_1, SYS_GPE_MFPH_PE10MFP_SPI1_MISO}, {PE_10, SPI_0, SYS_GPE_MFPH_PE10MFP_SPI0_MISO0}, From f4890f68f107b071ce6b47ed8bb2f8829a2a304b Mon Sep 17 00:00:00 2001 From: ccli8 Date: Fri, 18 Nov 2016 14:33:33 +0800 Subject: [PATCH 08/12] [NUC472] Remove SPI MOSI1 and MISO1 pins from pinmap These pins are for SPI 2-bit mode (not dual mode) and cannot be for SPI standard use. --- .../TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c index b1ad6b92a4f..b7813987f3a 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c @@ -371,25 +371,16 @@ const PinMap PinMap_UART_CTS[] = { const PinMap PinMap_SPI_MOSI[] = { {PA_10, SPI_3, SYS_GPA_MFPH_PA10MFP_SPI3_MOSI0}, - {PA_12, SPI_3, SYS_GPA_MFPH_PA12MFP_SPI3_MOSI1}, {PB_5, SPI_2, SYS_GPB_MFPL_PB5MFP_SPI2_MOSI0}, - {PB_13, SPI_2, SYS_GPB_MFPH_PB13MFP_SPI2_MOSI1}, - {PC_4, SPI_0, SYS_GPC_MFPL_PC4MFP_SPI0_MOSI1}, {PC_7, SPI_0, SYS_GPC_MFPL_PC7MFP_SPI0_MOSI0}, - {PC_13, SPI_1, SYS_GPC_MFPH_PC13MFP_SPI1_MOSI1}, {PC_15, SPI_1, SYS_GPC_MFPH_PC15MFP_SPI1_MOSI0}, - {PD_9, SPI_3, SYS_GPD_MFPH_PD9MFP_SPI3_MOSI1}, {PE_3, SPI_0, SYS_GPE_MFPL_PE3MFP_SPI0_MOSI0}, {PE_7, SPI_0, SYS_GPE_MFPL_PE7MFP_SPI0_MOSI0}, - {PE_11, SPI_0, SYS_GPE_MFPH_PE11MFP_SPI0_MOSI1}, {PF_0, SPI_1, SYS_GPF_MFPL_PF0MFP_SPI1_MOSI0}, - {PF_1, SPI_2, SYS_GPF_MFPL_PF1MFP_SPI2_MOSI1}, {PF_5, SPI_3, SYS_GPF_MFPL_PF5MFP_SPI3_MOSI0}, {PG_8, SPI_2, SYS_GPG_MFPH_PG8MFP_SPI2_MOSI0}, {PH_8, SPI_2, SYS_GPH_MFPH_PH8MFP_SPI2_MOSI0}, - {PH_10, SPI_2, SYS_GPH_MFPH_PH10MFP_SPI2_MOSI1}, {PI_6, SPI_3, SYS_GPI_MFPL_PI6MFP_SPI3_MOSI0}, - {PI_8, SPI_3, SYS_GPI_MFPH_PI8MFP_SPI3_MOSI1}, {NC, NC, 0} }; @@ -397,25 +388,16 @@ const PinMap PinMap_SPI_MOSI[] = { const PinMap PinMap_SPI_MISO[] = { {PA_2, SPI_3, SYS_GPA_MFPL_PA2MFP_SPI3_MISO0}, {PA_9, SPI_3, SYS_GPA_MFPH_PA9MFP_SPI3_MISO0}, - {PA_11, SPI_3, SYS_GPA_MFPH_PA11MFP_SPI3_MISO1}, {PB_4, SPI_2, SYS_GPB_MFPL_PB4MFP_SPI2_MISO0}, - {PB_12, SPI_2, SYS_GPB_MFPH_PB12MFP_SPI2_MISO1}, - {PC_3, SPI_0, SYS_GPC_MFPL_PC3MFP_SPI0_MISO1}, {PC_6, SPI_0, SYS_GPC_MFPL_PC6MFP_SPI0_MISO0}, - {PC_14, SPI_1, SYS_GPC_MFPH_PC14MFP_SPI1_MISO1}, {PD_0, SPI_1, SYS_GPD_MFPL_PD0MFP_SPI1_MISO0}, - {PD_8, SPI_3, SYS_GPD_MFPH_PD8MFP_SPI3_MISO1}, {PD_15, SPI_1, SYS_GPD_MFPH_PD15MFP_SPI1_MISO0}, {PE_2, SPI_0, SYS_GPE_MFPL_PE2MFP_SPI0_MISO0}, {PE_6, SPI_0, SYS_GPE_MFPL_PE6MFP_SPI0_MISO0}, - {PE_10, SPI_0, SYS_GPE_MFPH_PE10MFP_SPI0_MISO1}, {PF_4, SPI_3, SYS_GPF_MFPL_PF4MFP_SPI3_MISO0}, {PG_7, SPI_2, SYS_GPG_MFPL_PG7MFP_SPI2_MISO0}, {PH_7, SPI_2, SYS_GPH_MFPL_PH7MFP_SPI2_MISO0}, - {PH_9, SPI_2, SYS_GPH_MFPH_PH9MFP_SPI2_MISO1}, {PI_5, SPI_3, SYS_GPI_MFPL_PI5MFP_SPI3_MISO0}, - {PI_7, SPI_3, SYS_GPI_MFPL_PI7MFP_SPI3_MISO1}, - {PI_12, SPI_2, SYS_GPI_MFPH_PI12MFP_SPI2_MISO1}, {NC, NC, 0} }; From 57a22cd4abe1e6b078eed481569bbad1b0f42e2b Mon Sep 17 00:00:00 2001 From: ccli8 Date: Mon, 21 Nov 2016 17:05:57 +0800 Subject: [PATCH 09/12] [NUC472/M453] Fix CI I2C EEPROM failed --- targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c | 34 ++++++++++++------- .../TARGET_NUVOTON/TARGET_NUC472/i2c_api.c | 34 +++++++++++-------- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c b/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c index bf1ee28ef63..4912d569796 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c @@ -48,6 +48,7 @@ static void i2c0_vec(void); static void i2c1_vec(void); static void i2c_irq(i2c_t *obj); static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl); +static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv); static struct nu_i2c_var i2c0_var = { .obj = NULL, @@ -615,32 +616,30 @@ static void i2c_irq(i2c_t *obj) I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk); } else { - if (status == 0x18) { - obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED; - i2c_disable_int(obj); - break; - } - // Go Master Repeat Start - i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk); + i2c_fsm_tranfini(obj, 0); } } else { i2c_disable_int(obj); } break; + case 0x30: // Master Transmit Data NACK + i2c_fsm_tranfini(obj, 0); + break; + case 0x20: // Master Transmit Address NACK - // Go Master Repeat Start - i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk); + i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed break; + case 0x38: // Master Arbitration Lost i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk); break; case 0x48: // Master Receive Address NACK - // Go Master Repeat Start - i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk); + i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed break; + case 0x40: // Master Receive Address ACK case 0x50: // Master Receive Data ACK case 0x58: // Master Receive Data NACK @@ -657,8 +656,7 @@ static void i2c_irq(i2c_t *obj) while (1); } #endif - // Go Master Repeat Start - i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk); + i2c_fsm_tranfini(obj, 0); } else { uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk; @@ -825,6 +823,16 @@ static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl) obj->i2c.slaveaddr_state = NoData; } +static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv) +{ + if (obj->i2c.tran_pos) { + obj->i2c.tran_pos += tran_pos_adv; + } + + obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED; + i2c_disable_int(obj); +} + #if DEVICE_I2C_ASYNCH void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint) diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c index 73fd4f646ee..6547eb475c9 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c @@ -51,6 +51,7 @@ static void i2c3_vec(void); static void i2c4_vec(void); static void i2c_irq(i2c_t *obj); static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl); +static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv); static struct nu_i2c_var i2c0_var = { .obj = NULL, @@ -645,33 +646,30 @@ static void i2c_irq(i2c_t *obj) I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk); } else { - if (status == 0x18) { - obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED; - i2c_disable_int(obj); - break; - } - // Go Master Repeat Start - i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk); + i2c_fsm_tranfini(obj, 0); } } else { i2c_disable_int(obj); } break; + case 0x30: // Master Transmit Data NACK + i2c_fsm_tranfini(obj, 0); + break; + case 0x20: // Master Transmit Address NACK - // Go Master Repeat Start - i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk); + i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed break; + case 0x38: // Master Arbitration Lost i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk); break; case 0x48: // Master Receive Address NACK - // Go Master Stop. - // Go Master Repeat Start - i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk); + i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed break; + case 0x40: // Master Receive Address ACK case 0x50: // Master Receive Data ACK case 0x58: // Master Receive Data NACK @@ -688,8 +686,7 @@ static void i2c_irq(i2c_t *obj) while (1); } #endif - // Go Master Repeat Start - i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk); + i2c_fsm_tranfini(obj, 0); } else { uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk; @@ -856,6 +853,15 @@ static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl) obj->i2c.slaveaddr_state = NoData; } +static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv) +{ + if (obj->i2c.tran_pos) { + obj->i2c.tran_pos += tran_pos_adv; + } + + obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED; + i2c_disable_int(obj); +} #if DEVICE_I2C_ASYNCH From d24c71fad9990044a8b1a6a55469fbfbb4bf43af Mon Sep 17 00:00:00 2001 From: ccli8 Date: Tue, 22 Nov 2016 13:45:01 +0800 Subject: [PATCH 10/12] [NUC472/M453] Correct return of i2c_byte_write() on NAK --- targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c | 50 ++++++++----------- .../TARGET_NUVOTON/TARGET_NUC472/i2c_api.c | 50 ++++++++----------- 2 files changed, 44 insertions(+), 56 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c b/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c index 4912d569796..cb0a475117e 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c @@ -48,7 +48,7 @@ static void i2c0_vec(void); static void i2c1_vec(void); static void i2c_irq(i2c_t *obj); static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl); -static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv); +static void i2c_fsm_tranfini(i2c_t *obj, int lastdatanaked); static struct nu_i2c_var i2c0_var = { .obj = NULL, @@ -69,8 +69,6 @@ static const struct nu_modinit_s i2c_modinit_tab[] = { }; static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastdata); -static int i2c_do_write(i2c_t *obj, char data, int naklastdata); -static int i2c_do_read(i2c_t *obj, char *data, int naklastdata); static int i2c_do_trsn(i2c_t *obj, uint32_t i2c_ctl, int sync); #define NU_I2C_TIMEOUT_STAT_INT 500000 #define NU_I2C_TIMEOUT_STOP 500000 @@ -98,6 +96,7 @@ static void i2c_rollback_vector_interrupt(i2c_t *obj); #define TRANCTRL_STARTED (1) #define TRANCTRL_NAKLASTDATA (1 << 1) +#define TRANCTRL_LASTDATANAKED (1 << 2) uint32_t us_ticker_read(void); @@ -169,7 +168,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) return I2C_ERROR_BUS_BUSY; } - if (i2c_do_write(obj, i2c_addr2data(address, 1), 0)) { + if (i2c_byte_write(obj, i2c_addr2data(address, 1)) != 1) { i2c_stop(obj); return I2C_ERROR_NO_SLAVE; } @@ -192,7 +191,7 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) return I2C_ERROR_BUS_BUSY; } - if (i2c_do_write(obj, i2c_addr2data(address, 0), 0)) { + if (i2c_byte_write(obj, i2c_addr2data(address, 0)) != 1) { i2c_stop(obj); return I2C_ERROR_NO_SLAVE; } @@ -215,14 +214,22 @@ void i2c_reset(i2c_t *obj) int i2c_byte_read(i2c_t *obj, int last) { char data = 0; - - i2c_do_read(obj, &data, last); + i2c_do_tran(obj, &data, 1, 1, last); return data; } int i2c_byte_write(i2c_t *obj, int data) { - return i2c_do_write(obj, (data & 0xFF), 0) == 0 ? 1 : 0; + char data_[1]; + data_[0] = data & 0xFF; + + if (i2c_do_tran(obj, data_, 1, 0, 0) == 1 && + ! (obj->i2c.tran_ctrl & TRANCTRL_LASTDATANAKED)) { + return 1; + } + else { + return 0; + } } #if DEVICE_I2CSLAVE @@ -374,7 +381,6 @@ static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastd } else { i2c_disable_int(obj); - obj->i2c.tran_ctrl = 0; tran_len = obj->i2c.tran_pos - obj->i2c.tran_beg; obj->i2c.tran_beg = NULL; obj->i2c.tran_pos = NULL; @@ -385,18 +391,6 @@ static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastd return tran_len; } -static int i2c_do_write(i2c_t *obj, char data, int naklastdata) -{ - char data_[1]; - data_[0] = data; - return i2c_do_tran(obj, data_, 1, 0, naklastdata) == 1 ? 0 : I2C_ERROR_BUS_BUSY; -} - -static int i2c_do_read(i2c_t *obj, char *data, int naklastdata) -{ - return i2c_do_tran(obj, data, 1, 1, naklastdata) == 1 ? 0 : I2C_ERROR_BUS_BUSY; -} - static int i2c_do_trsn(i2c_t *obj, uint32_t i2c_ctl, int sync) { I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c); @@ -625,11 +619,11 @@ static void i2c_irq(i2c_t *obj) break; case 0x30: // Master Transmit Data NACK - i2c_fsm_tranfini(obj, 0); + i2c_fsm_tranfini(obj, 1); break; case 0x20: // Master Transmit Address NACK - i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed + i2c_fsm_tranfini(obj, 1); break; case 0x38: // Master Arbitration Lost @@ -637,7 +631,7 @@ static void i2c_irq(i2c_t *obj) break; case 0x48: // Master Receive Address NACK - i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed + i2c_fsm_tranfini(obj, 1); break; case 0x40: // Master Receive Address ACK @@ -656,7 +650,7 @@ static void i2c_irq(i2c_t *obj) while (1); } #endif - i2c_fsm_tranfini(obj, 0); + i2c_fsm_tranfini(obj, 1); } else { uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk; @@ -823,10 +817,10 @@ static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl) obj->i2c.slaveaddr_state = NoData; } -static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv) +static void i2c_fsm_tranfini(i2c_t *obj, int lastdatanaked) { - if (obj->i2c.tran_pos) { - obj->i2c.tran_pos += tran_pos_adv; + if (lastdatanaked) { + obj->i2c.tran_ctrl |= TRANCTRL_LASTDATANAKED; } obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED; diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c index 6547eb475c9..4b5e9ef8c58 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c @@ -51,7 +51,7 @@ static void i2c3_vec(void); static void i2c4_vec(void); static void i2c_irq(i2c_t *obj); static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl); -static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv); +static void i2c_fsm_tranfini(i2c_t *obj, int lastdatanaked); static struct nu_i2c_var i2c0_var = { .obj = NULL, @@ -87,8 +87,6 @@ static const struct nu_modinit_s i2c_modinit_tab[] = { }; static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastdata); -static int i2c_do_write(i2c_t *obj, char data, int naklastdata); -static int i2c_do_read(i2c_t *obj, char *data, int naklastdata); static int i2c_do_trsn(i2c_t *obj, uint32_t i2c_ctl, int sync); #define NU_I2C_TIMEOUT_STAT_INT 500000 #define NU_I2C_TIMEOUT_STOP 500000 @@ -115,6 +113,7 @@ static void i2c_rollback_vector_interrupt(i2c_t *obj); #define TRANCTRL_STARTED (1) #define TRANCTRL_NAKLASTDATA (1 << 1) +#define TRANCTRL_LASTDATANAKED (1 << 2) uint32_t us_ticker_read(void); @@ -186,7 +185,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) return I2C_ERROR_BUS_BUSY; } - if (i2c_do_write(obj, i2c_addr2data(address, 1), 0)) { + if (i2c_byte_write(obj, i2c_addr2data(address, 1)) != 1) { i2c_stop(obj); return I2C_ERROR_NO_SLAVE; } @@ -209,7 +208,7 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) return I2C_ERROR_BUS_BUSY; } - if (i2c_do_write(obj, i2c_addr2data(address, 0), 0)) { + if (i2c_byte_write(obj, i2c_addr2data(address, 0)) != 1) { i2c_stop(obj); return I2C_ERROR_NO_SLAVE; } @@ -232,14 +231,22 @@ void i2c_reset(i2c_t *obj) int i2c_byte_read(i2c_t *obj, int last) { char data = 0; - - i2c_do_read(obj, &data, last); + i2c_do_tran(obj, &data, 1, 1, last); return data; } int i2c_byte_write(i2c_t *obj, int data) { - return i2c_do_write(obj, (data & 0xFF), 0) == 0 ? 1 : 0; + char data_[1]; + data_[0] = data & 0xFF; + + if (i2c_do_tran(obj, data_, 1, 0, 0) == 1 && + ! (obj->i2c.tran_ctrl & TRANCTRL_LASTDATANAKED)) { + return 1; + } + else { + return 0; + } } #if DEVICE_I2CSLAVE @@ -391,7 +398,6 @@ static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastd } else { i2c_disable_int(obj); - obj->i2c.tran_ctrl = 0; tran_len = obj->i2c.tran_pos - obj->i2c.tran_beg; obj->i2c.tran_beg = NULL; obj->i2c.tran_pos = NULL; @@ -402,18 +408,6 @@ static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastd return tran_len; } -static int i2c_do_write(i2c_t *obj, char data, int naklastdata) -{ - char data_[1]; - data_[0] = data; - return i2c_do_tran(obj, data_, 1, 0, naklastdata) == 1 ? 0 : I2C_ERROR_BUS_BUSY; -} - -static int i2c_do_read(i2c_t *obj, char *data, int naklastdata) -{ - return i2c_do_tran(obj, data, 1, 1, naklastdata) == 1 ? 0 : I2C_ERROR_BUS_BUSY; -} - static int i2c_do_trsn(i2c_t *obj, uint32_t i2c_ctl, int sync) { I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c); @@ -655,11 +649,11 @@ static void i2c_irq(i2c_t *obj) break; case 0x30: // Master Transmit Data NACK - i2c_fsm_tranfini(obj, 0); + i2c_fsm_tranfini(obj, 1); break; case 0x20: // Master Transmit Address NACK - i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed + i2c_fsm_tranfini(obj, 1); break; case 0x38: // Master Arbitration Lost @@ -667,7 +661,7 @@ static void i2c_irq(i2c_t *obj) break; case 0x48: // Master Receive Address NACK - i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed + i2c_fsm_tranfini(obj, 1); break; case 0x40: // Master Receive Address ACK @@ -686,7 +680,7 @@ static void i2c_irq(i2c_t *obj) while (1); } #endif - i2c_fsm_tranfini(obj, 0); + i2c_fsm_tranfini(obj, 1); } else { uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk; @@ -853,10 +847,10 @@ static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl) obj->i2c.slaveaddr_state = NoData; } -static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv) +static void i2c_fsm_tranfini(i2c_t *obj, int lastdatanaked) { - if (obj->i2c.tran_pos) { - obj->i2c.tran_pos += tran_pos_adv; + if (lastdatanaked) { + obj->i2c.tran_ctrl |= TRANCTRL_LASTDATANAKED; } obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED; From 137053343e023d6a108777394cd410a37f8e4480 Mon Sep 17 00:00:00 2001 From: ccli8 Date: Wed, 23 Nov 2016 14:35:09 +0800 Subject: [PATCH 11/12] [M453] Fix button naming error --- .../TARGET_M451/TARGET_NUMAKER_PFM_M453/PinNames.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PinNames.h b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PinNames.h index 4e042cd6aca..a9964c135c3 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PinNames.h +++ b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PinNames.h @@ -101,8 +101,8 @@ typedef enum { LED_GREEN = LED3, LED_BLUE = LED1, // Button naming - SW1 = PA_15, - SW2 = PA_14, + SW2 = PA_15, + SW3 = PA_14, } PinName; From e1995dbe790741b12e32e56703937b6a4c1dcea4 Mon Sep 17 00:00:00 2001 From: ccli8 Date: Fri, 25 Nov 2016 15:32:25 +0800 Subject: [PATCH 12/12] [NUC472/M453] Fix spi_master_transfer failed as bit width is 32 --- targets/TARGET_NUVOTON/TARGET_M451/spi_api.c | 7 ++++++- targets/TARGET_NUVOTON/TARGET_NUC472/spi_api.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/spi_api.c b/targets/TARGET_NUVOTON/TARGET_M451/spi_api.c index 63f8e6a5a27..feda823720b 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/spi_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/spi_api.c @@ -709,7 +709,12 @@ static uint8_t spi_get_data_width(spi_t *obj) { SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi); - return ((spi_base->CTL & SPI_CTL_DWIDTH_Msk) >> SPI_CTL_DWIDTH_Pos); + uint32_t data_width = ((spi_base->CTL & SPI_CTL_DWIDTH_Msk) >> SPI_CTL_DWIDTH_Pos); + if (data_width == 0) { + data_width = 32; + } + + return data_width; } static int spi_is_tx_complete(spi_t *obj) diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/spi_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/spi_api.c index 79a3296d2bb..368e4ca5131 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/spi_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/spi_api.c @@ -702,7 +702,12 @@ static uint8_t spi_get_data_width(spi_t *obj) { SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi); - return ((spi_base->CTL & SPI_CTL_DWIDTH_Msk) >> SPI_CTL_DWIDTH_Pos); + uint32_t data_width = ((spi_base->CTL & SPI_CTL_DWIDTH_Msk) >> SPI_CTL_DWIDTH_Pos); + if (data_width == 0) { + data_width = 32; + } + + return data_width; } static int spi_is_tx_complete(spi_t *obj)