34
34
#include "nrfx_twim.h"
35
35
#include "nrf_gpio.h"
36
36
37
+ #include "nrfx_spim.h"
38
+ #include "nrf_gpio.h"
39
+
40
+ STATIC twim_peripheral_t twim_peripherals [] = {
41
+ #if NRFX_CHECK (NRFX_TWIM0_ENABLED )
42
+ // SPIM0 and TWIM0 share an address.
43
+ { .twim = NRFX_TWIM_INSTANCE (0 ),
44
+ .in_use = false,
45
+ .max_xfer_size = TWIM0_EASYDMA_MAXCNT_SIZE ,
46
+ },
47
+ #endif
48
+ #if NRFX_CHECK (NRFX_TWIM1_ENABLED )
49
+ // SPIM1 and TWIM1 share an address.
50
+ { .twim = NRFX_TWIM_INSTANCE (1 ),
51
+ .in_use = false,
52
+ .max_xfer_size = TWIM1_EASYDMA_MAXCNT_SIZE ,
53
+ },
54
+ #endif
55
+ };
56
+
37
57
#define INST_NO 0
38
- #define MAX_XFER_SIZE ((1U << NRFX_CONCAT_3(TWIM, INST_NO, _EASYDMA_MAXCNT_SIZE)) - 1)
39
58
40
59
static uint8_t twi_error_to_mp (const nrfx_err_t err ) {
41
60
switch (err ) {
@@ -54,11 +73,23 @@ static uint8_t twi_error_to_mp(const nrfx_err_t err) {
54
73
}
55
74
56
75
void common_hal_busio_i2c_construct (busio_i2c_obj_t * self , const mcu_pin_obj_t * scl , const mcu_pin_obj_t * sda , uint32_t frequency , uint32_t timeout ) {
57
- if (scl -> number == sda -> number )
76
+ if (scl -> number == sda -> number ) {
58
77
mp_raise_ValueError (translate ("Invalid pins" ));
78
+ }
79
+
80
+ // Find a free instance.
81
+ self -> twim_peripheral = NULL ;
82
+ for (size_t i = 0 ; i < MP_ARRAY_SIZE (twim_peripherals ); i ++ ) {
83
+ if (!twim_peripherals [i ].in_use ) {
84
+ self -> twim_peripheral = & twim_peripherals [i ];
85
+ self -> twim_peripheral -> in_use = true;
86
+ break ;
87
+ }
88
+ }
59
89
60
- const nrfx_twim_t instance = NRFX_TWIM_INSTANCE (INST_NO );
61
- self -> twim = instance ;
90
+ if (self -> twim_peripheral == NULL ) {
91
+ mp_raise_ValueError (translate ("All I2C peripherals are in use" ));
92
+ }
62
93
63
94
nrfx_twim_config_t config = NRFX_TWIM_DEFAULT_CONFIG ;
64
95
config .scl = scl -> number ;
@@ -76,12 +107,12 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
76
107
claim_pin (sda );
77
108
claim_pin (scl );
78
109
79
- nrfx_err_t err = nrfx_twim_init (& self -> twim , & config , NULL , NULL );
110
+ nrfx_err_t err = nrfx_twim_init (& self -> twim_peripheral -> twim , & config , NULL , NULL );
80
111
81
112
// A soft reset doesn't uninit the driver so we might end up with a invalid state
82
113
if (err == NRFX_ERROR_INVALID_STATE ) {
83
- nrfx_twim_uninit (& self -> twim );
84
- err = nrfx_twim_init (& self -> twim , & config , NULL , NULL );
114
+ nrfx_twim_uninit (& self -> twim_peripheral -> twim );
115
+ err = nrfx_twim_init (& self -> twim_peripheral -> twim , & config , NULL , NULL );
85
116
}
86
117
87
118
if (err != NRFX_SUCCESS ) {
@@ -99,20 +130,22 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
99
130
if (common_hal_busio_i2c_deinited (self ))
100
131
return ;
101
132
102
- nrfx_twim_uninit (& self -> twim );
133
+ nrfx_twim_uninit (& self -> twim_peripheral -> twim );
103
134
104
135
reset_pin_number (self -> sda_pin_number );
105
136
reset_pin_number (self -> scl_pin_number );
106
137
self -> sda_pin_number = NO_PIN ;
107
138
self -> scl_pin_number = NO_PIN ;
139
+
140
+ self -> twim_peripheral -> in_use = false;
108
141
}
109
142
110
143
// nrfx_twim_tx doesn't support 0-length data so we fall back to the hal API
111
144
bool common_hal_busio_i2c_probe (busio_i2c_obj_t * self , uint8_t addr ) {
112
- NRF_TWIM_Type * reg = self -> twim .p_twim ;
145
+ NRF_TWIM_Type * reg = self -> twim_peripheral -> twim .p_twim ;
113
146
bool found = true;
114
147
115
- nrfx_twim_enable (& self -> twim );
148
+ nrfx_twim_enable (& self -> twim_peripheral -> twim );
116
149
117
150
nrf_twim_address_set (reg , addr );
118
151
nrf_twim_tx_buffer_set (reg , NULL , 0 );
@@ -135,19 +168,19 @@ bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
135
168
found = false;
136
169
}
137
170
138
- nrfx_twim_disable (& self -> twim );
171
+ nrfx_twim_disable (& self -> twim_peripheral -> twim );
139
172
140
173
return found ;
141
174
}
142
175
143
176
bool common_hal_busio_i2c_try_lock (busio_i2c_obj_t * self ) {
144
177
bool grabbed_lock = false;
145
- // CRITICAL_SECTION_ENTER()
146
- if (!self -> has_lock ) {
147
- grabbed_lock = true;
148
- self -> has_lock = true;
149
- }
150
- // CRITICAL_SECTION_LEAVE ();
178
+ // NRFX_CRITICAL_SECTION_ENTER();
179
+ if (!self -> has_lock ) {
180
+ grabbed_lock = true;
181
+ self -> has_lock = true;
182
+ }
183
+ // NRFX_CRITICAL_SECTION_EXIT ();
151
184
return grabbed_lock ;
152
185
}
153
186
@@ -163,22 +196,23 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const u
163
196
if (len == 0 )
164
197
return common_hal_busio_i2c_probe (self , addr ) ? 0 : MP_ENODEV ;
165
198
166
- const uint32_t parts = len / MAX_XFER_SIZE ;
167
- const uint32_t remainder = len % MAX_XFER_SIZE ;
199
+ const uint32_t max_xfer_size = self -> twim_peripheral -> max_xfer_size ;
200
+ const uint32_t parts = len / max_xfer_size ;
201
+ const uint32_t remainder = len % max_xfer_size ;
168
202
nrfx_err_t err = NRFX_SUCCESS ;
169
203
170
- nrfx_twim_enable (& self -> twim );
204
+ nrfx_twim_enable (& self -> twim_peripheral -> twim );
171
205
172
206
for (uint32_t i = 0 ; i < parts ; ++ i ) {
173
- err = nrfx_twim_tx (& self -> twim , addr , data + i * MAX_XFER_SIZE , MAX_XFER_SIZE , !stopBit );
207
+ err = nrfx_twim_tx (& self -> twim_peripheral -> twim , addr , data + i * max_xfer_size , max_xfer_size , !stopBit );
174
208
if (err != NRFX_SUCCESS )
175
209
break ;
176
210
}
177
211
178
212
if ((remainder > 0 ) && (err == NRFX_SUCCESS ))
179
- err = nrfx_twim_tx (& self -> twim , addr , data + parts * MAX_XFER_SIZE , remainder , !stopBit );
213
+ err = nrfx_twim_tx (& self -> twim_peripheral -> twim , addr , data + parts * max_xfer_size , remainder , !stopBit );
180
214
181
- nrfx_twim_disable (& self -> twim );
215
+ nrfx_twim_disable (& self -> twim_peripheral -> twim );
182
216
183
217
return twi_error_to_mp (err );
184
218
}
@@ -187,22 +221,23 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t
187
221
if (len == 0 )
188
222
return 0 ;
189
223
190
- const uint32_t parts = len / MAX_XFER_SIZE ;
191
- const uint32_t remainder = len % MAX_XFER_SIZE ;
224
+ const uint32_t max_xfer_size = self -> twim_peripheral -> max_xfer_size ;
225
+ const uint32_t parts = len / max_xfer_size ;
226
+ const uint32_t remainder = len % max_xfer_size ;
192
227
nrfx_err_t err = NRFX_SUCCESS ;
193
228
194
- nrfx_twim_enable (& self -> twim );
229
+ nrfx_twim_enable (& self -> twim_peripheral -> twim );
195
230
196
231
for (uint32_t i = 0 ; i < parts ; ++ i ) {
197
- err = nrfx_twim_rx (& self -> twim , addr , data + i * MAX_XFER_SIZE , MAX_XFER_SIZE );
232
+ err = nrfx_twim_rx (& self -> twim_peripheral -> twim , addr , data + i * max_xfer_size , max_xfer_size );
198
233
if (err != NRFX_SUCCESS )
199
234
break ;
200
235
}
201
236
202
237
if ((remainder > 0 ) && (err == NRFX_SUCCESS ))
203
- err = nrfx_twim_rx (& self -> twim , addr , data + parts * MAX_XFER_SIZE , remainder );
238
+ err = nrfx_twim_rx (& self -> twim_peripheral -> twim , addr , data + parts * max_xfer_size , remainder );
204
239
205
- nrfx_twim_disable (& self -> twim );
240
+ nrfx_twim_disable (& self -> twim_peripheral -> twim );
206
241
207
242
return twi_error_to_mp (err );
208
243
}
0 commit comments