M263: Free up peripheral pins in peripheral free-up HAL API

Without free-up of peripheral pins, peripheral pins of the same peripheral may
share by multiple ports after port iteration, and this peripheral may fail with
pin interference.
pull/11379/head
Chun-Chieh Li 2019-08-20 17:52:03 +08:00
parent 78ae1e0c73
commit c67a0d8bd0
7 changed files with 71 additions and 11 deletions

View File

@ -54,6 +54,8 @@ 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);
obj->pin = pin;
// Wire pinout // Wire pinout
pinmap_pinout(pin, PinMap_ADC); pinmap_pinout(pin, PinMap_ADC);

View File

@ -53,6 +53,8 @@ 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);
obj->pin = pin;
/* Wire pinout */ /* Wire pinout */
pinmap_pinout(pin, PinMap_DAC); pinmap_pinout(pin, PinMap_DAC);
@ -128,6 +130,10 @@ void analogout_free(dac_t *obj)
// Disable IP clock // Disable IP clock
CLK_DisableModuleClock(modinit->clkidx); CLK_DisableModuleClock(modinit->clkidx);
} }
// Free up pins
gpio_set(obj->pin);
obj->pin = NC;
} }
void analogout_write(dac_t *obj, float value) void analogout_write(dac_t *obj, float value)

View File

@ -104,6 +104,9 @@ 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);
obj->i2c.pin_sda = sda;
obj->i2c.pin_scl = scl;
pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL); pinmap_pinout(scl, PinMap_I2C_SCL);

View File

@ -43,15 +43,21 @@ struct port_s {
struct analogin_s { struct analogin_s {
ADCName adc; ADCName adc;
PinName pin;
}; };
struct dac_s { struct dac_s {
DACName dac; DACName dac;
PinName pin;
}; };
struct serial_s { struct serial_s {
UARTName uart; UARTName uart;
PinName pin_tx;
PinName pin_rx;
PinName pin_rts;
PinName pin_cts;
uint32_t baudrate; uint32_t baudrate;
uint32_t databits; uint32_t databits;
uint32_t parity; uint32_t parity;
@ -90,8 +96,10 @@ struct spi_s {
struct i2c_s { struct i2c_s {
I2CName i2c; I2CName i2c;
PinName pin_sda;
PinName pin_scl;
int slaveaddr_state; int slaveaddr_state;
uint32_t tran_ctrl; uint32_t tran_ctrl;
char * tran_beg; char * tran_beg;
char * tran_pos; char * tran_pos;
@ -108,6 +116,7 @@ struct i2c_s {
struct pwmout_s { struct pwmout_s {
PWMName pwm; PWMName pwm;
PinName pin;
uint32_t period_us; uint32_t period_us;
uint32_t pulsewidth_us; uint32_t pulsewidth_us;
}; };

View File

@ -69,6 +69,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);
obj->pin = pin;
// Wire pinout // Wire pinout
pinmap_pinout(pin, PinMap_PWM); pinmap_pinout(pin, PinMap_PWM);
@ -119,6 +121,10 @@ void pwmout_free(pwmout_t* obj)
// Mark this module to be deinited. // Mark this module to be deinited.
int i = modinit - pwm_modinit_tab; int i = modinit - pwm_modinit_tab;
pwm_modinit_mask &= ~(1 << i); pwm_modinit_mask &= ~(1 << i);
// Free up pins
gpio_set(obj->pin);
obj->pin = NC;
} }
void pwmout_write(pwmout_t* obj, float value) void pwmout_write(pwmout_t* obj, float value)

View File

@ -201,10 +201,15 @@ 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) { obj->serial.pin_tx = tx;
pinmap_pinout(tx, PinMap_UART_TX); obj->serial.pin_rx = rx;
pinmap_pinout(rx, PinMap_UART_RX); obj->serial.pin_rts = NC;
obj->serial.pin_cts = NC;
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
if (! var->ref_cnt) {
// 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
@ -304,6 +309,16 @@ void serial_free(serial_t *obj)
int i = modinit - uart_modinit_tab; int i = modinit - uart_modinit_tab;
uart_modinit_mask &= ~(1 << i); uart_modinit_mask &= ~(1 << i);
} }
// Free up pins
gpio_set(obj->serial.pin_tx);
gpio_set(obj->serial.pin_rx);
gpio_set(obj->serial.pin_rts);
gpio_set(obj->serial.pin_cts);
obj->serial.pin_tx = NC;
obj->serial.pin_rx = NC;
obj->serial.pin_rts = NC;
obj->serial.pin_cts = NC;
} }
void serial_baud(serial_t *obj, int baudrate) void serial_baud(serial_t *obj, int baudrate)
@ -350,6 +365,16 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
{ {
UART_T *uart_base = (UART_T *) NU_MODBASE(obj->serial.uart); UART_T *uart_base = (UART_T *) NU_MODBASE(obj->serial.uart);
// Free up old rts/cts pins when they are different from new ones
if (obj->serial.pin_rts != rxflow) {
gpio_set(obj->serial.pin_rts);
obj->serial.pin_rts = rxflow;
}
if (obj->serial.pin_cts != txflow) {
gpio_set(obj->serial.pin_cts);
obj->serial.pin_cts = txflow;
}
if (rxflow != NC) { if (rxflow != NC) {
// Check if RTS pin matches. // Check if RTS pin matches.
uint32_t uart_rts = pinmap_peripheral(rxflow, PinMap_UART_RTS); uint32_t uart_rts = pinmap_peripheral(rxflow, PinMap_UART_RTS);

View File

@ -141,6 +141,11 @@ 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);
obj->spi.pin_mosi = mosi;
obj->spi.pin_miso = miso;
obj->spi.pin_sclk = sclk;
obj->spi.pin_ssel = ssel;
pinmap_pinout(mosi, PinMap_SPI_MOSI); pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO); pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK); pinmap_pinout(sclk, PinMap_SPI_SCLK);
@ -154,12 +159,6 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
// Reset this module // Reset this module
SYS_ResetModule(modinit->rsetidx); SYS_ResetModule(modinit->rsetidx);
obj->spi.pin_mosi = mosi;
obj->spi.pin_miso = miso;
obj->spi.pin_sclk = sclk;
obj->spi.pin_ssel = ssel;
#if DEVICE_SPI_ASYNCH #if DEVICE_SPI_ASYNCH
obj->spi.dma_usage = DMA_USAGE_NEVER; obj->spi.dma_usage = DMA_USAGE_NEVER;
obj->spi.event = 0; obj->spi.event = 0;
@ -205,6 +204,16 @@ void spi_free(spi_t *obj)
// Mark this module to be deinited. // Mark this module to be deinited.
int i = modinit - spi_modinit_tab; int i = modinit - spi_modinit_tab;
spi_modinit_mask &= ~(1 << i); spi_modinit_mask &= ~(1 << i);
// Free up pins
gpio_set(obj->spi.pin_mosi);
gpio_set(obj->spi.pin_miso);
gpio_set(obj->spi.pin_sclk);
gpio_set(obj->spi.pin_ssel);
obj->spi.pin_mosi = NC;
obj->spi.pin_miso = NC;
obj->spi.pin_sclk = NC;
obj->spi.pin_ssel = NC;
} }
void spi_format(spi_t *obj, int bits, int mode, int slave) void spi_format(spi_t *obj, int bits, int mode, int slave)