mimxrt: Replace Pin-config constants by a function call.

The Pin config setting by IOMUXC_SetPinConfig() is supplied by a
bit pattern. That pattern is specific for a MCU family. In preparation
for supporting the MIMXRT117x family, the constant bit pattern is
replaced by a function call, such that the bit pattern is created
at a single place. The code for this functions was taken from
machine_pin.c.

Note: A working port for the MIMXRT1176 exists already.
This commit is contained in:
robert-hh 2022-01-02 13:21:06 +01:00 committed by Damien George
parent 5bda84aed5
commit 1dc366f901
9 changed files with 111 additions and 62 deletions

View File

@ -194,7 +194,8 @@ void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy
const machine_pin_af_obj_t *af_obj = pin_find_af(reset_pin, PIN_AF_MODE_ALT5);
IOMUXC_SetPinMux(reset_pin->muxRegister, af_obj->af_mode, 0, 0, reset_pin->configRegister, 0U);
IOMUXC_SetPinConfig(reset_pin->muxRegister, af_obj->af_mode, 0, 0, reset_pin->configRegister, 0xB0A9U);
IOMUXC_SetPinConfig(reset_pin->muxRegister, af_obj->af_mode, 0, 0, reset_pin->configRegister,
pin_generate_config(PIN_PULL_DISABLED, PIN_MODE_OUT, PIN_DRIVE_POWER_5, reset_pin->configRegister));
GPIO_PinInit(reset_pin->gpio, reset_pin->pin, &gpio_config);
#endif
@ -204,7 +205,8 @@ void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy
af_obj = pin_find_af(int_pin, PIN_AF_MODE_ALT5);
IOMUXC_SetPinMux(int_pin->muxRegister, af_obj->af_mode, 0, 0, int_pin->configRegister, 0U);
IOMUXC_SetPinConfig(int_pin->muxRegister, af_obj->af_mode, 0, 0, int_pin->configRegister, 0xB0A9U);
IOMUXC_SetPinConfig(int_pin->muxRegister, af_obj->af_mode, 0, 0, int_pin->configRegister,
pin_generate_config(PIN_PULL_UP_47K, PIN_MODE_IN, PIN_DRIVE_POWER_5, int_pin->configRegister));
GPIO_PinInit(int_pin->gpio, int_pin->pin, &gpio_config);
#endif

View File

@ -72,15 +72,14 @@ static const iomux_table_t iomux_table[] = { IOMUX_TABLE_I2C };
bool lpi2c_set_iomux(int8_t hw_i2c, uint8_t drive) {
int index = (hw_i2c - 1) * 2;
uint16_t pad_config = pin_generate_config(PIN_PULL_UP_100K, PIN_MODE_OPEN_DRAIN, drive, SCL.configRegister);
if (SCL.muxRegister != 0) {
IOMUXC_SetPinMux(SCL.muxRegister, SCL.muxMode, SCL.inputRegister, SCL.inputDaisy, SCL.configRegister, 1U);
IOMUXC_SetPinConfig(SCL.muxRegister, SCL.muxMode, SCL.inputRegister, SCL.inputDaisy, SCL.configRegister,
0xF880u | drive << IOMUXC_SW_PAD_CTL_PAD_DSE_SHIFT);
IOMUXC_SetPinConfig(SCL.muxRegister, SCL.muxMode, SCL.inputRegister, SCL.inputDaisy, SCL.configRegister, pad_config);
IOMUXC_SetPinMux(SDA.muxRegister, SDA.muxMode, SDA.inputRegister, SDA.inputDaisy, SDA.configRegister, 1U);
IOMUXC_SetPinConfig(SDA.muxRegister, SDA.muxMode, SDA.inputRegister, SDA.inputDaisy, SDA.configRegister,
0xF880u | drive << IOMUXC_SW_PAD_CTL_PAD_DSE_SHIFT);
IOMUXC_SetPinConfig(SDA.muxRegister, SDA.muxMode, SDA.inputRegister, SDA.inputDaisy, SDA.configRegister, pad_config);
return true;
} else {
return false;

View File

@ -213,6 +213,7 @@ STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_
const machine_pin_af_obj_t *af_obj;
uint32_t pad_config = 0UL;
uint8_t pull = PIN_PULL_DISABLED;
uint32_t drive = (uint32_t)args[PIN_INIT_ARG_DRIVE].u_int;
// Generate pin configuration
if ((args[PIN_INIT_ARG_VALUE].u_obj != MP_OBJ_NULL) && (mp_obj_is_true(args[PIN_INIT_ARG_VALUE].u_obj))) {
@ -233,38 +234,7 @@ STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_
pull = (uint8_t)mp_obj_get_int(args[PIN_INIT_ARG_PULL].u_obj);
}
pad_config |= IOMUXC_SW_PAD_CTL_PAD_SRE(0U); // Slow Slew Rate
pad_config |= IOMUXC_SW_PAD_CTL_PAD_SPEED(0b01); // medium(100MHz)
if (mode == PIN_MODE_OPEN_DRAIN) {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_ODE(0b1); // Open Drain Enabled
} else {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_ODE(0b0); // Open Drain Disabled
}
if (pull == PIN_PULL_DISABLED) {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(0); // Pull/Keeper Disabled
} else if (pull == PIN_PULL_HOLD) {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(1) | // Pull/Keeper Enabled
IOMUXC_SW_PAD_CTL_PAD_PUE(0); // Keeper selected
} else {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(1) | // Pull/Keeper Enabled
IOMUXC_SW_PAD_CTL_PAD_PUE(1) | // Pull selected
IOMUXC_SW_PAD_CTL_PAD_PUS(pull);
}
if (mode == PIN_MODE_IN) {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_DSE(0b000) | // output driver disabled
IOMUXC_SW_PAD_CTL_PAD_HYS(1U); // Hysteresis enabled
} else {
uint drive = args[PIN_INIT_ARG_DRIVE].u_int;
if (!IS_GPIO_DRIVE(drive)) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid drive strength: %d"), drive);
}
pad_config |= IOMUXC_SW_PAD_CTL_PAD_DSE(drive) |
IOMUXC_SW_PAD_CTL_PAD_HYS(0U); // Hysteresis disabled
}
pad_config = pin_generate_config(pull, mode, drive, self->configRegister);
// Configure PAD as GPIO
IOMUXC_SetPinMux(self->muxRegister, af_obj->af_mode, 0, 0, self->configRegister, 1U); // Software Input On Field: Input Path is determined by functionality

View File

@ -518,7 +518,7 @@ STATIC mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args
IOMUXC_SetPinMux(pin1->muxRegister, af_obj1->af_mode, af_obj1->input_register, af_obj1->input_daisy,
pin1->configRegister, 0U);
IOMUXC_SetPinConfig(pin1->muxRegister, af_obj1->af_mode, af_obj1->input_register, af_obj1->input_daisy,
pin1->configRegister, 0x10B0U);
pin1->configRegister, pin_generate_config(PIN_PULL_DISABLED, PIN_MODE_OUT, PIN_DRIVE_POWER_5, pin1->configRegister));
// Settings for the second pin, if given.
if (pin2 != NULL && pin2 != pin1) {
@ -529,7 +529,7 @@ STATIC mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args
IOMUXC_SetPinMux(pin2->muxRegister, af_obj2->af_mode, af_obj2->input_register, af_obj2->input_daisy,
pin2->configRegister, 0U);
IOMUXC_SetPinConfig(pin2->muxRegister, af_obj2->af_mode, af_obj2->input_register, af_obj2->input_daisy,
pin2->configRegister, 0x10B0U);
pin2->configRegister, pin_generate_config(PIN_PULL_DISABLED, PIN_MODE_OUT, PIN_DRIVE_POWER_5, pin2->configRegister));
} else {
self->complementary = 0;
}

View File

@ -87,19 +87,19 @@ bool lpspi_set_iomux(int8_t spi, uint8_t drive) {
if (SCK.muxRegister != 0) {
IOMUXC_SetPinMux(SCK.muxRegister, SCK.muxMode, SCK.inputRegister, SCK.inputDaisy, SCK.configRegister, 0U);
IOMUXC_SetPinConfig(SCK.muxRegister, SCK.muxMode, SCK.inputRegister, SCK.inputDaisy, SCK.configRegister,
0x1080u | drive << IOMUXC_SW_PAD_CTL_PAD_DSE_SHIFT);
pin_generate_config(PIN_PULL_UP_100K, PIN_MODE_OUT, drive, SCK.configRegister));
IOMUXC_SetPinMux(CS0.muxRegister, CS0.muxMode, CS0.inputRegister, CS0.inputDaisy, CS0.configRegister, 0U);
IOMUXC_SetPinConfig(CS0.muxRegister, CS0.muxMode, CS0.inputRegister, CS0.inputDaisy, CS0.configRegister,
0x1080u | drive << IOMUXC_SW_PAD_CTL_PAD_DSE_SHIFT);
pin_generate_config(PIN_PULL_UP_100K, PIN_MODE_OUT, drive, CS0.configRegister));
IOMUXC_SetPinMux(SDO.muxRegister, SDO.muxMode, SDO.inputRegister, SDO.inputDaisy, SDO.configRegister, 0U);
IOMUXC_SetPinConfig(SDO.muxRegister, SDO.muxMode, SDO.inputRegister, SDO.inputDaisy, SDO.configRegister,
0x1080u | drive << IOMUXC_SW_PAD_CTL_PAD_DSE_SHIFT);
pin_generate_config(PIN_PULL_UP_100K, PIN_MODE_OUT, drive, SDO.configRegister));
IOMUXC_SetPinMux(SDI.muxRegister, SDI.muxMode, SDI.inputRegister, SDI.inputDaisy, SDI.configRegister, 0U);
IOMUXC_SetPinConfig(SDI.muxRegister, SDI.muxMode, SDI.inputRegister, SDI.inputDaisy, SDI.configRegister,
0x1080u | drive << IOMUXC_SW_PAD_CTL_PAD_DSE_SHIFT);
pin_generate_config(PIN_PULL_UP_100K, PIN_MODE_IN, drive, SDI.configRegister));
return true;
} else {

View File

@ -84,10 +84,12 @@ bool lpuart_set_iomux(int8_t uart) {
if (TX.muxRegister != 0) {
IOMUXC_SetPinMux(TX.muxRegister, TX.muxMode, TX.inputRegister, TX.inputDaisy, TX.configRegister, 0U);
IOMUXC_SetPinConfig(TX.muxRegister, TX.muxMode, TX.inputRegister, TX.inputDaisy, TX.configRegister, 0x10B0u);
IOMUXC_SetPinConfig(TX.muxRegister, TX.muxMode, TX.inputRegister, TX.inputDaisy, TX.configRegister,
pin_generate_config(PIN_PULL_UP_100K, PIN_MODE_OUT, PIN_DRIVE_POWER_6, TX.configRegister));
IOMUXC_SetPinMux(RX.muxRegister, RX.muxMode, RX.inputRegister, RX.inputDaisy, RX.configRegister, 0U);
IOMUXC_SetPinConfig(RX.muxRegister, RX.muxMode, RX.inputRegister, RX.inputDaisy, RX.configRegister, 0x10B0u);
IOMUXC_SetPinConfig(RX.muxRegister, RX.muxMode, RX.inputRegister, RX.inputDaisy, RX.configRegister,
pin_generate_config(PIN_PULL_UP_100K, PIN_MODE_IN, PIN_DRIVE_POWER_6, RX.configRegister));
return true;
} else {
return false;

View File

@ -62,6 +62,86 @@ uint32_t pin_get_af(const machine_pin_obj_t *pin) {
return (uint32_t)(mux_register & IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_MASK) >> IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_SHIFT;
}
uint32_t pin_generate_config(const uint32_t pull, const uint32_t mode, const uint32_t drive, uint32_t config_register) {
uint32_t pad_config = 0x0UL;
#if defined MIMXRT117x_SERIES
// Set Pull-up
if ((config_register >= 0x400E8350 && config_register <= 0x400E83dc) || // GPIO_AD_xx
(config_register >= 0x40C08040 && config_register <= 0x40C0807C)) { // GPIO_LPSR_xx
pad_config |= IOMUXC_SW_PAD_CTL_PAD_SRE(0U); // Set slew rate; there is a discrepancy between doc and header file
if (pull != PIN_PULL_DISABLED) {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PUE(1) | // Pull Enabled
IOMUXC_SW_PAD_CTL_PAD_PUS(pull != PIN_PULL_DOWN_100K); // Up or DOWn
}
} else { // GPIO_SD_Bx_xx
if (pull == PIN_PULL_DISABLED) {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PULL(0b11);
} else if (pull == PIN_PULL_DOWN_100K) {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PULL(0b10);
} else {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PULL(0b01);
}
}
// Set open Drain; different for LPSR GPIO!
if (config_register >= 0x40C08040 && config_register <= 0x40C0807C) { // GPIO_LPSR_xx
if (mode == PIN_MODE_OPEN_DRAIN) {
pad_config |= 1 << 5; // Open Drain Enabled, no Macro provided
}
} else {
if (mode == PIN_MODE_OPEN_DRAIN) {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_ODE(0b1); // Open Drain Enabled
}
}
// Set drive strength
if (mode != PIN_MODE_IN) {
if (!IS_GPIO_DRIVE(drive)) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid drive strength: %d"), drive);
}
pad_config |= IOMUXC_SW_PAD_CTL_PAD_DSE(drive >= PIN_DRIVE_POWER_4);
}
#else
pad_config |= IOMUXC_SW_PAD_CTL_PAD_SRE(0U); // Slow Slew Rate
pad_config |= IOMUXC_SW_PAD_CTL_PAD_SPEED(0b01); // medium(100MHz)
if (mode == PIN_MODE_OPEN_DRAIN) {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_ODE(0b1); // Open Drain Enabled
} else {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_ODE(0b0); // Open Drain Disabled
}
if (pull == PIN_PULL_DISABLED) {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(0); // Pull/Keeper Disabled
} else if (pull == PIN_PULL_HOLD) {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(1) | // Pull/Keeper Enabled
IOMUXC_SW_PAD_CTL_PAD_PUE(0); // Keeper selected
} else {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(1) | // Pull/Keeper Enabled
IOMUXC_SW_PAD_CTL_PAD_PUE(1) | // Pull selected
IOMUXC_SW_PAD_CTL_PAD_PUS(pull);
}
if (mode == PIN_MODE_IN) {
pad_config |= IOMUXC_SW_PAD_CTL_PAD_DSE(0b000) | // output driver disabled
IOMUXC_SW_PAD_CTL_PAD_HYS(1U); // Hysteresis enabled
} else {
if (!IS_GPIO_DRIVE(drive)) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid drive strength: %d"), drive);
}
pad_config |= IOMUXC_SW_PAD_CTL_PAD_DSE(drive) |
IOMUXC_SW_PAD_CTL_PAD_HYS(0U); // Hysteresis disabled
}
#endif
return pad_config;
}
const machine_pin_obj_t *pin_find(mp_obj_t user_obj) {
const machine_pin_obj_t *pin_obj;

View File

@ -55,6 +55,7 @@ enum {
PIN_MODE_OUT,
PIN_MODE_OPEN_DRAIN,
PIN_MODE_ALT,
PIN_MODE_SKIP,
};
enum {
@ -159,5 +160,6 @@ const machine_pin_af_obj_t *pin_find_af(const machine_pin_obj_t *pin, uint8_t fn
const machine_pin_af_obj_t *pin_find_af_by_index(const machine_pin_obj_t *pin, mp_uint_t af_idx);
const machine_pin_af_obj_t *pin_find_af_by_name(const machine_pin_obj_t *pin, const char *name);
void machine_pin_set_mode(const machine_pin_obj_t *pin, uint8_t mode);
uint32_t pin_generate_config(const uint32_t pull, const uint32_t mode, const uint32_t drive, uint32_t config_register);
#endif // MICROPY_INCLUDED_MIMXRT_PIN_H

View File

@ -725,24 +725,18 @@ static inline void sdcard_init_pin(const machine_pin_obj_t *pin, uint8_t af_idx,
void sdcard_init_pins(mimxrt_sdcard_obj_t *card) {
// speed and strength optimized for clock frequency < 100MHz
uint32_t speed = 1U;
uint32_t strength = 7U;
const mimxrt_sdcard_obj_pins_t *pins = card->pins;
uint32_t default_config = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) |
IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK |
IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK |
IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
IOMUXC_SW_PAD_CTL_PAD_DSE(strength);
uint32_t no_cd_config = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) |
IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK |
IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK |
IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
IOMUXC_SW_PAD_CTL_PAD_DSE(strength);
uint32_t default_config = pin_generate_config(
PIN_PULL_UP_47K, PIN_MODE_SKIP, PIN_DRIVE_POWER_6, card->pins->clk.pin->configRegister);
#if USDHC_DATA3_PULL_DOWN_ON_BOARD
// Pull down on the board -> must not enable internal PD.
uint32_t no_cd_config = pin_generate_config(
PIN_PULL_DISABLED, PIN_MODE_SKIP, PIN_DRIVE_POWER_6, card->pins->data3.pin->configRegister);
#else
uint32_t no_cd_config = pin_generate_config(
PIN_PULL_DOWN_100K, PIN_MODE_SKIP, PIN_DRIVE_POWER_6, card->pins->data3.pin->configRegister);
#endif // USDHC_DATA3_PULL_DOWN_ON_BOARD
sdcard_init_pin(card->pins->clk.pin, card->pins->clk.af_idx, default_config); // USDHC1_CLK
sdcard_init_pin(card->pins->cmd.pin, card->pins->cmd.af_idx, default_config); // USDHC1_CMD