2424 * THE SOFTWARE.
2525 */
2626
27- #include STM32_HAL_H
28-
2927#include "py/nlr.h"
3028#include "py/runtime.h"
29+ #include "lib/fatfs/ff.h"
30+ #include "extmod/fsusermount.h"
31+
3132#include "sdcard.h"
3233#include "pin.h"
3334#include "genhdr/pins.h"
@@ -279,9 +280,18 @@ mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t n
279280/******************************************************************************/
280281// Micro Python bindings
281282//
282- // Note: these function are a bit ad-hoc at the moment and are mainly intended
283- // for testing purposes. In the future SD should be a proper class with a
284- // consistent interface and methods to mount/unmount it.
283+ // Expose the SD card as an object with the block protocol.
284+
285+ // there is a singleton SDCard object
286+ const mp_obj_base_t pyb_sdcard_obj = {& pyb_sdcard_type };
287+
288+ STATIC mp_obj_t pyb_sdcard_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * args ) {
289+ // check arguments
290+ mp_arg_check_num (n_args , n_kw , 0 , 0 , false);
291+
292+ // return singleton object
293+ return (mp_obj_t )& pyb_sdcard_obj ;
294+ }
285295
286296STATIC mp_obj_t sd_present (mp_obj_t self ) {
287297 return mp_obj_new_bool (sdcard_is_present ());
@@ -316,6 +326,7 @@ STATIC mp_obj_t sd_info(mp_obj_t self) {
316326}
317327STATIC MP_DEFINE_CONST_FUN_OBJ_1 (sd_info_obj , sd_info );
318328
329+ // now obsolete, kept for backwards compatibility
319330STATIC mp_obj_t sd_read (mp_obj_t self , mp_obj_t block_num ) {
320331 uint8_t * dest = m_new (uint8_t , SDCARD_BLOCK_SIZE );
321332 mp_uint_t ret = sdcard_read_blocks (dest , mp_obj_get_int (block_num ), 1 );
@@ -329,6 +340,7 @@ STATIC mp_obj_t sd_read(mp_obj_t self, mp_obj_t block_num) {
329340}
330341STATIC MP_DEFINE_CONST_FUN_OBJ_2 (sd_read_obj , sd_read );
331342
343+ // now obsolete, kept for backwards compatibility
332344STATIC mp_obj_t sd_write (mp_obj_t self , mp_obj_t block_num , mp_obj_t data ) {
333345 mp_buffer_info_t bufinfo ;
334346 mp_get_buffer_raise (data , & bufinfo , MP_BUFFER_READ );
@@ -346,22 +358,70 @@ STATIC mp_obj_t sd_write(mp_obj_t self, mp_obj_t block_num, mp_obj_t data) {
346358}
347359STATIC MP_DEFINE_CONST_FUN_OBJ_3 (sd_write_obj , sd_write );
348360
349- STATIC const mp_map_elem_t sdcard_locals_dict_table [] = {
361+ STATIC mp_obj_t pyb_sdcard_readblocks (mp_obj_t self , mp_obj_t block_num , mp_obj_t buf ) {
362+ mp_buffer_info_t bufinfo ;
363+ mp_get_buffer_raise (buf , & bufinfo , MP_BUFFER_WRITE );
364+ mp_uint_t ret = sdcard_read_blocks (bufinfo .buf , mp_obj_get_int (block_num ), bufinfo .len / SDCARD_BLOCK_SIZE );
365+ return mp_obj_new_bool (ret == 0 );
366+ }
367+ STATIC MP_DEFINE_CONST_FUN_OBJ_3 (pyb_sdcard_readblocks_obj , pyb_sdcard_readblocks );
368+
369+ STATIC mp_obj_t pyb_sdcard_writeblocks (mp_obj_t self , mp_obj_t block_num , mp_obj_t buf ) {
370+ mp_buffer_info_t bufinfo ;
371+ mp_get_buffer_raise (buf , & bufinfo , MP_BUFFER_READ );
372+ mp_uint_t ret = sdcard_write_blocks (bufinfo .buf , mp_obj_get_int (block_num ), bufinfo .len / SDCARD_BLOCK_SIZE );
373+ return mp_obj_new_bool (ret == 0 );
374+ }
375+ STATIC MP_DEFINE_CONST_FUN_OBJ_3 (pyb_sdcard_writeblocks_obj , pyb_sdcard_writeblocks );
376+
377+ STATIC mp_obj_t pyb_sdcard_ioctl (mp_obj_t self , mp_obj_t cmd_in , mp_obj_t arg_in ) {
378+ mp_int_t cmd = mp_obj_get_int (cmd_in );
379+ switch (cmd ) {
380+ case 1 : // INIT
381+ if (!sdcard_power_on ()) {
382+ return MP_OBJ_NEW_SMALL_INT (-1 ); // error
383+ }
384+ return MP_OBJ_NEW_SMALL_INT (0 ); // success
385+
386+ case 2 : // DEINIT
387+ sdcard_power_off ();
388+ return MP_OBJ_NEW_SMALL_INT (0 ); // success
389+
390+ case 3 : // SYNC
391+ // nothing to do
392+ return MP_OBJ_NEW_SMALL_INT (0 ); // success
393+
394+ case 4 : // SEC_COUNT
395+ return MP_OBJ_NEW_SMALL_INT (0 ); // TODO
396+
397+ case 5 : // SEC_SIZE
398+ return MP_OBJ_NEW_SMALL_INT (SDCARD_BLOCK_SIZE );
399+
400+ default : // unknown command
401+ return MP_OBJ_NEW_SMALL_INT (-1 ); // error
402+ }
403+ }
404+ STATIC MP_DEFINE_CONST_FUN_OBJ_3 (pyb_sdcard_ioctl_obj , pyb_sdcard_ioctl );
405+
406+ STATIC const mp_map_elem_t pyb_sdcard_locals_dict_table [] = {
350407 { MP_OBJ_NEW_QSTR (MP_QSTR_present ), (mp_obj_t )& sd_present_obj },
351408 { MP_OBJ_NEW_QSTR (MP_QSTR_power ), (mp_obj_t )& sd_power_obj },
352409 { MP_OBJ_NEW_QSTR (MP_QSTR_info ), (mp_obj_t )& sd_info_obj },
353410 { MP_OBJ_NEW_QSTR (MP_QSTR_read ), (mp_obj_t )& sd_read_obj },
354411 { MP_OBJ_NEW_QSTR (MP_QSTR_write ), (mp_obj_t )& sd_write_obj },
412+ // block device protocol
413+ { MP_OBJ_NEW_QSTR (MP_QSTR_readblocks ), (mp_obj_t )& pyb_sdcard_readblocks_obj },
414+ { MP_OBJ_NEW_QSTR (MP_QSTR_writeblocks ), (mp_obj_t )& pyb_sdcard_writeblocks_obj },
415+ { MP_OBJ_NEW_QSTR (MP_QSTR_ioctl ), (mp_obj_t )& pyb_sdcard_ioctl_obj },
355416};
356417
357- STATIC MP_DEFINE_CONST_DICT (sdcard_locals_dict , sdcard_locals_dict_table );
418+ STATIC MP_DEFINE_CONST_DICT (pyb_sdcard_locals_dict , pyb_sdcard_locals_dict_table );
358419
359- static const mp_obj_type_t sdcard_type = {
420+ const mp_obj_type_t pyb_sdcard_type = {
360421 { & mp_type_type },
361- .name = MP_QSTR_SDcard ,
362- .locals_dict = (mp_obj_t )& sdcard_locals_dict ,
422+ .name = MP_QSTR_SDCard ,
423+ .make_new = pyb_sdcard_make_new ,
424+ .locals_dict = (mp_obj_t )& pyb_sdcard_locals_dict ,
363425};
364426
365- const mp_obj_base_t pyb_sdcard_obj = {& sdcard_type };
366-
367427#endif // MICROPY_HW_HAS_SDCARD
0 commit comments