Skip to content

Commit 27dac8a

Browse files
committed
[Nuvoton] Fix IP initialization sequence
Better IP initialization sequence: 1. Configure IP pins 2. Select IP clock source and then enable it 3. Reset the IP (SYS_ResetModule) NOTE1: IP reset takes effect regardless of IP clock. So it doesn't matter if IP clock enable is before IP reset. NOTE2: Non-configured pins may disturb IP's state, so IP pinout first and then IP reset. NOTE3: IP reset at the end of IP initialization sequence can cover unexpected situation.
1 parent aa04732 commit 27dac8a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+323
-305
lines changed

targets/TARGET_NUVOTON/TARGET_M2351/analogin_api.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,37 +53,37 @@ void analogin_init(analogin_t *obj, PinName pin)
5353
MBED_ASSERT(modinit != NULL);
5454
MBED_ASSERT(modinit->modname == (int) obj->adc);
5555

56+
// Wire pinout
57+
pinmap_pinout(pin, PinMap_ADC);
58+
5659
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
5760

5861
// NOTE: All channels (identified by ADCName) share a ADC module. This reset will also affect other channels of the same ADC module.
5962
if (! eadc_modinit_mask) {
60-
/* Reset module
61-
*
62-
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
63-
*/
64-
SYS_ResetModule_S(modinit->rsetidx);
65-
6663
/* Select IP clock source
6764
*
6865
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
6966
*/
7067
CLK_SetModuleClock_S(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
71-
68+
7269
/* Enable IP clock
7370
*
7471
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
7572
*/
7673
CLK_EnableModuleClock_S(modinit->clkidx);
7774

75+
/* Reset module
76+
*
77+
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
78+
*/
79+
SYS_ResetModule_S(modinit->rsetidx);
80+
7881
// Set the ADC internal sampling time, input mode as single-end and enable the A/D converter
7982
EADC_Open(eadc_base, EADC_CTL_DIFFEN_SINGLE_END);
8083
}
8184

8285
uint32_t chn = NU_MODSUBINDEX(obj->adc);
8386

84-
// Wire pinout
85-
pinmap_pinout(pin, PinMap_ADC);
86-
8787
// Configure the sample module Nmod for analog input channel Nch and software trigger source
8888
EADC_ConfigSampleModule(eadc_base, chn, EADC_SOFTWARE_TRIGGER, chn);
8989

targets/TARGET_NUVOTON/TARGET_M2351/analogout_api.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ void analogout_init(dac_t *obj, PinName pin)
5353
uint32_t chn = NU_MODSUBINDEX(obj->dac);
5454
MBED_ASSERT(chn < NU_DACCHN_MAXNUM);
5555

56+
/* Wire pinout */
57+
pinmap_pinout(pin, PinMap_DAC);
58+
5659
DAC_T *dac_base = (DAC_T *) NU_MODBASE(obj->dac);
5760

5861
/* Module-level setup from here */
@@ -66,12 +69,6 @@ void analogout_init(dac_t *obj, PinName pin)
6669
* channels are deactivated.
6770
*/
6871
if ((! dac_modinit_mask[0]) && (! dac_modinit_mask[1])) {
69-
/* Reset IP
70-
*
71-
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
72-
*/
73-
SYS_ResetModule_S(modinit->rsetidx);
74-
7572
/* Select IP clock source and clock divider
7673
*
7774
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
@@ -83,7 +80,13 @@ void analogout_init(dac_t *obj, PinName pin)
8380
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
8481
*/
8582
CLK_EnableModuleClock_S(modinit->clkidx);
86-
83+
84+
/* Reset IP
85+
*
86+
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
87+
*/
88+
SYS_ResetModule_S(modinit->rsetidx);
89+
8790
/* The conversion settling time is 8us when 12-bit input code transition from
8891
* lowest code (0x000) to highest code (0xFFF). */
8992
DAC_SetDelayTime(dac_base, 8);
@@ -98,8 +101,7 @@ void analogout_init(dac_t *obj, PinName pin)
98101
/* Set the software trigger, enable DAC event trigger mode and enable D/A converter */
99102
DAC_Open(dac_base, chn, DAC_SOFTWARE_TRIGGER);
100103

101-
/* Wire pinout */
102-
pinmap_pinout(pin, PinMap_DAC);
104+
103105

104106
/* Mark channel allocated */
105107
dac_modinit_mask[modidx] |= 1 << chn;

targets/TARGET_NUVOTON/TARGET_M2351/dma_api.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,17 @@ void dma_init(void)
6969
dma_chn_mask = ~NU_PDMA_CH_Msk;
7070
memset(dma_chn_arr, 0x00, sizeof (dma_chn_arr));
7171

72-
/* Reset module
72+
/* Enable IP clock
7373
*
7474
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
7575
*/
76-
SYS_ResetModule_S(dma_modinit.rsetidx);
76+
CLK_EnableModuleClock_S(dma_modinit.clkidx);
7777

78-
/* Enable IP clock
78+
/* Reset module
7979
*
8080
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
8181
*/
82-
CLK_EnableModuleClock_S(dma_modinit.clkidx);
82+
SYS_ResetModule_S(dma_modinit.rsetidx);
8383

8484
/* Check security state of PDMA0/1 match the partition policy above. */
8585
PDMA_T *pdma_base = dma_modbase();

targets/TARGET_NUVOTON/TARGET_M2351/i2c_api.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,20 +102,20 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
102102
MBED_ASSERT(modinit != NULL);
103103
MBED_ASSERT(modinit->modname == (int) obj->i2c.i2c);
104104

105-
/* Reset module
106-
*
107-
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
108-
*/
109-
SYS_ResetModule_S(modinit->rsetidx);
105+
pinmap_pinout(sda, PinMap_I2C_SDA);
106+
pinmap_pinout(scl, PinMap_I2C_SCL);
110107

111108
/* Select IP clock source
112109
*
113110
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
114111
*/
115112
CLK_EnableModuleClock_S(modinit->clkidx);
116113

117-
pinmap_pinout(sda, PinMap_I2C_SDA);
118-
pinmap_pinout(scl, PinMap_I2C_SCL);
114+
/* Reset module
115+
*
116+
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
117+
*/
118+
SYS_ResetModule_S(modinit->rsetidx);
119119

120120
#if DEVICE_I2C_ASYNCH
121121
obj->i2c.dma_usage = DMA_USAGE_NEVER;

targets/TARGET_NUVOTON/TARGET_M2351/lp_ticker.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,6 @@ void lp_ticker_init(void)
105105
}
106106
ticker_inited = 1;
107107

108-
/* Reset module
109-
*
110-
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
111-
*/
112-
SYS_ResetModule_S(TIMER_MODINIT.rsetidx);
113-
114108
/* Select IP clock source
115109
*
116110
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
@@ -123,6 +117,12 @@ void lp_ticker_init(void)
123117
*/
124118
CLK_EnableModuleClock_S(TIMER_MODINIT.clkidx);
125119

120+
/* Reset module
121+
*
122+
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
123+
*/
124+
SYS_ResetModule_S(TIMER_MODINIT.rsetidx);
125+
126126
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
127127

128128
// Configure clock

targets/TARGET_NUVOTON/TARGET_M2351/pwmout_api.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,8 @@ void pwmout_init(pwmout_t* obj, PinName pin)
6868
MBED_ASSERT(modinit != NULL);
6969
MBED_ASSERT(modinit->modname == (int) obj->pwm);
7070

71-
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
72-
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
73-
/* Reset module
74-
*
75-
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
76-
*/
77-
SYS_ResetModule_S(modinit->rsetidx);
78-
}
79-
80-
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
71+
// Wire pinout
72+
pinmap_pinout(pin, PinMap_PWM);
8173

8274
// NOTE: Channels 0/1/2/3/4/5 share a clock source.
8375
if ((((struct nu_pwm_var *) modinit->var)->en_msk & 0x3F) == 0) {
@@ -94,8 +86,16 @@ void pwmout_init(pwmout_t* obj, PinName pin)
9486
CLK_EnableModuleClock_S(modinit->clkidx);
9587
}
9688

97-
// Wire pinout
98-
pinmap_pinout(pin, PinMap_PWM);
89+
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
90+
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
91+
/* Reset module
92+
*
93+
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
94+
*/
95+
SYS_ResetModule_S(modinit->rsetidx);
96+
}
97+
98+
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
9999

100100
// Default: period = 10 ms, pulse width = 0 ms
101101
obj->period_us = 1000 * 10;

targets/TARGET_NUVOTON/TARGET_M2351/serial_api.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,8 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
200200
struct nu_uart_var *var = (struct nu_uart_var *) modinit->var;
201201

202202
if (! var->ref_cnt) {
203-
/* Reset module
204-
*
205-
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
206-
*/
207-
SYS_ResetModule_S(modinit->rsetidx);
203+
pinmap_pinout(tx, PinMap_UART_TX);
204+
pinmap_pinout(rx, PinMap_UART_RX);
208205

209206
/* Select IP clock source
210207
*
@@ -218,8 +215,11 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
218215
*/
219216
CLK_EnableModuleClock_S(modinit->clkidx);
220217

221-
pinmap_pinout(tx, PinMap_UART_TX);
222-
pinmap_pinout(rx, PinMap_UART_RX);
218+
/* Reset module
219+
*
220+
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
221+
*/
222+
SYS_ResetModule_S(modinit->rsetidx);
223223

224224
// Configure baudrate
225225
int baudrate = 9600;

targets/TARGET_NUVOTON/TARGET_M2351/spi_api.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,10 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
147147
MBED_ASSERT(modinit != NULL);
148148
MBED_ASSERT(modinit->modname == (int) obj->spi.spi);
149149

150-
/* Reset module
151-
*
152-
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
153-
*/
154-
SYS_ResetModule_S(modinit->rsetidx);
150+
pinmap_pinout(mosi, PinMap_SPI_MOSI);
151+
pinmap_pinout(miso, PinMap_SPI_MISO);
152+
pinmap_pinout(sclk, PinMap_SPI_SCLK);
153+
pinmap_pinout(ssel, PinMap_SPI_SSEL);
155154

156155
/* Select IP clock source
157156
*
@@ -165,10 +164,11 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
165164
*/
166165
CLK_EnableModuleClock_S(modinit->clkidx);
167166

168-
pinmap_pinout(mosi, PinMap_SPI_MOSI);
169-
pinmap_pinout(miso, PinMap_SPI_MISO);
170-
pinmap_pinout(sclk, PinMap_SPI_SCLK);
171-
pinmap_pinout(ssel, PinMap_SPI_SSEL);
167+
/* Reset module
168+
*
169+
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
170+
*/
171+
SYS_ResetModule_S(modinit->rsetidx);
172172

173173
obj->spi.pin_mosi = mosi;
174174
obj->spi.pin_miso = miso;

targets/TARGET_NUVOTON/TARGET_M2351/us_ticker.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,6 @@ void us_ticker_init(void)
7979
}
8080
ticker_inited = 1;
8181

82-
/* Reset module
83-
*
84-
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
85-
*/
86-
SYS_ResetModule_S(TIMER_MODINIT.rsetidx);
87-
8882
/* Select IP clock source
8983
*
9084
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
@@ -97,6 +91,12 @@ void us_ticker_init(void)
9791
*/
9892
CLK_EnableModuleClock_S(TIMER_MODINIT.clkidx);
9993

94+
/* Reset module
95+
*
96+
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
97+
*/
98+
SYS_ResetModule_S(TIMER_MODINIT.rsetidx);
99+
100100
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
101101

102102
// Timer for normal counter

targets/TARGET_NUVOTON/TARGET_M451/analogin_api.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,29 +52,30 @@ void analogin_init(analogin_t *obj, PinName pin)
5252
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
5353
MBED_ASSERT(modinit != NULL);
5454
MBED_ASSERT(modinit->modname == obj->adc);
55-
55+
56+
// Wire pinout
57+
pinmap_pinout(pin, PinMap_ADC);
58+
5659
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
57-
60+
5861
// NOTE: All channels (identified by ADCName) share a ADC module. This reset will also affect other channels of the same ADC module.
5962
if (! eadc_modinit_mask) {
60-
// Reset this module if no channel enabled
61-
SYS_ResetModule(modinit->rsetidx);
62-
6363
// Select clock source of paired channels
6464
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
65+
6566
// Enable clock of paired channels
6667
CLK_EnableModuleClock(modinit->clkidx);
67-
68+
69+
// Reset this module if no channel enabled
70+
SYS_ResetModule(modinit->rsetidx);
71+
6872
// Set the ADC internal sampling time, input mode as single-end and enable the A/D converter
6973
EADC_Open(eadc_base, EADC_CTL_DIFFEN_SINGLE_END);
7074
EADC_SetInternalSampleTime(eadc_base, 6);
7175
}
72-
76+
7377
uint32_t chn = NU_MODSUBINDEX(obj->adc);
74-
75-
// Wire pinout
76-
pinmap_pinout(pin, PinMap_ADC);
77-
78+
7879
// Configure the sample module Nmod for analog input channel Nch and software trigger source
7980
EADC_ConfigSampleModule(eadc_base, chn, EADC_SOFTWARE_TRIGGER, chn);
8081

targets/TARGET_NUVOTON/TARGET_M451/analogout_api.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,22 @@ void analogout_init(dac_t *obj, PinName pin)
5252
uint32_t chn = NU_MODSUBINDEX(obj->dac);
5353
MBED_ASSERT(chn < NU_DACCHN_MAXNUM);
5454

55+
/* Wire pinout */
56+
pinmap_pinout(pin, PinMap_DAC);
57+
5558
DAC_T *dac_base = (DAC_T *) NU_MODBASE(obj->dac);
5659

5760
/* Module-level setup from here */
58-
5961
if (! dac_modinit_mask[modidx]) {
60-
/* Reset IP */
61-
SYS_ResetModule(modinit->rsetidx);
62-
6362
/* Select IP clock source and clock divider */
6463
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
6564

6665
/* Enable IP clock */
6766
CLK_EnableModuleClock(modinit->clkidx);
68-
67+
68+
/* Reset IP */
69+
SYS_ResetModule(modinit->rsetidx);
70+
6971
/* The conversion settling time is 8us when 12-bit input code transition from
7072
* lowest code (0x000) to highest code (0xFFF). */
7173
DAC_SetDelayTime(dac_base, 8);
@@ -79,9 +81,6 @@ void analogout_init(dac_t *obj, PinName pin)
7981

8082
/* Set the software trigger, enable DAC event trigger mode and enable D/A converter */
8183
DAC_Open(dac_base, chn, DAC_SOFTWARE_TRIGGER);
82-
83-
/* Wire pinout */
84-
pinmap_pinout(pin, PinMap_DAC);
8584

8685
/* Mark channel allocated */
8786
dac_modinit_mask[modidx] |= 1 << chn;

0 commit comments

Comments
 (0)