|
1 | 1 | /* |
2 | | - * Copyright (c) 2014-2018 Thomas Roell. All rights reserved. |
| 2 | + * Copyright (c) 2014-2019 Thomas Roell. All rights reserved. |
3 | 3 | * |
4 | 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
5 | 5 | * of this software and associated documentation files (the "Software"), to |
@@ -103,37 +103,52 @@ void stm32l0_gpio_pin_configure(unsigned int pin, unsigned int mode) |
103 | 103 | RCC->IOPENR |= (RCC_IOPENR_IOPAEN << group); |
104 | 104 | RCC->IOPENR; |
105 | 105 |
|
106 | | - /* First switch the pin back to analog mode */ |
107 | | - GPIO->MODER |= (0x00000003 << (index << 1)); |
108 | | - |
109 | | - /* Set OPTYPER */ |
110 | | - GPIO->OTYPER = (GPIO->OTYPER & ~(0x00000001 << index)) | (((mode & STM32L0_GPIO_OTYPE_MASK) >> STM32L0_GPIO_OTYPE_SHIFT) << index); |
111 | | - |
112 | | - /* Set OPSPEEDR */ |
113 | | - GPIO->OSPEEDR = (GPIO->OSPEEDR & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_OSPEED_MASK) >> STM32L0_GPIO_OSPEED_SHIFT) << (index << 1)); |
114 | | - |
115 | | - /* Set PUPD */ |
116 | | - GPIO->PUPDR = (GPIO->PUPDR & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_PUPD_MASK) >> STM32L0_GPIO_PUPD_SHIFT) << (index << 1)); |
117 | | - |
118 | | - /* Set AFRL/AFRH */ |
119 | | - GPIO->AFR[index >> 3] = (GPIO->AFR[index >> 3] & ~(0x0000000f << ((index & 7) << 2))) | (afsel << ((index & 7) << 2)); |
120 | | - |
121 | | - GPIO->MODER = (GPIO->MODER & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_MODE_MASK) >> STM32L0_GPIO_MODE_SHIFT) << (index << 1)); |
122 | | - |
123 | | - // if ((((mode & STM32L0_GPIO_MODE_MASK) >> STM32L0_GPIO_MODE_SHIFT) == STM32L0_GPIO_MODE_INPUT) || (((mode & STM32L0_GPIO_MODE_MASK) >> STM32L0_GPIO_MODE_SHIFT) == STM32L0_GPIO_MODE_OUTPUT)) |
124 | | - if (((mode & STM32L0_GPIO_MODE_MASK) >> STM32L0_GPIO_MODE_SHIFT) != STM32L0_GPIO_MODE_ANALOG) |
125 | | - { |
126 | | - stm32l0_gpio_device.enables[port] |= (1 << index); |
127 | | - } |
128 | | - else |
| 106 | + /* If the mode is ANALOG, set MODER first */ |
| 107 | + if (((mode & STM32L0_GPIO_MODE_MASK) >> STM32L0_GPIO_MODE_SHIFT) == STM32L0_GPIO_MODE_ANALOG) |
129 | 108 | { |
| 109 | + GPIO->MODER |= (0x00000003 << (index << 1)); |
| 110 | + |
130 | 111 | stm32l0_gpio_device.enables[port] &= ~(1 << index); |
131 | 112 |
|
132 | 113 | if (!stm32l0_gpio_device.enables[port]) |
133 | 114 | { |
134 | 115 | RCC->IOPENR &= ~(RCC_IOPENR_IOPAEN << group); |
135 | 116 | } |
136 | 117 | } |
| 118 | + else |
| 119 | + { |
| 120 | + /* Set AFRL/AFRH */ |
| 121 | + GPIO->AFR[index >> 3] = (GPIO->AFR[index >> 3] & ~(0x0000000f << ((index & 7) << 2))) | (afsel << ((index & 7) << 2)); |
| 122 | + |
| 123 | + /* Set OPSPEEDR */ |
| 124 | + GPIO->OSPEEDR = (GPIO->OSPEEDR & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_OSPEED_MASK) >> STM32L0_GPIO_OSPEED_SHIFT) << (index << 1)); |
| 125 | + |
| 126 | + /* Set OPTYPER */ |
| 127 | + GPIO->OTYPER = (GPIO->OTYPER & ~(0x00000001 << index)) | (((mode & STM32L0_GPIO_OTYPE_MASK) >> STM32L0_GPIO_OTYPE_SHIFT) << index); |
| 128 | + |
| 129 | + /* If the mode is OUTPUT, or OUTPUT OPENDRAIN with a ODR of 0. then first switch MODER and then PUPDR |
| 130 | + * to avoid spurious edges. N.b. ALTERNATE is assumed to be INPUT before the peripheral drives it. |
| 131 | + */ |
| 132 | + if (((mode & STM32L0_GPIO_MODE_MASK) == STM32L0_GPIO_MODE_OUTPUT) && |
| 133 | + (((mode & STM32L0_GPIO_OTYPE_MASK) != STM32L0_GPIO_OTYPE_OPENDRAIN) || !(GPIO->ODR & (0x00000001 << index)))) |
| 134 | + { |
| 135 | + /* Set MODE */ |
| 136 | + GPIO->MODER = (GPIO->MODER & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_MODE_MASK) >> STM32L0_GPIO_MODE_SHIFT) << (index << 1)); |
| 137 | + |
| 138 | + /* Set PUPD */ |
| 139 | + GPIO->PUPDR = (GPIO->PUPDR & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_PUPD_MASK) >> STM32L0_GPIO_PUPD_SHIFT) << (index << 1)); |
| 140 | + } |
| 141 | + else |
| 142 | + { |
| 143 | + /* Set PUPD */ |
| 144 | + GPIO->PUPDR = (GPIO->PUPDR & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_PUPD_MASK) >> STM32L0_GPIO_PUPD_SHIFT) << (index << 1)); |
| 145 | + |
| 146 | + /* Set MODE */ |
| 147 | + GPIO->MODER = (GPIO->MODER & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_MODE_MASK) >> STM32L0_GPIO_MODE_SHIFT) << (index << 1)); |
| 148 | + } |
| 149 | + |
| 150 | + stm32l0_gpio_device.enables[port] |= (1 << index); |
| 151 | + } |
137 | 152 |
|
138 | 153 | stm32l0_gpio_device.mode[port] &= ~(0x00000003 << (index << 1)); |
139 | 154 | stm32l0_gpio_device.pupd[port] &= ~(0x00000003 << (index << 1)); |
|
0 commit comments