@@ -84,8 +84,9 @@ digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output(
84
84
PADS_BANK0_GPIO0_DRIVE_BITS );
85
85
86
86
self -> output = true;
87
+ self -> open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN ;
88
+
87
89
// Pin direction is ultimately set in set_value. We don't need to do it here.
88
- common_hal_digitalio_digitalinout_set_drive_mode (self , drive_mode );
89
90
common_hal_digitalio_digitalinout_set_value (self , value );
90
91
return DIGITALINOUT_OK ;
91
92
}
@@ -98,10 +99,21 @@ digitalio_direction_t common_hal_digitalio_digitalinout_get_direction(
98
99
void common_hal_digitalio_digitalinout_set_value (
99
100
digitalio_digitalinout_obj_t * self , bool value ) {
100
101
const uint8_t pin = self -> pin -> number ;
101
- if (self -> open_drain ) {
102
- gpio_set_dir (pin , value ? GPIO_IN : GPIO_OUT );
102
+ if (value ) {
103
+ // If true, set the direction -before- setting the pin value, to
104
+ // to avoid a glitch true 3.3v on the pin before switching from output to input for open drain.
105
+ if (self -> open_drain ) {
106
+ gpio_set_dir (pin , GPIO_IN );
107
+ }
108
+ gpio_put (pin , true);
103
109
} else {
104
- gpio_put (pin , value );
110
+ // If false, set the direction -after- setting the pin value,
111
+ // to avoid a glitch 3.3v on the pin before switching from input to output for open drain,
112
+ // when previous value was high.
113
+ gpio_put (pin , false);
114
+ if (self -> open_drain ) {
115
+ gpio_set_dir (pin , GPIO_OUT );
116
+ }
105
117
}
106
118
}
107
119
0 commit comments