3838
3939#define GPIO_MODE_INPUT (0)
4040#define GPIO_MODE_OUTPUT (1)
41+ #define GPIO_MODE_OPEN_DRAIN (2) // synthesised
4142#define GPIO_PULL_NONE (0)
4243#define GPIO_PULL_UP (1)
4344// Removed in SDK 1.1.0
@@ -66,6 +67,42 @@ STATIC const pyb_pin_obj_t pyb_pin_obj[] = {
6667 {{& pyb_pin_type }, 15 , 15 , PERIPHS_IO_MUX_MTDO_U , FUNC_GPIO15 },
6768};
6869
70+ STATIC uint8_t pin_mode [16 ];
71+
72+ STATIC void pin_set (uint pin , uint mode , int value ) {
73+ uint32_t enable = 0 ;
74+ uint32_t disable = 0 ;
75+ switch (mode ) {
76+ case GPIO_MODE_INPUT :
77+ value = -1 ;
78+ disable = 1 ;
79+ break ;
80+
81+ case GPIO_MODE_OUTPUT :
82+ enable = 1 ;
83+ break ;
84+
85+ case GPIO_MODE_OPEN_DRAIN :
86+ if (value == -1 ) {
87+ return ;
88+ } else if (value == 0 ) {
89+ enable = 1 ;
90+ } else {
91+ value = -1 ;
92+ disable = 1 ;
93+ }
94+ break ;
95+ }
96+
97+ enable <<= pin ;
98+ disable <<= pin ;
99+ if (value == -1 ) {
100+ gpio_output_set (0 , 0 , enable , disable );
101+ } else {
102+ gpio_output_set (value << pin , (1 - value ) << pin , enable , disable );
103+ }
104+ }
105+
69106STATIC void pyb_pin_print (const mp_print_t * print , mp_obj_t self_in , mp_print_kind_t kind ) {
70107 pyb_pin_obj_t * self = self_in ;
71108
@@ -77,18 +114,33 @@ STATIC void pyb_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki
77114STATIC mp_obj_t pyb_pin_obj_init_helper (pyb_pin_obj_t * self , mp_uint_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
78115 static const mp_arg_t allowed_args [] = {
79116 { MP_QSTR_mode , MP_ARG_REQUIRED | MP_ARG_INT },
80- { MP_QSTR_pull , MP_ARG_INT , {.u_int = GPIO_PULL_NONE }},
117+ { MP_QSTR_pull , MP_ARG_INT , {.u_int = GPIO_PULL_NONE }},
118+ { MP_QSTR_value , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL }},
81119 };
82120
83121 // parse args
84- mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
85- mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
122+ struct {
123+ mp_arg_val_t mode , pull , value ;
124+ } args ;
125+ mp_arg_parse_all (n_args , pos_args , kw_args ,
126+ MP_ARRAY_SIZE (allowed_args ), allowed_args , (mp_arg_val_t * )& args );
86127
87128 // get io mode
88- uint mode = args [ 0 ] .u_int ;
129+ uint mode = args . mode .u_int ;
89130
90131 // get pull mode
91- uint pull = args [1 ].u_int ;
132+ uint pull = args .pull .u_int ;
133+
134+ // get initial value
135+ int value ;
136+ if (args .value .u_obj == MP_OBJ_NULL ) {
137+ value = -1 ;
138+ } else {
139+ value = mp_obj_is_true (args .value .u_obj );
140+ }
141+
142+ // save the mode
143+ pin_mode [self -> phys_port ] = mode ;
92144
93145 // configure the GPIO as requested
94146 PIN_FUNC_SELECT (self -> periph , self -> func );
@@ -110,10 +162,7 @@ STATIC mp_obj_t pyb_pin_obj_init_helper(pyb_pin_obj_t *self, mp_uint_t n_args, c
110162 PIN_PULLUP_EN (self -> periph );
111163 }
112164
113- // TODO input mode is not working...
114- if ((mode & GPIO_MODE_OUTPUT ) == 0 ) {
115- GPIO_DIS_OUTPUT (self -> phys_port );
116- }
165+ pin_set (self -> phys_port , mode , value );
117166
118167 return mp_const_none ;
119168}
@@ -145,6 +194,20 @@ STATIC mp_obj_t pyb_pin_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp
145194 return (mp_obj_t )pin ;
146195}
147196
197+ // fast method for getting/setting pin value
198+ STATIC mp_obj_t pyb_pin_call (mp_obj_t self_in , mp_uint_t n_args , mp_uint_t n_kw , const mp_obj_t * args ) {
199+ mp_arg_check_num (n_args , n_kw , 0 , 1 , false);
200+ pyb_pin_obj_t * self = self_in ;
201+ if (n_args == 0 ) {
202+ // get pin
203+ return MP_OBJ_NEW_SMALL_INT (GPIO_INPUT_GET (self -> phys_port ));
204+ } else {
205+ // set pin
206+ pin_set (self -> phys_port , pin_mode [self -> phys_port ], mp_obj_is_true (args [0 ]));
207+ return mp_const_none ;
208+ }
209+ }
210+
148211// pin.init(mode, pull)
149212STATIC mp_obj_t pyb_pin_obj_init (mp_uint_t n_args , const mp_obj_t * args , mp_map_t * kw_args ) {
150213 return pyb_pin_obj_init_helper (args [0 ], n_args - 1 , args + 1 , kw_args );
@@ -153,34 +216,22 @@ MP_DEFINE_CONST_FUN_OBJ_KW(pyb_pin_init_obj, 1, pyb_pin_obj_init);
153216
154217// pin.value([value])
155218STATIC mp_obj_t pyb_pin_value (mp_uint_t n_args , const mp_obj_t * args ) {
156- pyb_pin_obj_t * self = args [0 ];
157- if (n_args == 1 ) {
158- // get pin
159- return MP_OBJ_NEW_SMALL_INT (GPIO_INPUT_GET (self -> phys_port ));
160- } else {
161- // set pin
162- if (mp_obj_is_true (args [1 ])) {
163- GPIO_OUTPUT_SET (self -> phys_port , 1 );
164- } else {
165- GPIO_OUTPUT_SET (self -> phys_port , 0 );
166- }
167- return mp_const_none ;
168- }
219+ return pyb_pin_call (args [0 ], n_args - 1 , 0 , args + 1 );
169220}
170221STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (pyb_pin_value_obj , 1 , 2 , pyb_pin_value );
171222
172223// pin.low()
173224STATIC mp_obj_t pyb_pin_low (mp_obj_t self_in ) {
174225 pyb_pin_obj_t * self = self_in ;
175- GPIO_OUTPUT_SET (self -> phys_port , 0 );
226+ pin_set (self -> phys_port , pin_mode [ self -> phys_port ] , 0 );
176227 return mp_const_none ;
177228}
178229STATIC MP_DEFINE_CONST_FUN_OBJ_1 (pyb_pin_low_obj , pyb_pin_low );
179230
180231// pin.high()
181232STATIC mp_obj_t pyb_pin_high (mp_obj_t self_in ) {
182233 pyb_pin_obj_t * self = self_in ;
183- GPIO_OUTPUT_SET (self -> phys_port , 1 );
234+ pin_set (self -> phys_port , pin_mode [ self -> phys_port ] , 1 );
184235 return mp_const_none ;
185236}
186237STATIC MP_DEFINE_CONST_FUN_OBJ_1 (pyb_pin_high_obj , pyb_pin_high );
@@ -194,7 +245,8 @@ STATIC const mp_map_elem_t pyb_pin_locals_dict_table[] = {
194245
195246 // class constants
196247 { MP_OBJ_NEW_QSTR (MP_QSTR_IN ), MP_OBJ_NEW_SMALL_INT (GPIO_MODE_INPUT ) },
197- { MP_OBJ_NEW_QSTR (MP_QSTR_OUT_PP ), MP_OBJ_NEW_SMALL_INT (GPIO_MODE_OUTPUT ) },
248+ { MP_OBJ_NEW_QSTR (MP_QSTR_OUT ), MP_OBJ_NEW_SMALL_INT (GPIO_MODE_OUTPUT ) },
249+ { MP_OBJ_NEW_QSTR (MP_QSTR_OPEN_DRAIN ), MP_OBJ_NEW_SMALL_INT (GPIO_MODE_OPEN_DRAIN ) },
198250 { MP_OBJ_NEW_QSTR (MP_QSTR_PULL_NONE ), MP_OBJ_NEW_SMALL_INT (GPIO_PULL_NONE ) },
199251 { MP_OBJ_NEW_QSTR (MP_QSTR_PULL_UP ), MP_OBJ_NEW_SMALL_INT (GPIO_PULL_UP ) },
200252 //{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_DOWN), MP_OBJ_NEW_SMALL_INT(GPIO_PULL_DOWN) },
@@ -207,5 +259,6 @@ const mp_obj_type_t pyb_pin_type = {
207259 .name = MP_QSTR_Pin ,
208260 .print = pyb_pin_print ,
209261 .make_new = pyb_pin_make_new ,
262+ .call = pyb_pin_call ,
210263 .locals_dict = (mp_obj_t )& pyb_pin_locals_dict ,
211264};
0 commit comments