2424 * THE SOFTWARE.
2525 */
2626
27- #include "shared-bindings/busio/I2C.h"
2827#include "py/mperrno.h"
28+ #include "py/mphal.h"
29+ #include "shared-bindings/busio/I2C.h"
2930#include "py/runtime.h"
3031
3132#include "shared-bindings/microcontroller/__init__.h"
32- #include "supervisor/ shared/translate .h"
33+ #include "shared-bindings/bitbangio/I2C .h"
3334
3435#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h"
3536
3637// Synopsys DW_apb_i2c (v2.01) IP
3738
3839#define NO_PIN 0xff
3940
41+ // One second
42+ #define BUS_TIMEOUT_US 1000000
43+
4044STATIC bool never_reset_i2c [2 ];
4145STATIC i2c_inst_t * i2c [2 ] = {i2c0 , i2c1 };
4246
@@ -94,15 +98,23 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
9498 }
9599#endif
96100
97- gpio_set_function (sda -> number , GPIO_FUNC_I2C );
98- gpio_set_function (scl -> number , GPIO_FUNC_I2C );
101+ // Create a bitbangio.I2C object to do short writes.
102+ // Must be done before setting up the I2C pins, since they will be
103+ // set up as GPIO by the bitbangio.I2C object.
104+ //
105+ // Sets pins to open drain, high, and input.
106+ shared_module_bitbangio_i2c_construct (& self -> bitbangio_i2c , scl , sda ,
107+ frequency , timeout );
99108
100109 self -> baudrate = i2c_init (self -> peripheral , frequency );
101110
102- self -> sda_pin = sda -> number ;
103111 self -> scl_pin = scl -> number ;
104- claim_pin ( sda ) ;
112+ self -> sda_pin = sda -> number ;
105113 claim_pin (scl );
114+ claim_pin (sda );
115+
116+ gpio_set_function (self -> scl_pin , GPIO_FUNC_I2C );
117+ gpio_set_function (self -> sda_pin , GPIO_FUNC_I2C );
106118}
107119
108120bool common_hal_busio_i2c_deinited (busio_i2c_obj_t * self ) {
@@ -124,8 +136,7 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
124136}
125137
126138bool common_hal_busio_i2c_probe (busio_i2c_obj_t * self , uint8_t addr ) {
127- uint8_t fake_read = 0 ;
128- return i2c_read_blocking (self -> peripheral , addr , & fake_read , 1 , false) != PICO_ERROR_GENERIC ;
139+ return common_hal_busio_i2c_write (self , addr , NULL , 0 , true) == 0 ;
129140}
130141
131142bool common_hal_busio_i2c_try_lock (busio_i2c_obj_t * self ) {
@@ -147,24 +158,56 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
147158
148159uint8_t common_hal_busio_i2c_write (busio_i2c_obj_t * self , uint16_t addr ,
149160 const uint8_t * data , size_t len , bool transmit_stop_bit ) {
150- int result = i2c_write_blocking (self -> peripheral , addr , data , len , !transmit_stop_bit );
161+ if (len <= 2 ) {
162+ // The RP2040 I2C peripheral will not do writes 2 bytes or less long.
163+ // So use bitbangio.I2C to do the write.
164+
165+ gpio_set_function (self -> scl_pin , GPIO_FUNC_SIO );
166+ gpio_set_function (self -> sda_pin , GPIO_FUNC_SIO );
167+ gpio_set_dir (self -> scl_pin , GPIO_IN );
168+ gpio_set_dir (self -> sda_pin , GPIO_IN );
169+ gpio_put (self -> scl_pin , false);
170+ gpio_put (self -> sda_pin , false);
171+
172+ uint8_t status = shared_module_bitbangio_i2c_write (& self -> bitbangio_i2c ,
173+ addr , data , len , transmit_stop_bit );
174+
175+ // The pins must be set back to GPIO_FUNC_I2C in the order given here,
176+ // SCL first, otherwise reads will hang.
177+ gpio_set_function (self -> scl_pin , GPIO_FUNC_I2C );
178+ gpio_set_function (self -> sda_pin , GPIO_FUNC_I2C );
179+
180+ return status ;
181+ }
182+
183+ int result = i2c_write_timeout_us (self -> peripheral , addr , data , len , !transmit_stop_bit , BUS_TIMEOUT_US );
151184 if (result == len ) {
152185 return 0 ;
153- } else if (result == PICO_ERROR_GENERIC ) {
154- return MP_ENODEV ;
155186 }
156- return MP_EIO ;
187+ switch (result ) {
188+ case PICO_ERROR_GENERIC :
189+ return MP_ENODEV ;
190+ case PICO_ERROR_TIMEOUT :
191+ return MP_ETIMEDOUT ;
192+ default :
193+ return MP_EIO ;
194+ }
157195}
158196
159197uint8_t common_hal_busio_i2c_read (busio_i2c_obj_t * self , uint16_t addr ,
160198 uint8_t * data , size_t len ) {
161- int result = i2c_read_blocking (self -> peripheral , addr , data , len , false);
199+ int result = i2c_read_timeout_us (self -> peripheral , addr , data , len , false, BUS_TIMEOUT_US );
162200 if (result == len ) {
163201 return 0 ;
164- } else if (result == PICO_ERROR_GENERIC ) {
165- return MP_ENODEV ;
166202 }
167- return MP_EIO ;
203+ switch (result ) {
204+ case PICO_ERROR_GENERIC :
205+ return MP_ENODEV ;
206+ case PICO_ERROR_TIMEOUT :
207+ return MP_ETIMEDOUT ;
208+ default :
209+ return MP_EIO ;
210+ }
168211}
169212
170213void common_hal_busio_i2c_never_reset (busio_i2c_obj_t * self ) {
0 commit comments