@@ -43,6 +43,7 @@ digitalinout_result_t common_hal_digitalio_digitalinout_construct(
43
43
self -> output = false;
44
44
self -> open_drain = false;
45
45
46
+ // Set to input. No output value.
46
47
gpio_init (pin -> number );
47
48
return DIGITALINOUT_OK ;
48
49
}
@@ -75,11 +76,17 @@ digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output(
75
76
digitalio_digitalinout_obj_t * self , bool value ,
76
77
digitalio_drive_mode_t drive_mode ) {
77
78
const uint8_t pin = self -> pin -> number ;
78
- gpio_set_dir (pin , GPIO_OUT );
79
- // TODO: Turn on "strong" pin driving (more current available).
79
+ gpio_disable_pulls (pin );
80
+
81
+ // Turn on "strong" pin driving (more current available).
82
+ hw_write_masked (& padsbank0_hw -> io [pin ],
83
+ PADS_BANK0_GPIO0_DRIVE_VALUE_12MA << PADS_BANK0_GPIO0_DRIVE_LSB ,
84
+ PADS_BANK0_GPIO0_DRIVE_BITS );
80
85
81
86
self -> output = true;
82
- common_hal_digitalio_digitalinout_set_drive_mode (self , drive_mode );
87
+ self -> open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN ;
88
+
89
+ // Pin direction is ultimately set in set_value. We don't need to do it here.
83
90
common_hal_digitalio_digitalinout_set_value (self , value );
84
91
return DIGITALINOUT_OK ;
85
92
}
@@ -92,10 +99,18 @@ digitalio_direction_t common_hal_digitalio_digitalinout_get_direction(
92
99
void common_hal_digitalio_digitalinout_set_value (
93
100
digitalio_digitalinout_obj_t * self , bool value ) {
94
101
const uint8_t pin = self -> pin -> number ;
95
- if (self -> open_drain ) {
96
- gpio_set_dir (pin , value ? GPIO_IN : GPIO_OUT );
102
+ if (self -> open_drain && value ) {
103
+ // If true and open-drain, set the direction -before- setting
104
+ // the pin value, to to avoid a high glitch on the pin before
105
+ // switching from output to input for open-drain.
106
+ gpio_set_dir (pin , GPIO_IN );
107
+ gpio_put (pin , value );
97
108
} else {
109
+ // Otherwise set the direction -after- setting the pin value,
110
+ // to avoid a glitch which might occur if the old value was
111
+ // different and the pin was previously set to input.
98
112
gpio_put (pin , value );
113
+ gpio_set_dir (pin , GPIO_OUT );
99
114
}
100
115
}
101
116
@@ -110,9 +125,6 @@ digitalinout_result_t common_hal_digitalio_digitalinout_set_drive_mode(
110
125
const uint8_t pin = self -> pin -> number ;
111
126
bool value = common_hal_digitalio_digitalinout_get_value (self );
112
127
self -> open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN ;
113
- if (self -> open_drain ) {
114
- gpio_put (pin , false);
115
- }
116
128
// True is implemented differently between modes so reset the value to make
117
129
// sure it's correct for the new mode.
118
130
if (value ) {
0 commit comments