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;
|
uintptr_t base;
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
uint32_t setting;
|
uint32_t setting;
|
||||||
|
uint32_t alt_setting;
|
||||||
unsigned int regoffset;
|
unsigned int regoffset;
|
||||||
unsigned int port;
|
unsigned int port;
|
||||||
unsigned int pin;
|
unsigned int pin;
|
||||||
@ -463,6 +464,41 @@ int stm32_configgpio(uint32_t cfgset)
|
|||||||
|
|
||||||
flags = enter_critical_section();
|
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 */
|
/* Now apply the configuration to the mode register */
|
||||||
|
|
||||||
regval = getreg32(base + STM32_GPIO_MODER_OFFSET);
|
regval = getreg32(base + STM32_GPIO_MODER_OFFSET);
|
||||||
@ -496,32 +532,29 @@ int stm32_configgpio(uint32_t cfgset)
|
|||||||
regval |= (setting << GPIO_PUPDR_SHIFT(pin));
|
regval |= (setting << GPIO_PUPDR_SHIFT(pin));
|
||||||
putreg32(regval, base + STM32_GPIO_PUPDR_OFFSET);
|
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;
|
if (pin < 8)
|
||||||
}
|
{
|
||||||
else
|
regoffset = STM32_GPIO_AFRL_OFFSET;
|
||||||
{
|
pos = pin;
|
||||||
setting = 0;
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
regoffset = STM32_GPIO_AFRH_OFFSET;
|
||||||
|
pos = pin - 8;
|
||||||
|
}
|
||||||
|
|
||||||
if (pin < 8)
|
regval = getreg32(base + regoffset);
|
||||||
{
|
regval &= ~GPIO_AFR_MASK(pos);
|
||||||
regoffset = STM32_GPIO_AFRL_OFFSET;
|
regval |= (alt_setting << GPIO_AFR_SHIFT(pos));
|
||||||
pos = pin;
|
putreg32(regval, base + regoffset);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
regoffset = STM32_GPIO_AFRH_OFFSET;
|
|
||||||
pos = pin - 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
regval = getreg32(base + regoffset);
|
|
||||||
regval &= ~GPIO_AFR_MASK(pos);
|
|
||||||
regval |= (setting << GPIO_AFR_SHIFT(pos));
|
|
||||||
putreg32(regval, base + regoffset);
|
|
||||||
|
|
||||||
/* Set speed (Only outputs and alternate function pins) */
|
/* Set speed (Only outputs and alternate function pins) */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user