2727
2828#include <stdio.h>
2929
30+ #include "shared-bindings/microcontroller/Pin.h"
31+ #include "shared-bindings/microcontroller/__init__.h"
3032#include "shared-bindings/busio/I2C.h"
3133#include "py/mperrno.h"
3234#include "py/runtime.h"
3335#include "periph.h"
3436
3537#include "fsl_lpi2c.h"
38+ #include "fsl_gpio.h"
3639
3740#define I2C_CLOCK_FREQ (CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8 / (1+CLOCK_GetDiv(kCLOCK_Lpi2cDiv)))
38-
41+ #define IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_ALT5 5U
42+
43+ //arrays use 0 based numbering: I2C1 is stored at index 0
44+ #define MAX_I2C 4
45+ STATIC bool reserved_i2c [MAX_I2C ];
46+ STATIC bool never_reset_i2c [MAX_I2C ];
47+
48+ void i2c_reset (void ) {
49+ for (uint i = 0 ; i < MP_ARRAY_SIZE (mcu_i2c_banks ); i ++ ) {
50+ if (!never_reset_i2c [i ]) {
51+ reserved_i2c [i ] = false;
52+ LPI2C_MasterDeinit (mcu_i2c_banks [i ]);
53+ }
54+ }
55+ }
3956
4057static void config_periph_pin (const mcu_periph_obj_t * periph ) {
4158 IOMUXC_SetPinMux (
@@ -56,11 +73,49 @@ static void config_periph_pin(const mcu_periph_obj_t *periph) {
5673 | IOMUXC_SW_PAD_CTL_PAD_SRE (0 ));
5774}
5875
76+ static void i2c_check_pin_config (const mcu_pin_obj_t * pin , uint32_t pull )
77+ {
78+ IOMUXC_SetPinConfig (0 , 0 , 0 , 0 , pin -> cfg_reg ,
79+ IOMUXC_SW_PAD_CTL_PAD_HYS (1 )
80+ | IOMUXC_SW_PAD_CTL_PAD_PUS (0 ) // Pulldown
81+ | IOMUXC_SW_PAD_CTL_PAD_PUE (pull ) // 0=nopull (keeper), 1=pull
82+ | IOMUXC_SW_PAD_CTL_PAD_PKE (1 )
83+ | IOMUXC_SW_PAD_CTL_PAD_ODE (0 )
84+ | IOMUXC_SW_PAD_CTL_PAD_SPEED (2 )
85+ | IOMUXC_SW_PAD_CTL_PAD_DSE (1 )
86+ | IOMUXC_SW_PAD_CTL_PAD_SRE (0 ));
87+ }
88+
5989void common_hal_busio_i2c_construct (busio_i2c_obj_t * self ,
6090 const mcu_pin_obj_t * scl , const mcu_pin_obj_t * sda , uint32_t frequency , uint32_t timeout ) {
6191
62- const uint32_t sda_count = sizeof (mcu_i2c_sda_list ) / sizeof (mcu_periph_obj_t );
63- const uint32_t scl_count = sizeof (mcu_i2c_scl_list ) / sizeof (mcu_periph_obj_t );
92+ #if CIRCUITPY_REQUIRE_I2C_PULLUPS
93+ // Test that the pins are in a high state. (Hopefully indicating they are pulled up.)
94+ IOMUXC_SetPinMux (sda -> mux_reg , IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_ALT5 , 0 , 0 , 0 , 0 );
95+ IOMUXC_SetPinMux (scl -> mux_reg , IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_ALT5 , 0 , 0 , 0 , 0 );
96+ i2c_check_pin_config (sda , 1 );
97+ i2c_check_pin_config (scl , 1 );
98+ const gpio_pin_config_t check_config = { kGPIO_DigitalInput , 0 , kGPIO_NoIntmode };
99+ GPIO_PinInit (sda -> gpio , sda -> number , & check_config );
100+ GPIO_PinInit (scl -> gpio , scl -> number , & check_config );
101+
102+ common_hal_mcu_delay_us (10 );
103+
104+ i2c_check_pin_config (sda , 0 );
105+ i2c_check_pin_config (scl , 0 );
106+
107+ // We must pull up within 3us to achieve 400khz.
108+ common_hal_mcu_delay_us (3 );
109+
110+ if ( !GPIO_PinRead (sda -> gpio , sda -> number ) || !GPIO_PinRead (scl -> gpio , scl -> number )) {
111+ common_hal_reset_pin (sda );
112+ common_hal_reset_pin (scl );
113+ mp_raise_RuntimeError (translate ("SDA or SCL needs a pull up" ));
114+ }
115+ #endif
116+
117+ const uint32_t sda_count = MP_ARRAY_SIZE (mcu_i2c_sda_list );
118+ const uint32_t scl_count = MP_ARRAY_SIZE (mcu_i2c_scl_list );
64119
65120 for (uint32_t i = 0 ; i < sda_count ; ++ i ) {
66121 if (mcu_i2c_sda_list [i ].pin != sda )
@@ -73,21 +128,21 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
73128 if (mcu_i2c_scl_list [j ].bank_idx != mcu_i2c_sda_list [i ].bank_idx )
74129 continue ;
75130
76- self -> sda_pin = & mcu_i2c_sda_list [i ];
77- self -> scl_pin = & mcu_i2c_scl_list [j ];
131+ self -> sda = & mcu_i2c_sda_list [i ];
132+ self -> scl = & mcu_i2c_scl_list [j ];
78133
79134 break ;
80135 }
81136 }
82137
83- if (self -> sda_pin == NULL || self -> scl_pin == NULL ) {
84- mp_raise_ValueError (translate ("Invalid I2C pin selection " ));
138+ if (self -> sda == NULL || self -> scl == NULL ) {
139+ mp_raise_ValueError (translate ("Invalid pins " ));
85140 } else {
86- self -> i2c = mcu_i2c_banks [self -> sda_pin -> bank_idx - 1 ];
141+ self -> i2c = mcu_i2c_banks [self -> sda -> bank_idx - 1 ];
87142 }
88143
89- config_periph_pin (self -> sda_pin );
90- config_periph_pin (self -> scl_pin );
144+ config_periph_pin (self -> sda );
145+ config_periph_pin (self -> scl );
91146
92147 lpi2c_master_config_t config = { 0 };
93148 LPI2C_MasterGetDefaultConfig (& config );
@@ -96,34 +151,35 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
96151
97152 LPI2C_MasterInit (self -> i2c , & config , I2C_CLOCK_FREQ );
98153
99- #if CIRCUITPY_REQUIRE_I2C_PULLUPS
100- // if (!gpio_get_pin_level(sda->number) || !gpio_get_pin_level(scl->number)) {
101- // reset_pin_number(sda->number);
102- // reset_pin_number(scl->number);
103- // mp_raise_RuntimeError(translate("SDA or SCL needs a pull up"));
104- // }
105- #endif
154+ claim_pin (self -> sda -> pin );
155+ claim_pin (self -> scl -> pin );
156+ }
157+
158+ void common_hal_busio_i2c_never_reset (busio_i2c_obj_t * self ) {
159+ never_reset_i2c [self -> sda -> bank_idx - 1 ] = true;
106160
107- claim_pin (self -> sda_pin -> pin );
108- claim_pin (self -> scl_pin -> pin );
161+ common_hal_never_reset_pin (self -> sda -> pin );
162+ common_hal_never_reset_pin (self -> scl -> pin );
109163}
110164
111165bool common_hal_busio_i2c_deinited (busio_i2c_obj_t * self ) {
112- return self -> sda_pin == NULL ;
166+ return self -> sda == NULL ;
113167}
114168
115169void common_hal_busio_i2c_deinit (busio_i2c_obj_t * self ) {
116170 if (common_hal_busio_i2c_deinited (self )) {
117171 return ;
118172 }
173+ reserved_i2c [self -> sda -> bank_idx - 1 ] = false;
174+ never_reset_i2c [self -> sda -> bank_idx - 1 ] = false;
119175
120176 LPI2C_MasterDeinit (self -> i2c );
121177
122- // reset_pin_number (self->sda_pin );
123- // reset_pin_number (self->scl_pin );
178+ common_hal_reset_pin (self -> sda -> pin );
179+ common_hal_reset_pin (self -> scl -> pin );
124180
125- self -> sda_pin = NULL ;
126- self -> scl_pin = NULL ;
181+ self -> sda = NULL ;
182+ self -> scl = NULL ;
127183}
128184
129185bool common_hal_busio_i2c_probe (busio_i2c_obj_t * self , uint8_t addr ) {
@@ -183,10 +239,3 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
183239
184240 return MP_EIO ;
185241}
186-
187- void common_hal_busio_i2c_never_reset (busio_i2c_obj_t * self ) {
188- // never_reset_sercom(self->i2c_desc.device.hw);
189- //
190- // never_reset_pin_number(self->scl_pin);
191- // never_reset_pin_number(self->sda_pin);
192- }
0 commit comments