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.
pull/11696/head
Chun-Chieh Li 2019-07-30 13:37:44 +08:00 committed by adbridge
parent 3cdf84d943
commit a5b7048668
9 changed files with 43 additions and 43 deletions

View File

@ -55,19 +55,22 @@ void analogin_init(analogin_t *obj, PinName pin)
MBED_ASSERT(modinit != NULL); MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->adc); MBED_ASSERT(modinit->modname == (int) obj->adc);
// Wire pinout
pinmap_pinout(pin, PinMap_ADC);
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(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. // NOTE: All channels (identified by ADCName) share a ADC module. This reset will also affect other channels of the same ADC module.
if (! eadc_modinit_mask) { if (! eadc_modinit_mask) {
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
// Select clock source // Select clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv); CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable clock // Enable clock
CLK_EnableModuleClock(modinit->clkidx); CLK_EnableModuleClock(modinit->clkidx);
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
/* Configure EADC_module to be ready to convert /* Configure EADC_module to be ready to convert
* M251 doesn't support 'input mode' feature. Configure it to 0. */ * M251 doesn't support 'input mode' feature. Configure it to 0. */
EADC_Open(eadc_base, 0); EADC_Open(eadc_base, 0);
@ -75,9 +78,6 @@ void analogin_init(analogin_t *obj, PinName pin)
uint32_t chn = NU_MODSUBINDEX(obj->adc); uint32_t chn = NU_MODSUBINDEX(obj->adc);
// Wire pinout
pinmap_pinout(pin, PinMap_ADC);
// Configure the sample module Nmod for analog input channel Nch and software trigger source // Configure the sample module Nmod for analog input channel Nch and software trigger source
EADC_ConfigSampleModule(eadc_base, chn, EADC_SOFTWARE_TRIGGER, chn); EADC_ConfigSampleModule(eadc_base, chn, EADC_SOFTWARE_TRIGGER, chn);

View File

@ -53,20 +53,23 @@ void analogout_init(dac_t *obj, PinName pin)
uint32_t chn = NU_MODSUBINDEX(obj->dac); uint32_t chn = NU_MODSUBINDEX(obj->dac);
MBED_ASSERT(chn < NU_DACCHN_MAXNUM); MBED_ASSERT(chn < NU_DACCHN_MAXNUM);
/* Wire pinout */
pinmap_pinout(pin, PinMap_DAC);
DAC_T *dac_base = (DAC_T *) NU_MODBASE(obj->dac); DAC_T *dac_base = (DAC_T *) NU_MODBASE(obj->dac);
/* Module-level setup from here */ /* Module-level setup from here */
if (! dac_modinit_mask[modidx]) { if (! dac_modinit_mask[modidx]) {
/* Reset IP */
SYS_ResetModule(modinit->rsetidx);
/* Select IP clock source and clock divider */ /* Select IP clock source and clock divider */
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv); CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
/* Enable IP clock */ /* Enable IP clock */
CLK_EnableModuleClock(modinit->clkidx); CLK_EnableModuleClock(modinit->clkidx);
/* Reset IP */
SYS_ResetModule(modinit->rsetidx);
/* The conversion settling time is 6us when 12-bit input code transition from /* The conversion settling time is 6us when 12-bit input code transition from
* lowest code (0x000) to highest code (0xFFF). */ * lowest code (0x000) to highest code (0xFFF). */
DAC_SetDelayTime(dac_base, 6); DAC_SetDelayTime(dac_base, 6);
@ -81,9 +84,6 @@ void analogout_init(dac_t *obj, PinName pin)
/* Set the software trigger, enable DAC event trigger mode and enable D/A converter */ /* Set the software trigger, enable DAC event trigger mode and enable D/A converter */
DAC_Open(dac_base, chn, DAC_SOFTWARE_TRIGGER); DAC_Open(dac_base, chn, DAC_SOFTWARE_TRIGGER);
/* Wire pinout */
pinmap_pinout(pin, PinMap_DAC);
/* Mark channel allocated */ /* Mark channel allocated */
dac_modinit_mask[modidx] |= 1 << chn; dac_modinit_mask[modidx] |= 1 << chn;
} }

View File

@ -52,12 +52,12 @@ void dma_init(void)
dma_chn_mask = ~NU_PDMA_CH_Msk; dma_chn_mask = ~NU_PDMA_CH_Msk;
memset(dma_chn_arr, 0x00, sizeof (dma_chn_arr)); memset(dma_chn_arr, 0x00, sizeof (dma_chn_arr));
/* Reset module */
SYS_ResetModule(dma_modinit.rsetidx);
/* Enable IP clock */ /* Enable IP clock */
CLK_EnableModuleClock(dma_modinit.clkidx); CLK_EnableModuleClock(dma_modinit.clkidx);
/* Reset module */
SYS_ResetModule(dma_modinit.rsetidx);
PDMA_T *pdma_base = dma_modbase(); PDMA_T *pdma_base = dma_modbase();
PDMA_Open(pdma_base, 0); PDMA_Open(pdma_base, 0);

View File

@ -98,14 +98,14 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
MBED_ASSERT(modinit != NULL); MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->i2c.i2c); MBED_ASSERT(modinit->modname == (int) obj->i2c.i2c);
// Reset this module pinmap_pinout(sda, PinMap_I2C_SDA);
SYS_ResetModule(modinit->rsetidx); pinmap_pinout(scl, PinMap_I2C_SCL);
// Enable IP clock // Enable IP clock
CLK_EnableModuleClock(modinit->clkidx); CLK_EnableModuleClock(modinit->clkidx);
pinmap_pinout(sda, PinMap_I2C_SDA); // Reset this module
pinmap_pinout(scl, PinMap_I2C_SCL); SYS_ResetModule(modinit->rsetidx);
#if DEVICE_I2C_ASYNCH #if DEVICE_I2C_ASYNCH
obj->i2c.dma_usage = DMA_USAGE_NEVER; obj->i2c.dma_usage = DMA_USAGE_NEVER;

View File

@ -82,15 +82,15 @@ void lp_ticker_init(void)
} }
ticker_inited = 1; ticker_inited = 1;
// Reset module
SYS_ResetModule(TIMER_MODINIT.rsetidx);
// Select IP clock source // Select IP clock source
CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv); CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv);
// Enable IP clock // Enable IP clock
CLK_EnableModuleClock(TIMER_MODINIT.clkidx); CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
// Reset module
SYS_ResetModule(TIMER_MODINIT.rsetidx);
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname); TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
// Configure clock // Configure clock

View File

@ -70,11 +70,8 @@ void pwmout_init(pwmout_t* obj, PinName pin)
MBED_ASSERT(modinit != NULL); MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->pwm); MBED_ASSERT(modinit->modname == (int) obj->pwm);
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module. // Wire pinout
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) { pinmap_pinout(pin, PinMap_PWM);
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
}
uint32_t chn = NU_MODSUBINDEX(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm);
@ -86,8 +83,11 @@ void pwmout_init(pwmout_t* obj, PinName pin)
CLK_EnableModuleClock(modinit->clkidx); CLK_EnableModuleClock(modinit->clkidx);
} }
// Wire pinout // NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
pinmap_pinout(pin, PinMap_PWM); if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
}
// Default: period = 10 ms, pulse width = 0 ms // Default: period = 10 ms, pulse width = 0 ms
obj->period_us = 1000 * 10; obj->period_us = 1000 * 10;

View File

@ -156,16 +156,16 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
struct nu_uart_var *var = (struct nu_uart_var *) modinit->var; struct nu_uart_var *var = (struct nu_uart_var *) modinit->var;
if (! var->ref_cnt) { if (! var->ref_cnt) {
// Reset this module pinmap_pinout(tx, PinMap_UART_TX);
SYS_ResetModule(modinit->rsetidx); pinmap_pinout(rx, PinMap_UART_RX);
// Select IP clock source // Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv); CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock // Enable IP clock
CLK_EnableModuleClock(modinit->clkidx); CLK_EnableModuleClock(modinit->clkidx);
pinmap_pinout(tx, PinMap_UART_TX); // Reset this module
pinmap_pinout(rx, PinMap_UART_RX); SYS_ResetModule(modinit->rsetidx);
// Configure baudrate // Configure baudrate
int baudrate = 9600; int baudrate = 9600;

View File

@ -120,18 +120,18 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
MBED_ASSERT(modinit != NULL); MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->spi.spi); MBED_ASSERT(modinit->modname == (int) obj->spi.spi);
// Reset this module pinmap_pinout(mosi, PinMap_SPI_MOSI);
SYS_ResetModule(modinit->rsetidx); pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
pinmap_pinout(ssel, PinMap_SPI_SSEL);
// Select IP clock source // Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv); CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock // Enable IP clock
CLK_EnableModuleClock(modinit->clkidx); CLK_EnableModuleClock(modinit->clkidx);
pinmap_pinout(mosi, PinMap_SPI_MOSI); // Reset this module
pinmap_pinout(miso, PinMap_SPI_MISO); SYS_ResetModule(modinit->rsetidx);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
pinmap_pinout(ssel, PinMap_SPI_SSEL);
obj->spi.pin_mosi = mosi; obj->spi.pin_mosi = mosi;
obj->spi.pin_miso = miso; obj->spi.pin_miso = miso;

View File

@ -58,15 +58,15 @@ void us_ticker_init(void)
} }
ticker_inited = 1; ticker_inited = 1;
// Reset IP
SYS_ResetModule(TIMER_MODINIT.rsetidx);
// Select IP clock source // Select IP clock source
CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv); CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv);
// Enable IP clock // Enable IP clock
CLK_EnableModuleClock(TIMER_MODINIT.clkidx); CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
// Reset IP
SYS_ResetModule(TIMER_MODINIT.rsetidx);
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname); TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
// Timer for normal counter // Timer for normal counter