@@ -162,10 +162,19 @@ void pin_mode(PinName pin, PinMode mode)
162
162
163
163
uint32_t port_index = STM_PORT (pin );
164
164
uint32_t pin_index = STM_PIN (pin );
165
-
166
165
// Enable GPIO clock
167
166
uint32_t gpio_add = Set_GPIO_Clock (port_index );
168
167
GPIO_TypeDef * gpio = (GPIO_TypeDef * )gpio_add ;
168
+ __IO uint32_t * gpio_reg_hl ;//gpio register depends on bit index (high or low)
169
+ uint32_t shift ;
170
+
171
+ if (pin_index < 8 ) {
172
+ shift = (pin_index * 4 );
173
+ gpio_reg_hl = & (gpio -> CRL );
174
+ } else {
175
+ shift = (pin_index % 8 ) * 4 ;
176
+ gpio_reg_hl = & (gpio -> CRH );
177
+ }
169
178
170
179
// Configure open-drain and pull-up/down
171
180
switch (mode ) {
@@ -174,16 +183,9 @@ void pin_mode(PinName pin, PinMode mode)
174
183
case PullUp :
175
184
case PullDown :
176
185
// Set pull-up / pull-down for Input mode
177
- if (pin_index < 8 ) {
178
- if ((gpio -> CRL & (0x03 << (pin_index * 4 ))) == 0 ) { // MODE bits = Input mode
179
- gpio -> CRL |= (0x08 << (pin_index * 4 )); // Set pull-up / pull-down
180
- gpio -> CRL &= ~(0x04 << (pin_index * 4 )); // ENSURES GPIOx_CRL.CNFx.bit0 = 0
181
- }
182
- } else {
183
- if ((gpio -> CRH & (0x03 << ((pin_index % 8 ) * 4 ))) == 0 ) { // MODE bits = Input mode
184
- gpio -> CRH |= (0x08 << ((pin_index % 8 ) * 4 )); // Set pull-up / pull-down
185
- gpio -> CRH &= ~(0x04 << ((pin_index % 8 ) * 4 )); // ENSURES GPIOx_CRH.CNFx.bit0 = 0
186
- }
186
+ if ((* gpio_reg_hl & (0x03 << shift )) == 0 ) { // MODE bits = Input mode
187
+ * gpio_reg_hl |= (0x08 << shift ); // Set pull-up / pull-down
188
+ * gpio_reg_hl &= ~(0x04 << shift ); // ENSURES GPIOx_CRL.CNFx.bit0 = 0
187
189
}
188
190
// Now it's time to setup properly if pullup or pulldown. This is done in ODR register:
189
191
// set pull-up => bit=1, set pull-down => bit = 0
@@ -195,17 +197,51 @@ void pin_mode(PinName pin, PinMode mode)
195
197
break ;
196
198
case OpenDrain :
197
199
// Set open-drain for Output mode (General Purpose or Alternate Function)
198
- if (pin_index < 8 ) {
199
- if ((gpio -> CRL & (0x03 << (pin_index * 4 ))) > 0 ) { // MODE bits = Output mode
200
- gpio -> CRL |= (0x04 << (pin_index * 4 )); // Set open-drain
201
- }
202
- } else {
203
- if ((gpio -> CRH & (0x03 << ((pin_index % 8 ) * 4 ))) > 0 ) { // MODE bits = Output mode
204
- gpio -> CRH |= (0x04 << ((pin_index % 8 ) * 4 )); // Set open-drain
205
- }
200
+ if ((* gpio_reg_hl & (0x03 << shift )) > 0 ) { // MODE bits = Output mode
201
+ * gpio_reg_hl |= (0x04 << shift ); // Set open-drain
206
202
}
207
203
break ;
208
204
default :
209
205
break ;
210
206
}
211
207
}
208
+
209
+ /* Internal function for setting the gpiomode/function
210
+ * without changing Pull mode
211
+ */
212
+ void pin_function_gpiomode (PinName pin , uint32_t gpiomode ) {
213
+
214
+ /* Read current pull state from HW to avoid over-write*/
215
+ uint32_t port_index = STM_PORT (pin );
216
+ uint32_t pin_index = STM_PIN (pin );
217
+ GPIO_TypeDef * gpio = (GPIO_TypeDef * ) Set_GPIO_Clock (port_index );
218
+ uint32_t pull = PullNone ;
219
+ __IO uint32_t * gpio_reg_hl ;//gpio register depends on bit index (high or low)
220
+ uint32_t shift ;
221
+
222
+ if (pin_index < 8 ) {
223
+ shift = (pin_index * 4 );
224
+ gpio_reg_hl = & (gpio -> CRL );
225
+ } else {
226
+ shift = (pin_index % 8 ) * 4 ;
227
+ gpio_reg_hl = & (gpio -> CRH );
228
+ }
229
+
230
+ /* Check if pull/pull down is active */
231
+ if ((!(* gpio_reg_hl & (0x03 << shift ))) // input
232
+ && (!!(* gpio_reg_hl & (0x08 << shift ))) // pull-up / down
233
+ && (!(* gpio_reg_hl & (0x04 << shift )))) { // GPIOx_CRL.CNFx.bit0 = 0
234
+ if (!!(gpio -> ODR & (0x01 << pin_index ))) {
235
+ pull = PullUp ;
236
+ } else {
237
+ pull = PullDown ;
238
+ }
239
+ } else { //output
240
+ if (!!(* gpio_reg_hl & (0x04 << shift ))) { //open drain
241
+ pull = OpenDrain ;
242
+ }
243
+ }
244
+
245
+ /* Then re-use global function for updating the mode part*/
246
+ pin_function (pin , STM_PIN_DATA (gpiomode , pull , 0 ));
247
+ }
0 commit comments