M263: 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-08-20 16:52:05 +08:00 committed by adbridge
parent 668d3b077e
commit d6172f0227
9 changed files with 46 additions and 46 deletions

View File

@ -54,28 +54,28 @@ 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 module
SYS_ResetModule(modinit->rsetidx);
// Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
// Reset module
SYS_ResetModule(modinit->rsetidx);
// 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);
}
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);

View File

@ -53,6 +53,9 @@ 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 */
@ -66,15 +69,15 @@ void analogout_init(dac_t *obj, PinName pin)
* channels are deactivated.
*/
if ((! dac_modinit_mask[0]) && (! dac_modinit_mask[1])) {
// 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 8us when 12-bit input code transition from
* lowest code (0x000) to highest code (0xFFF). */
DAC_SetDelayTime(dac_base, 8);
@ -88,9 +91,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;

View File

@ -54,12 +54,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);
/* Check PDMA0. */
PDMA_T *pdma_base = dma_modbase();
if (((uint32_t) pdma_base) != PDMA0_BASE) {

View File

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

View File

@ -82,12 +82,6 @@ void lp_ticker_init(void)
}
ticker_inited = 1;
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule(TIMER_MODINIT.rsetidx);
/* Select IP clock source
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
@ -100,6 +94,12 @@ void lp_ticker_init(void)
*/
CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule(TIMER_MODINIT.rsetidx);
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
// Configure clock

View File

@ -69,11 +69,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);
@ -85,8 +82,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;

View File

@ -201,16 +201,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;

View File

@ -141,18 +141,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;

View File

@ -57,15 +57,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