mirror of https://github.com/ARMmbed/mbed-os.git
[STM32] Fix pull over write to all families
This applies the same fix as was done for F4 to solve issue #2638. The fix applies ell to all other families excpet STM32F1. Basically, to avoid over-writing the pull-up/-down settings, we read the current state from HW.pull/3056/head
parent
9976738882
commit
af51027f61
|
@ -127,6 +127,7 @@ static void gpio_irq2(void) {
|
|||
}
|
||||
|
||||
extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
|
||||
extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode);
|
||||
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
|
||||
IRQn_Type irq_n = (IRQn_Type)0;
|
||||
|
@ -196,8 +197,8 @@ void gpio_irq_free(gpio_irq_t *obj) {
|
|||
gpio_channel->channel_gpio[gpio_idx] = 0;
|
||||
gpio_channel->channel_pin[gpio_idx] = 0;
|
||||
|
||||
// Disable EXTI line
|
||||
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
|
||||
// Disable EXTI line, but don't change pull-up config
|
||||
pin_function_gpiomode(obj->pin, STM_MODE_INPUT);
|
||||
obj->event = EDGE_NONE;
|
||||
}
|
||||
|
||||
|
@ -245,7 +246,7 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
|
|||
}
|
||||
}
|
||||
|
||||
pin_function(obj->pin, STM_PIN_DATA(mode, pull, 0));
|
||||
pin_function_gpiomode(obj->pin, mode);
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_irq_t *obj) {
|
||||
|
|
|
@ -138,5 +138,20 @@ void pin_mode(PinName pin, PinMode mode) {
|
|||
if (pupd > 2) pupd = 0; // Open-drain = No pull-up/No pull-down
|
||||
gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2)));
|
||||
gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2));
|
||||
|
||||
}
|
||||
|
||||
/* Internal function for setting the gpiomode/function
|
||||
* without changing Pull mode
|
||||
*/
|
||||
void pin_function_gpiomode(PinName pin, uint32_t gpiomode) {
|
||||
|
||||
/* Read current pull state from HW to avoid over-write*/
|
||||
uint32_t port_index = STM_PORT(pin);
|
||||
uint32_t pin_index = STM_PIN(pin);
|
||||
GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index);
|
||||
uint32_t temp = gpio->PUPDR;
|
||||
uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPDR0;
|
||||
|
||||
/* Then re-use global function for updating the mode part*/
|
||||
pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0));
|
||||
}
|
||||
|
|
|
@ -163,6 +163,7 @@ static void gpio_irq6(void)
|
|||
}
|
||||
|
||||
extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
|
||||
extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode);
|
||||
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
|
||||
{
|
||||
|
@ -267,15 +268,14 @@ void gpio_irq_free(gpio_irq_t *obj)
|
|||
gpio_channel->channel_gpio[gpio_idx] = 0;
|
||||
gpio_channel->channel_pin[gpio_idx] = 0;
|
||||
|
||||
// Disable EXTI line
|
||||
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
|
||||
// Disable EXTI line, but don't change pull-up config
|
||||
pin_function_gpiomode(obj->pin, STM_MODE_INPUT);
|
||||
obj->event = EDGE_NONE;
|
||||
}
|
||||
|
||||
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
||||
{
|
||||
uint32_t mode = STM_MODE_IT_EVT_RESET;
|
||||
uint32_t pull = GPIO_NOPULL;
|
||||
|
||||
if (enable) {
|
||||
if (event == IRQ_RISE) {
|
||||
|
@ -317,7 +317,7 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
|||
}
|
||||
}
|
||||
|
||||
pin_function(obj->pin, STM_PIN_DATA(mode, pull, 0));
|
||||
pin_function_gpiomode(obj->pin, mode);
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_irq_t *obj)
|
||||
|
|
|
@ -178,5 +178,20 @@ void pin_mode(PinName pin, PinMode mode)
|
|||
}
|
||||
gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2)));
|
||||
gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2));
|
||||
|
||||
}
|
||||
|
||||
/* Internal function for setting the gpiomode/function
|
||||
* without changing Pull mode
|
||||
*/
|
||||
void pin_function_gpiomode(PinName pin, uint32_t gpiomode) {
|
||||
|
||||
/* Read current pull state from HW to avoid over-write*/
|
||||
uint32_t port_index = STM_PORT(pin);
|
||||
uint32_t pin_index = STM_PIN(pin);
|
||||
GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index);
|
||||
uint32_t temp = gpio->PUPDR;
|
||||
uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPDR0;
|
||||
|
||||
/* Then re-use global function for updating the mode part*/
|
||||
pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0));
|
||||
}
|
||||
|
|
|
@ -163,6 +163,7 @@ static void gpio_irq6(void)
|
|||
}
|
||||
|
||||
extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
|
||||
extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode);
|
||||
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
|
||||
{
|
||||
|
@ -267,15 +268,14 @@ void gpio_irq_free(gpio_irq_t *obj)
|
|||
gpio_channel->channel_gpio[gpio_idx] = 0;
|
||||
gpio_channel->channel_pin[gpio_idx] = 0;
|
||||
|
||||
// Disable EXTI line
|
||||
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
|
||||
// Disable EXTI line, but don't change pull-up config
|
||||
pin_function_gpiomode(obj->pin, STM_MODE_INPUT);
|
||||
obj->event = EDGE_NONE;
|
||||
}
|
||||
|
||||
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
||||
{
|
||||
uint32_t mode = STM_MODE_IT_EVT_RESET;
|
||||
uint32_t pull = GPIO_NOPULL;
|
||||
|
||||
if (enable) {
|
||||
if (event == IRQ_RISE) {
|
||||
|
@ -317,7 +317,7 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
|||
}
|
||||
}
|
||||
|
||||
pin_function(obj->pin, STM_PIN_DATA(mode, pull, 0));
|
||||
pin_function_gpiomode(obj->pin, mode);
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_irq_t *obj)
|
||||
|
|
|
@ -177,3 +177,19 @@ void pin_mode(PinName pin, PinMode mode)
|
|||
gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2)));
|
||||
gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2));
|
||||
}
|
||||
|
||||
/* Internal function for setting the gpiomode/function
|
||||
* without changing Pull mode
|
||||
*/
|
||||
void pin_function_gpiomode(PinName pin, uint32_t gpiomode) {
|
||||
|
||||
/* Read current pull state from HW to avoid over-write*/
|
||||
uint32_t port_index = STM_PORT(pin);
|
||||
uint32_t pin_index = STM_PIN(pin);
|
||||
GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index);
|
||||
uint32_t temp = gpio->PUPDR;
|
||||
uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPDR0;
|
||||
|
||||
/* Then re-use global function for updating the mode part*/
|
||||
pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0));
|
||||
}
|
||||
|
|
|
@ -163,6 +163,7 @@ static void gpio_irq6(void)
|
|||
}
|
||||
|
||||
extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
|
||||
extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode);
|
||||
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
|
||||
{
|
||||
|
@ -267,15 +268,14 @@ void gpio_irq_free(gpio_irq_t *obj)
|
|||
gpio_channel->channel_gpio[gpio_idx] = 0;
|
||||
gpio_channel->channel_pin[gpio_idx] = 0;
|
||||
|
||||
// Disable EXTI line
|
||||
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
|
||||
// Disable EXTI line, but don't change pull-up config
|
||||
pin_function_gpiomode(obj->pin, STM_MODE_INPUT);
|
||||
obj->event = EDGE_NONE;
|
||||
}
|
||||
|
||||
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
||||
{
|
||||
uint32_t mode = STM_MODE_IT_EVT_RESET;
|
||||
uint32_t pull = GPIO_NOPULL;
|
||||
|
||||
if (enable) {
|
||||
if (event == IRQ_RISE) {
|
||||
|
@ -317,7 +317,7 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
|||
}
|
||||
}
|
||||
|
||||
pin_function(obj->pin, STM_PIN_DATA(mode, pull, 0));
|
||||
pin_function_gpiomode(obj->pin, mode);
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_irq_t *obj)
|
||||
|
|
|
@ -177,5 +177,20 @@ void pin_mode(PinName pin, PinMode mode)
|
|||
pupd = 0; // Open-drain = No pull-up/No pull-down
|
||||
gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2)));
|
||||
gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2));
|
||||
|
||||
}
|
||||
|
||||
/* Internal function for setting the gpiomode/function
|
||||
* without changing Pull mode
|
||||
*/
|
||||
void pin_function_gpiomode(PinName pin, uint32_t gpiomode) {
|
||||
|
||||
/* Read current pull state from HW to avoid over-write*/
|
||||
uint32_t port_index = STM_PORT(pin);
|
||||
uint32_t pin_index = STM_PIN(pin);
|
||||
GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index);
|
||||
uint32_t temp = gpio->PUPDR;
|
||||
uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPDR0;
|
||||
|
||||
/* Then re-use global function for updating the mode part*/
|
||||
pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0));
|
||||
}
|
||||
|
|
|
@ -131,6 +131,7 @@ static void gpio_irq2(void)
|
|||
}
|
||||
|
||||
extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
|
||||
extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode);
|
||||
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
|
||||
{
|
||||
|
@ -202,15 +203,14 @@ void gpio_irq_free(gpio_irq_t *obj)
|
|||
gpio_channel->channel_gpio[gpio_idx] = 0;
|
||||
gpio_channel->channel_pin[gpio_idx] = 0;
|
||||
|
||||
// Disable EXTI line
|
||||
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
|
||||
// Disable EXTI line, but don't change pull-up config
|
||||
pin_function_gpiomode(obj->pin, STM_MODE_INPUT);
|
||||
obj->event = EDGE_NONE;
|
||||
}
|
||||
|
||||
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
||||
{
|
||||
uint32_t mode = STM_MODE_IT_EVT_RESET;
|
||||
uint32_t pull = GPIO_NOPULL;
|
||||
|
||||
if (enable) {
|
||||
if (event == IRQ_RISE) {
|
||||
|
@ -252,7 +252,7 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
|||
}
|
||||
}
|
||||
|
||||
pin_function(obj->pin, STM_PIN_DATA(mode, pull, 0));
|
||||
pin_function_gpiomode(obj->pin, mode);
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_irq_t *obj)
|
||||
|
|
|
@ -146,5 +146,20 @@ void pin_mode(PinName pin, PinMode mode)
|
|||
}
|
||||
gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPD0 << (pin_index * 2)));
|
||||
gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2));
|
||||
|
||||
}
|
||||
|
||||
/* Internal function for setting the gpiomode/function
|
||||
* without changing Pull mode
|
||||
*/
|
||||
void pin_function_gpiomode(PinName pin, uint32_t gpiomode) {
|
||||
|
||||
/* Read current pull state from HW to avoid over-write*/
|
||||
uint32_t port_index = STM_PORT(pin);
|
||||
uint32_t pin_index = STM_PIN(pin);
|
||||
GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index);
|
||||
uint32_t temp = gpio->PUPDR;
|
||||
uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPD0;
|
||||
|
||||
/* Then re-use global function for updating the mode part*/
|
||||
pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0));
|
||||
}
|
||||
|
|
|
@ -163,6 +163,7 @@ static void gpio_irq6(void)
|
|||
}
|
||||
|
||||
extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
|
||||
extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode);
|
||||
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
|
||||
{
|
||||
|
@ -267,15 +268,14 @@ void gpio_irq_free(gpio_irq_t *obj)
|
|||
gpio_channel->channel_gpio[gpio_idx] = 0;
|
||||
gpio_channel->channel_pin[gpio_idx] = 0;
|
||||
|
||||
// Disable EXTI line
|
||||
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
|
||||
// Disable EXTI line, but don't change pull-up config
|
||||
pin_function_gpiomode(obj->pin, STM_MODE_INPUT);
|
||||
obj->event = EDGE_NONE;
|
||||
}
|
||||
|
||||
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
||||
{
|
||||
uint32_t mode = STM_MODE_IT_EVT_RESET;
|
||||
uint32_t pull = GPIO_NOPULL;
|
||||
|
||||
if (enable) {
|
||||
if (event == IRQ_RISE) {
|
||||
|
@ -317,7 +317,7 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
|||
}
|
||||
}
|
||||
|
||||
pin_function(obj->pin, STM_PIN_DATA(mode, pull, 0));
|
||||
pin_function_gpiomode(obj->pin, mode);
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_irq_t *obj)
|
||||
|
|
|
@ -139,5 +139,20 @@ void pin_mode(PinName pin, PinMode mode)
|
|||
}
|
||||
gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2)));
|
||||
gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2));
|
||||
|
||||
}
|
||||
|
||||
/* Internal function for setting the gpiomode/function
|
||||
* without changing Pull mode
|
||||
*/
|
||||
void pin_function_gpiomode(PinName pin, uint32_t gpiomode) {
|
||||
|
||||
/* Read current pull state from HW to avoid over-write*/
|
||||
uint32_t port_index = STM_PORT(pin);
|
||||
uint32_t pin_index = STM_PIN(pin);
|
||||
GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index);
|
||||
uint32_t temp = gpio->PUPDR;
|
||||
uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPDR0;
|
||||
|
||||
/* Then re-use global function for updating the mode part*/
|
||||
pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0));
|
||||
}
|
||||
|
|
|
@ -163,6 +163,7 @@ static void gpio_irq6(void)
|
|||
}
|
||||
|
||||
extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
|
||||
extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode);
|
||||
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
|
||||
{
|
||||
|
@ -267,15 +268,14 @@ void gpio_irq_free(gpio_irq_t *obj)
|
|||
gpio_channel->channel_gpio[gpio_idx] = 0;
|
||||
gpio_channel->channel_pin[gpio_idx] = 0;
|
||||
|
||||
// Disable EXTI line
|
||||
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
|
||||
// Disable EXTI line, but don't change pull-up config
|
||||
pin_function_gpiomode(obj->pin, STM_MODE_INPUT);
|
||||
obj->event = EDGE_NONE;
|
||||
}
|
||||
|
||||
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
||||
{
|
||||
uint32_t mode = STM_MODE_IT_EVT_RESET;
|
||||
uint32_t pull = GPIO_NOPULL;
|
||||
|
||||
if (enable) {
|
||||
if (event == IRQ_RISE) {
|
||||
|
@ -317,7 +317,7 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
|||
}
|
||||
}
|
||||
|
||||
pin_function(obj->pin, STM_PIN_DATA(mode, pull, 0));
|
||||
pin_function_gpiomode(obj->pin, mode);
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_irq_t *obj)
|
||||
|
|
|
@ -149,3 +149,19 @@ void pin_mode(PinName pin, PinMode mode)
|
|||
gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2)));
|
||||
gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2));
|
||||
}
|
||||
|
||||
/* Internal function for setting the gpiomode/function
|
||||
* without changing Pull mode
|
||||
*/
|
||||
void pin_function_gpiomode(PinName pin, uint32_t gpiomode) {
|
||||
|
||||
/* Read current pull state from HW to avoid over-write*/
|
||||
uint32_t port_index = STM_PORT(pin);
|
||||
uint32_t pin_index = STM_PIN(pin);
|
||||
GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index);
|
||||
uint32_t temp = gpio->PUPDR;
|
||||
uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPDR0;
|
||||
|
||||
/* Then re-use global function for updating the mode part*/
|
||||
pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue