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->modname == (int) obj->adc);
|
||||
|
||||
// Wire pinout
|
||||
pinmap_pinout(pin, PinMap_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 (! eadc_modinit_mask) {
|
||||
// Reset this module if no channel enabled
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
|
||||
// Select clock source
|
||||
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
|
||||
|
||||
// Enable clock
|
||||
CLK_EnableModuleClock(modinit->clkidx);
|
||||
|
||||
// Reset this module if no channel enabled
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
|
||||
/* Configure EADC_module to be ready to convert
|
||||
* M251 doesn't support 'input mode' feature. Configure it to 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);
|
||||
|
||||
// Wire pinout
|
||||
pinmap_pinout(pin, PinMap_ADC);
|
||||
|
||||
// Configure the sample module Nmod for analog input channel Nch and software trigger source
|
||||
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);
|
||||
MBED_ASSERT(chn < NU_DACCHN_MAXNUM);
|
||||
|
||||
/* Wire pinout */
|
||||
pinmap_pinout(pin, PinMap_DAC);
|
||||
|
||||
DAC_T *dac_base = (DAC_T *) NU_MODBASE(obj->dac);
|
||||
|
||||
/* Module-level setup from here */
|
||||
|
||||
if (! dac_modinit_mask[modidx]) {
|
||||
/* Reset IP */
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
|
||||
/* Select IP clock source and clock divider */
|
||||
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
|
||||
|
||||
/* Enable IP clock */
|
||||
CLK_EnableModuleClock(modinit->clkidx);
|
||||
|
||||
/* Reset IP */
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
|
||||
/* The conversion settling time is 6us when 12-bit input code transition from
|
||||
* lowest code (0x000) to highest code (0xFFF). */
|
||||
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 */
|
||||
DAC_Open(dac_base, chn, DAC_SOFTWARE_TRIGGER);
|
||||
|
||||
/* Wire pinout */
|
||||
pinmap_pinout(pin, PinMap_DAC);
|
||||
|
||||
/* Mark channel allocated */
|
||||
dac_modinit_mask[modidx] |= 1 << chn;
|
||||
}
|
||||
|
|
|
@ -52,12 +52,12 @@ void dma_init(void)
|
|||
dma_chn_mask = ~NU_PDMA_CH_Msk;
|
||||
memset(dma_chn_arr, 0x00, sizeof (dma_chn_arr));
|
||||
|
||||
/* Reset module */
|
||||
SYS_ResetModule(dma_modinit.rsetidx);
|
||||
|
||||
/* Enable IP clock */
|
||||
CLK_EnableModuleClock(dma_modinit.clkidx);
|
||||
|
||||
/* Reset module */
|
||||
SYS_ResetModule(dma_modinit.rsetidx);
|
||||
|
||||
PDMA_T *pdma_base = dma_modbase();
|
||||
|
||||
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->modname == (int) obj->i2c.i2c);
|
||||
|
||||
// Reset this module
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
pinmap_pinout(sda, PinMap_I2C_SDA);
|
||||
pinmap_pinout(scl, PinMap_I2C_SCL);
|
||||
|
||||
// Enable IP clock
|
||||
CLK_EnableModuleClock(modinit->clkidx);
|
||||
|
||||
pinmap_pinout(sda, PinMap_I2C_SDA);
|
||||
pinmap_pinout(scl, PinMap_I2C_SCL);
|
||||
// Reset this module
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
|
||||
#if DEVICE_I2C_ASYNCH
|
||||
obj->i2c.dma_usage = DMA_USAGE_NEVER;
|
||||
|
|
|
@ -82,15 +82,15 @@ void lp_ticker_init(void)
|
|||
}
|
||||
ticker_inited = 1;
|
||||
|
||||
// Reset module
|
||||
SYS_ResetModule(TIMER_MODINIT.rsetidx);
|
||||
|
||||
// Select IP clock source
|
||||
CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv);
|
||||
|
||||
// Enable IP clock
|
||||
CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
|
||||
|
||||
// Reset module
|
||||
SYS_ResetModule(TIMER_MODINIT.rsetidx);
|
||||
|
||||
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
|
||||
|
||||
// Configure clock
|
||||
|
|
|
@ -70,11 +70,8 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
MBED_ASSERT(modinit != NULL);
|
||||
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.
|
||||
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
|
||||
// Reset this module if no channel enabled
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
}
|
||||
// Wire pinout
|
||||
pinmap_pinout(pin, PinMap_PWM);
|
||||
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
|
||||
|
@ -86,8 +83,11 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
CLK_EnableModuleClock(modinit->clkidx);
|
||||
}
|
||||
|
||||
// Wire pinout
|
||||
pinmap_pinout(pin, PinMap_PWM);
|
||||
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
|
||||
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
|
||||
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;
|
||||
|
||||
if (! var->ref_cnt) {
|
||||
// Reset this module
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
pinmap_pinout(tx, PinMap_UART_TX);
|
||||
pinmap_pinout(rx, PinMap_UART_RX);
|
||||
|
||||
// Select IP clock source
|
||||
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
|
||||
// Enable IP clock
|
||||
CLK_EnableModuleClock(modinit->clkidx);
|
||||
|
||||
pinmap_pinout(tx, PinMap_UART_TX);
|
||||
pinmap_pinout(rx, PinMap_UART_RX);
|
||||
// Reset this module
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
|
||||
// Configure baudrate
|
||||
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->modname == (int) obj->spi.spi);
|
||||
|
||||
// Reset this module
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
pinmap_pinout(mosi, PinMap_SPI_MOSI);
|
||||
pinmap_pinout(miso, PinMap_SPI_MISO);
|
||||
pinmap_pinout(sclk, PinMap_SPI_SCLK);
|
||||
pinmap_pinout(ssel, PinMap_SPI_SSEL);
|
||||
|
||||
// Select IP clock source
|
||||
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
|
||||
// Enable IP clock
|
||||
CLK_EnableModuleClock(modinit->clkidx);
|
||||
|
||||
pinmap_pinout(mosi, PinMap_SPI_MOSI);
|
||||
pinmap_pinout(miso, PinMap_SPI_MISO);
|
||||
pinmap_pinout(sclk, PinMap_SPI_SCLK);
|
||||
pinmap_pinout(ssel, PinMap_SPI_SSEL);
|
||||
// Reset this module
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
|
||||
obj->spi.pin_mosi = mosi;
|
||||
obj->spi.pin_miso = miso;
|
||||
|
|
|
@ -58,15 +58,15 @@ void us_ticker_init(void)
|
|||
}
|
||||
ticker_inited = 1;
|
||||
|
||||
// Reset IP
|
||||
SYS_ResetModule(TIMER_MODINIT.rsetidx);
|
||||
|
||||
// Select IP clock source
|
||||
CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv);
|
||||
|
||||
// Enable IP clock
|
||||
CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
|
||||
|
||||
// Reset IP
|
||||
SYS_ResetModule(TIMER_MODINIT.rsetidx);
|
||||
|
||||
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
|
||||
|
||||
// Timer for normal counter
|
||||
|
|
Loading…
Reference in New Issue