stm32:Etablish device before enabling outputs
This prevents gliches on changing to an output mode. If not the ALT mux can be selecting a IP block that is drving the line to say 0. Then the output is connected to that source, then swithced to the correct source. This produced a 430 nS glich on a F4 @168 Mhz. It was a enough to corrupt an I2C device with a bus monitor.
This commit is contained in:
parent
0504e1d5f6
commit
d5e306e6f3
@ -406,6 +406,7 @@ int stm32_configgpio(uint32_t cfgset)
|
||||
uintptr_t base;
|
||||
uint32_t regval;
|
||||
uint32_t setting;
|
||||
uint32_t alt_setting;
|
||||
unsigned int regoffset;
|
||||
unsigned int port;
|
||||
unsigned int pin;
|
||||
@ -463,6 +464,41 @@ int stm32_configgpio(uint32_t cfgset)
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Determine the alternate function (Only alternate function pins) */
|
||||
|
||||
if (pinmode == GPIO_MODER_ALT)
|
||||
{
|
||||
alt_setting = (cfgset & GPIO_AF_MASK) >> GPIO_AF_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
alt_setting = 0;
|
||||
}
|
||||
|
||||
/* Set the alternate function (Only alternate function pins)
|
||||
* This is done before configuring the Outputs on a change to
|
||||
* an Alternate function.
|
||||
*/
|
||||
|
||||
if (alt_setting != 0)
|
||||
{
|
||||
if (pin < 8)
|
||||
{
|
||||
regoffset = STM32_GPIO_AFRL_OFFSET;
|
||||
pos = pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
regoffset = STM32_GPIO_AFRH_OFFSET;
|
||||
pos = pin - 8;
|
||||
}
|
||||
|
||||
regval = getreg32(base + regoffset);
|
||||
regval &= ~GPIO_AFR_MASK(pos);
|
||||
regval |= (alt_setting << GPIO_AFR_SHIFT(pos));
|
||||
putreg32(regval, base + regoffset);
|
||||
}
|
||||
|
||||
/* Now apply the configuration to the mode register */
|
||||
|
||||
regval = getreg32(base + STM32_GPIO_MODER_OFFSET);
|
||||
@ -496,17 +532,13 @@ int stm32_configgpio(uint32_t cfgset)
|
||||
regval |= (setting << GPIO_PUPDR_SHIFT(pin));
|
||||
putreg32(regval, base + STM32_GPIO_PUPDR_OFFSET);
|
||||
|
||||
/* Set the alternate function (Only alternate function pins) */
|
||||
/* Set the alternate function (Only alternate function pins)
|
||||
* This is done after configuring the the pin's connection
|
||||
* on a change away from an Alternate function.
|
||||
*/
|
||||
|
||||
if (pinmode == GPIO_MODER_ALT)
|
||||
if (alt_setting == 0)
|
||||
{
|
||||
setting = (cfgset & GPIO_AF_MASK) >> GPIO_AF_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
setting = 0;
|
||||
}
|
||||
|
||||
if (pin < 8)
|
||||
{
|
||||
regoffset = STM32_GPIO_AFRL_OFFSET;
|
||||
@ -520,8 +552,9 @@ int stm32_configgpio(uint32_t cfgset)
|
||||
|
||||
regval = getreg32(base + regoffset);
|
||||
regval &= ~GPIO_AFR_MASK(pos);
|
||||
regval |= (setting << GPIO_AFR_SHIFT(pos));
|
||||
regval |= (alt_setting << GPIO_AFR_SHIFT(pos));
|
||||
putreg32(regval, base + regoffset);
|
||||
}
|
||||
|
||||
/* Set speed (Only outputs and alternate function pins) */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user