3030#include "py/runtime.h"
3131
3232#include "shared-bindings/microcontroller/__init__.h"
33+ #include "shared-bindings/microcontroller/Pin.h"
3334
34- #define NO_PIN 0xff
35+ #include "peripherals/broadcom/cpu.h"
36+ #include "peripherals/broadcom/vcmailbox.h"
3537
36- // One second
37- #define BUS_TIMEOUT_US 1000000
38+ #define NUM_I2C (2)
3839
39- STATIC bool never_reset_i2c [2 ];
40- // STATIC i2c_inst_t *i2c[2] = {i2c0, i2c1};
40+ STATIC bool never_reset_i2c [NUM_I2C ];
41+ STATIC bool in_use_i2c [NUM_I2C ];
42+ STATIC BSC0_Type * i2c [2 ] = {BSC0 , BSC1 };
4143
4244void reset_i2c (void ) {
4345 for (size_t i = 0 ; i < 2 ; i ++ ) {
4446 if (never_reset_i2c [i ]) {
4547 continue ;
4648 }
47-
49+ in_use_i2c [ i ] = false;
4850 }
4951}
5052
5153void common_hal_busio_i2c_construct (busio_i2c_obj_t * self ,
5254 const mcu_pin_obj_t * scl , const mcu_pin_obj_t * sda , uint32_t frequency , uint32_t timeout ) {
55+ size_t instance_index = NUM_I2C ;
56+ if ((scl == & pin_GPIO1 || scl == & pin_GPIO29 || scl == & pin_GPIO45 ) &&
57+ (sda == & pin_GPIO0 || sda == & pin_GPIO28 || sda == & pin_GPIO44 )) {
58+ instance_index = 0 ;
59+ } else if ((scl == & pin_GPIO44 || scl == & pin_GPIO3 ) &&
60+ (sda == & pin_GPIO43 || sda == & pin_GPIO2 )) {
61+ instance_index = 1 ;
62+ }
63+ if (instance_index == NUM_I2C ) {
64+ mp_raise_ValueError (translate ("Invalid pins" ));
65+ }
66+ in_use_i2c [instance_index ] = true;
67+ self -> index = instance_index ;
68+ self -> peripheral = i2c [self -> index ];
69+ self -> sda_pin = sda ;
70+ self -> scl_pin = scl ;
71+
72+ uint32_t source_clock = vcmailbox_get_clock_rate_measured (VCMAILBOX_CLOCK_CORE );
73+ uint16_t clock_divider = source_clock / frequency ;
74+ self -> peripheral -> DIV_b .CDIV = clock_divider ;
75+
76+ gpio_set_function (sda -> number , GPIO_GPFSEL0_FSEL2_SDA1 );
77+ gpio_set_function (scl -> number , GPIO_GPFSEL0_FSEL3_SCL1 );
5378}
5479
5580bool common_hal_busio_i2c_deinited (busio_i2c_obj_t * self ) {
56- return self -> sda_pin == NO_PIN ;
81+ return self -> sda_pin == NULL ;
5782}
5883
5984void common_hal_busio_i2c_deinit (busio_i2c_obj_t * self ) {
6085 if (common_hal_busio_i2c_deinited (self )) {
6186 return ;
6287 }
63- // never_reset_i2c[i2c_hw_index( self->peripheral) ] = false;
88+ never_reset_i2c [self -> index ] = false;
6489
65- reset_pin_number (self -> sda_pin );
66- reset_pin_number (self -> scl_pin );
67- self -> sda_pin = NO_PIN ;
68- self -> scl_pin = NO_PIN ;
90+ common_hal_reset_pin (self -> sda_pin );
91+ common_hal_reset_pin (self -> scl_pin );
92+ self -> sda_pin = NULL ;
93+ self -> scl_pin = NULL ;
6994}
7095
7196bool common_hal_busio_i2c_probe (busio_i2c_obj_t * self , uint8_t addr ) {
72- return common_hal_busio_i2c_write (self , addr , NULL , 0 , true) == 0 ;
97+ uint8_t result = common_hal_busio_i2c_write (self , addr , NULL , 0 , true);
98+ // mp_printf(&mp_plat_print, "result %d %d\n", addr, result);
99+ return result == 0 ;
73100}
74101
75102bool common_hal_busio_i2c_try_lock (busio_i2c_obj_t * self ) {
@@ -89,20 +116,111 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
89116 self -> has_lock = false;
90117}
91118
119+ // Discussion of I2C implementation is here: https://github.com/raspberrypi/linux/issues/254
120+
92121uint8_t common_hal_busio_i2c_write (busio_i2c_obj_t * self , uint16_t addr ,
93122 const uint8_t * data , size_t len , bool transmit_stop_bit ) {
123+ COMPLETE_MEMORY_READS ;
124+ self -> peripheral -> S_b .DONE = true;
125+ self -> peripheral -> A_b .ADDR = addr ;
126+ size_t loop_len = len ;
127+ // Prevent the stop bit by transmitting everything but the last byte. Doing
128+ // so is left up to the subsequent read.
129+ if (!transmit_stop_bit ) {
130+ loop_len -= 1 ;
131+ }
132+ self -> peripheral -> DLEN_b .DLEN = len ;
133+ self -> peripheral -> C = BSC0_C_ST_Msk | BSC0_C_I2CEN_Msk ;
134+ // Wait for the transaction to start.
135+ while (self -> peripheral -> S_b .TA == 0 ) {
136+ RUN_BACKGROUND_TASKS ;
137+ }
138+ for (size_t i = 0 ; i < loop_len ; i ++ ) {
139+ if (self -> peripheral -> S_b .ERR ) {
140+ break ;
141+ }
142+ self -> peripheral -> FIFO_b .DATA = data [i ];
143+ // Wait for the FIFO to empty enough that we can write more data.
144+ while (self -> peripheral -> S_b .TXE == 0 ) {
145+ RUN_BACKGROUND_TASKS ;
146+ }
147+ }
148+ // Wait for the FIFO to empty completely, not DONE, because we may not complete the
149+ // transaction with a write.
150+ while (self -> peripheral -> S_b .ERR == 0 &&
151+ ((!transmit_stop_bit && self -> peripheral -> S_b .TXE == 0 ) ||
152+ (transmit_stop_bit && self -> peripheral -> S_b .TA == 1 ))) {
153+ RUN_BACKGROUND_TASKS ;
154+ }
155+ self -> finish_write = false;
156+ if (self -> peripheral -> S_b .ERR ) {
157+ // Wait for the transfer to finish.
158+ while (self -> peripheral -> S_b .TA == 1 ) {
159+ RUN_BACKGROUND_TASKS ;
160+ }
161+ // Clear the flag by writing it and wait for it to clear.
162+ self -> peripheral -> S_b .ERR = true;
163+ while (self -> peripheral -> S_b .ERR == 1 ) {
164+ RUN_BACKGROUND_TASKS ;
165+ }
166+ return MP_ENODEV ;
167+ }
94168
95- return MP_ENODEV ;
169+ if (loop_len < len ) {
170+ self -> finish_write = true;
171+ self -> last_write_data = data [len - 1 ];
172+ }
173+ return 0 ;
96174}
97175
98176uint8_t common_hal_busio_i2c_read (busio_i2c_obj_t * self , uint16_t addr ,
99177 uint8_t * data , size_t len ) {
100- return MP_ENODEV ;
178+ COMPLETE_MEMORY_READS ;
179+ self -> peripheral -> A_b .ADDR = addr ;
180+ if (self -> finish_write ) {
181+ self -> finish_write = false;
182+ if (self -> peripheral -> S_b .ERR == 1 ) {
183+ return MP_ENODEV ;
184+ }
185+ self -> peripheral -> FIFO_b .DATA = self -> last_write_data ;
186+ } else {
187+ self -> peripheral -> S_b .DONE = true;
188+ }
189+ self -> peripheral -> DLEN_b .DLEN = len ;
190+ self -> peripheral -> C = BSC0_C_READ_Msk | BSC0_C_ST_Msk | BSC0_C_I2CEN_Msk ;
191+ // Wait for the transaction to start.
192+ while (self -> peripheral -> S_b .TA == 0 ) {
193+ RUN_BACKGROUND_TASKS ;
194+ }
195+ for (size_t i = 0 ; i < len ; i ++ ) {
196+ if (self -> peripheral -> S_b .ERR ) {
197+ break ;
198+ }
199+ // Wait for the FIFO to have enough data that we can read it. RXR is low
200+ // once the transaction is done so we check the done bit too.
201+ while (!self -> peripheral -> S_b .RXR && !self -> peripheral -> S_b .DONE ) {
202+ RUN_BACKGROUND_TASKS ;
203+ }
204+ data [i ] = self -> peripheral -> FIFO_b .DATA ;
205+ }
206+ // Wait for the transaction to finish.
207+ while (!self -> peripheral -> S_b .DONE && !self -> peripheral -> S_b .ERR ) {
208+ RUN_BACKGROUND_TASKS ;
209+ }
210+ if (self -> peripheral -> S_b .ERR ) {
211+ self -> peripheral -> S_b .ERR = true;
212+ while (self -> peripheral -> S_b .ERR == 1 ) {
213+ RUN_BACKGROUND_TASKS ;
214+ }
215+ return MP_ENODEV ;
216+ }
217+
218+ return 0 ;
101219}
102220
103221void common_hal_busio_i2c_never_reset (busio_i2c_obj_t * self ) {
104- // never_reset_i2c[i2c_hw_index( self->peripheral) ] = true;
222+ never_reset_i2c [self -> index ] = true;
105223
106- never_reset_pin_number (self -> scl_pin );
107- never_reset_pin_number (self -> sda_pin );
224+ common_hal_never_reset_pin (self -> scl_pin );
225+ common_hal_never_reset_pin (self -> sda_pin );
108226}
0 commit comments