@@ -141,54 +141,46 @@ uint64_t sdcard_get_capacity_in_bytes(void) {
141
141
return cardinfo .CardCapacity ;
142
142
}
143
143
144
- bool sdcard_read_blocks (uint8_t * dest , uint32_t block_num , uint32_t num_blocks ) {
144
+ mp_uint_t sdcard_read_blocks (uint8_t * dest , uint32_t block_num , uint32_t num_blocks ) {
145
145
// check that dest pointer is aligned on a 4-byte boundary
146
146
if (((uint32_t )dest & 3 ) != 0 ) {
147
- return false ;
147
+ return SD_ERROR ;
148
148
}
149
149
150
150
// check that SD card is initialised
151
151
if (sd_handle .Instance == NULL ) {
152
- return false ;
152
+ return SD_ERROR ;
153
153
}
154
154
155
155
// We must disable IRQs because the SDIO peripheral has a small FIFO
156
156
// buffer and we can't let it fill up in the middle of a read.
157
157
// This will not be needed when SD uses DMA for transfer.
158
- __disable_irq ();
159
- HAL_SD_ErrorTypedef err = HAL_SD_ReadBlocks (& sd_handle , (uint32_t * )dest , ( uint64_t ) block_num * SDCARD_BLOCK_SIZE , SDCARD_BLOCK_SIZE , num_blocks );
160
- __enable_irq ( );
158
+ mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION ();
159
+ HAL_SD_ErrorTypedef err = HAL_SD_ReadBlocks_BlockNumber (& sd_handle , (uint32_t * )dest , block_num , SDCARD_BLOCK_SIZE , num_blocks );
160
+ MICROPY_END_ATOMIC_SECTION ( atomic_state );
161
161
162
- if (err != SD_OK ) {
163
- return false;
164
- }
165
-
166
- return true;
162
+ return err ;
167
163
}
168
164
169
- bool sdcard_write_blocks (const uint8_t * src , uint32_t block_num , uint32_t num_blocks ) {
165
+ mp_uint_t sdcard_write_blocks (const uint8_t * src , uint32_t block_num , uint32_t num_blocks ) {
170
166
// check that src pointer is aligned on a 4-byte boundary
171
167
if (((uint32_t )src & 3 ) != 0 ) {
172
- return false ;
168
+ return SD_ERROR ;
173
169
}
174
170
175
171
// check that SD card is initialised
176
172
if (sd_handle .Instance == NULL ) {
177
- return false ;
173
+ return SD_ERROR ;
178
174
}
179
175
180
176
// We must disable IRQs because the SDIO peripheral has a small FIFO
181
177
// buffer and we can't let it drain to empty in the middle of a write.
182
178
// This will not be needed when SD uses DMA for transfer.
183
- __disable_irq ();
184
- HAL_SD_ErrorTypedef err = HAL_SD_WriteBlocks (& sd_handle , (uint32_t * )src , (uint64_t )block_num * SDCARD_BLOCK_SIZE , SDCARD_BLOCK_SIZE , num_blocks );
185
- __enable_irq ();
186
-
187
- if (err != SD_OK ) {
188
- return false;
189
- }
179
+ mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION ();
180
+ HAL_SD_ErrorTypedef err = HAL_SD_WriteBlocks_BlockNumber (& sd_handle , (uint32_t * )src , block_num , SDCARD_BLOCK_SIZE , num_blocks );
181
+ MICROPY_END_ATOMIC_SECTION (atomic_state );
190
182
191
- return true ;
183
+ return err ;
192
184
}
193
185
194
186
#if 0
@@ -205,7 +197,7 @@ bool sdcard_read_blocks_dma(uint8_t *dest, uint32_t block_num, uint32_t num_bloc
205
197
}
206
198
207
199
// do the read
208
- if (HAL_SD_ReadBlocks_DMA (& sd_handle , (uint32_t * )dest , ( uint64_t ) block_num * SDCARD_BLOCK_SIZE , SDCARD_BLOCK_SIZE ) != SD_OK ) {
200
+ if (HAL_SD_ReadBlocks_BlockNumber_DMA (& sd_handle , (uint32_t * )dest , block_num , SDCARD_BLOCK_SIZE ) != SD_OK ) {
209
201
return false;
210
202
}
211
203
@@ -230,7 +222,7 @@ bool sdcard_write_blocks_dma(const uint8_t *src, uint32_t block_num, uint32_t nu
230
222
231
223
SD_Error status ;
232
224
233
- status = HAL_SD_WriteBlock_DMA (& sd_handle , (uint32_t * )src , ( uint64_t ) block_num * SDCARD_BLOCK_SIZE , SDCARD_BLOCK_SIZE , num_blocks );
225
+ status = HAL_SD_WriteBlocks_BlockNumber_DMA (& sd_handle , (uint32_t * )src , block_num , SDCARD_BLOCK_SIZE , num_blocks );
234
226
if (status != SD_OK ) {
235
227
return false;
236
228
}
@@ -247,14 +239,17 @@ bool sdcard_write_blocks_dma(const uint8_t *src, uint32_t block_num, uint32_t nu
247
239
248
240
/******************************************************************************/
249
241
// Micro Python bindings
242
+ //
243
+ // Note: these function are a bit ad-hoc at the moment and are mainly intended
244
+ // for testing purposes. In the future SD should be a proper class with a
245
+ // consistent interface and methods to mount/unmount it.
250
246
251
- static mp_obj_t sd_present (mp_obj_t self ) {
247
+ STATIC mp_obj_t sd_present (mp_obj_t self ) {
252
248
return MP_BOOL (sdcard_is_present ());
253
249
}
250
+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (sd_present_obj , sd_present );
254
251
255
- static MP_DEFINE_CONST_FUN_OBJ_1 (sd_present_obj , sd_present ) ;
256
-
257
- static mp_obj_t sd_power (mp_obj_t self , mp_obj_t state ) {
252
+ STATIC mp_obj_t sd_power (mp_obj_t self , mp_obj_t state ) {
258
253
bool result ;
259
254
if (mp_obj_is_true (state )) {
260
255
result = sdcard_power_on ();
@@ -264,40 +259,59 @@ static mp_obj_t sd_power(mp_obj_t self, mp_obj_t state) {
264
259
}
265
260
return MP_BOOL (result );
266
261
}
262
+ STATIC MP_DEFINE_CONST_FUN_OBJ_2 (sd_power_obj , sd_power );
267
263
268
- static MP_DEFINE_CONST_FUN_OBJ_2 (sd_power_obj , sd_power ) ;
264
+ STATIC mp_obj_t sd_info (mp_obj_t self ) {
265
+ HAL_SD_ErrorTypedef HAL_SD_Init (SD_HandleTypeDef * hsd , HAL_SD_CardInfoTypedef * SDCardInfo );
266
+ if (sd_handle .Instance == NULL ) {
267
+ return mp_const_none ;
268
+ }
269
+ HAL_SD_CardInfoTypedef cardinfo ;
270
+ HAL_SD_Get_CardInfo (& sd_handle , & cardinfo );
271
+ // cardinfo.SD_csd and cardinfo.SD_cid have lots of info but we don't use them
272
+ mp_obj_t tuple [3 ] = {
273
+ mp_obj_new_int_from_ull (cardinfo .CardCapacity ),
274
+ mp_obj_new_int_from_uint (cardinfo .CardBlockSize ),
275
+ mp_obj_new_int (cardinfo .CardType ),
276
+ };
277
+ return mp_obj_new_tuple (3 , tuple );
278
+ }
279
+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (sd_info_obj , sd_info );
269
280
270
- static mp_obj_t sd_read (mp_obj_t self , mp_obj_t block_num ) {
281
+ STATIC mp_obj_t sd_read (mp_obj_t self , mp_obj_t block_num ) {
271
282
uint8_t * dest = m_new (uint8_t , SDCARD_BLOCK_SIZE );
272
- if (!sdcard_read_blocks (dest , mp_obj_get_int (block_num ), 1 )) {
283
+ mp_uint_t ret = sdcard_read_blocks (dest , mp_obj_get_int (block_num ), 1 );
284
+
285
+ if (ret != 0 ) {
273
286
m_free (dest , SDCARD_BLOCK_SIZE );
274
- return mp_const_none ;
287
+ nlr_raise ( mp_obj_new_exception_msg_varg ( & mp_type_Exception , "sdcard_read_blocks failed [%u]" , ret )) ;
275
288
}
289
+
276
290
return mp_obj_new_bytearray_by_ref (SDCARD_BLOCK_SIZE , dest );
277
291
}
292
+ STATIC MP_DEFINE_CONST_FUN_OBJ_2 (sd_read_obj , sd_read );
278
293
279
- static MP_DEFINE_CONST_FUN_OBJ_2 (sd_read_obj , sd_read ) ;
280
-
281
- static mp_obj_t sd_write (mp_obj_t self , mp_obj_t block_num , mp_obj_t source ) {
294
+ STATIC mp_obj_t sd_write (mp_obj_t self , mp_obj_t block_num , mp_obj_t data ) {
282
295
mp_buffer_info_t bufinfo ;
283
- uint8_t tmp [1 ];
284
-
285
- pyb_buf_get_for_send (source , & bufinfo , tmp );
296
+ mp_get_buffer_raise (data , & bufinfo , MP_BUFFER_READ );
286
297
if (bufinfo .len % SDCARD_BLOCK_SIZE != 0 ) {
287
- nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError , "writes must be aligned to SDCARD_BLOCK_SIZE (%d) bytes" , SDCARD_BLOCK_SIZE ));
298
+ nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError , "writes must be a multiple of %d bytes" , SDCARD_BLOCK_SIZE ));
288
299
}
289
300
290
- if (!sdcard_write_blocks (bufinfo .buf , mp_obj_get_int (block_num ), bufinfo .len / SDCARD_BLOCK_SIZE )) {
291
- nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_Exception , "sdcard_write_blocks failed" ));
301
+ mp_uint_t ret = sdcard_write_blocks (bufinfo .buf , mp_obj_get_int (block_num ), bufinfo .len / SDCARD_BLOCK_SIZE );
302
+
303
+ if (ret != 0 ) {
304
+ nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_Exception , "sdcard_write_blocks failed [%u]" , ret ));
292
305
}
306
+
293
307
return mp_const_none ;
294
308
}
295
-
296
- static MP_DEFINE_CONST_FUN_OBJ_3 (sd_write_obj , sd_write ) ;
309
+ STATIC MP_DEFINE_CONST_FUN_OBJ_3 (sd_write_obj , sd_write );
297
310
298
311
STATIC const mp_map_elem_t sdcard_locals_dict_table [] = {
299
312
{ MP_OBJ_NEW_QSTR (MP_QSTR_present ), (mp_obj_t )& sd_present_obj },
300
313
{ MP_OBJ_NEW_QSTR (MP_QSTR_power ), (mp_obj_t )& sd_power_obj },
314
+ { MP_OBJ_NEW_QSTR (MP_QSTR_info ), (mp_obj_t )& sd_info_obj },
301
315
{ MP_OBJ_NEW_QSTR (MP_QSTR_read ), (mp_obj_t )& sd_read_obj },
302
316
{ MP_OBJ_NEW_QSTR (MP_QSTR_write ), (mp_obj_t )& sd_write_obj },
303
317
};
0 commit comments