27
27
28
28
#include <stdio.h>
29
29
30
+ #include "shared-bindings/microcontroller/Pin.h"
31
+ #include "shared-bindings/microcontroller/__init__.h"
30
32
#include "shared-bindings/busio/I2C.h"
31
33
#include "py/mperrno.h"
32
34
#include "py/runtime.h"
33
35
#include "periph.h"
34
36
35
37
#include "fsl_lpi2c.h"
38
+ #include "fsl_gpio.h"
36
39
37
40
#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
+ }
39
56
40
57
static void config_periph_pin (const mcu_periph_obj_t * periph ) {
41
58
IOMUXC_SetPinMux (
@@ -56,11 +73,49 @@ static void config_periph_pin(const mcu_periph_obj_t *periph) {
56
73
| IOMUXC_SW_PAD_CTL_PAD_SRE (0 ));
57
74
}
58
75
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
+
59
89
void common_hal_busio_i2c_construct (busio_i2c_obj_t * self ,
60
90
const mcu_pin_obj_t * scl , const mcu_pin_obj_t * sda , uint32_t frequency , uint32_t timeout ) {
61
91
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 );
64
119
65
120
for (uint32_t i = 0 ; i < sda_count ; ++ i ) {
66
121
if (mcu_i2c_sda_list [i ].pin != sda )
@@ -73,21 +128,21 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
73
128
if (mcu_i2c_scl_list [j ].bank_idx != mcu_i2c_sda_list [i ].bank_idx )
74
129
continue ;
75
130
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 ];
78
133
79
134
break ;
80
135
}
81
136
}
82
137
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 " ));
85
140
} else {
86
- self -> i2c = mcu_i2c_banks [self -> sda_pin -> bank_idx - 1 ];
141
+ self -> i2c = mcu_i2c_banks [self -> sda -> bank_idx - 1 ];
87
142
}
88
143
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 );
91
146
92
147
lpi2c_master_config_t config = { 0 };
93
148
LPI2C_MasterGetDefaultConfig (& config );
@@ -96,34 +151,35 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
96
151
97
152
LPI2C_MasterInit (self -> i2c , & config , I2C_CLOCK_FREQ );
98
153
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;
106
160
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 );
109
163
}
110
164
111
165
bool common_hal_busio_i2c_deinited (busio_i2c_obj_t * self ) {
112
- return self -> sda_pin == NULL ;
166
+ return self -> sda == NULL ;
113
167
}
114
168
115
169
void common_hal_busio_i2c_deinit (busio_i2c_obj_t * self ) {
116
170
if (common_hal_busio_i2c_deinited (self )) {
117
171
return ;
118
172
}
173
+ reserved_i2c [self -> sda -> bank_idx - 1 ] = false;
174
+ never_reset_i2c [self -> sda -> bank_idx - 1 ] = false;
119
175
120
176
LPI2C_MasterDeinit (self -> i2c );
121
177
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 );
124
180
125
- self -> sda_pin = NULL ;
126
- self -> scl_pin = NULL ;
181
+ self -> sda = NULL ;
182
+ self -> scl = NULL ;
127
183
}
128
184
129
185
bool 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,
183
239
184
240
return MP_EIO ;
185
241
}
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