mirror of https://github.com/ARMmbed/mbed-os.git
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
parent
3cdf84d943
commit
a5b7048668
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -80,9 +83,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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue