3030#include "py/mperrno.h"
3131#include "extmod/vfs.h"
3232
33+ #if CIRCUITPY_SDCARDIO
34+ #include "shared-bindings/sdcardio/SDCard.h"
35+ #endif
36+ #if CIRCUITPY_SDIOIO
37+ #include "shared-bindings/sdioio/SDCard.h"
38+ #endif
39+
40+ #include "esp_log.h"
41+
42+ static const char * TAG = "vfs_blockdev" ;
43+
3344#if MICROPY_VFS
3445
3546void mp_vfs_blockdev_init (mp_vfs_blockdev_t * self , mp_obj_t bdev ) {
3647 mp_load_method (bdev , MP_QSTR_readblocks , self -> readblocks );
3748 mp_load_method_maybe (bdev , MP_QSTR_writeblocks , self -> writeblocks );
3849 mp_load_method_maybe (bdev , MP_QSTR_ioctl , self -> u .ioctl );
50+ ESP_LOGI (TAG , "new vfs blockdev %p around %p" , self , MP_OBJ_TO_PTR (bdev ));
51+
52+ // CIRCUITPY-CHANGE: Support native SD cards.
53+ #if CIRCUITPY_SDCARDIO
54+ if (mp_obj_get_type (bdev ) == & sdcardio_SDCard_type ) {
55+ ESP_LOGI (TAG , "sdcardio.SDCard" );
56+ self -> flags |= MP_BLOCKDEV_FLAG_NATIVE | MP_BLOCKDEV_FLAG_HAVE_IOCTL ;
57+ self -> readblocks [0 ] = mp_const_none ;
58+ self -> readblocks [1 ] = bdev ;
59+ self -> readblocks [2 ] = (mp_obj_t )sdcardio_sdcard_readblocks ; // native version
60+ self -> writeblocks [0 ] = mp_const_none ;
61+ self -> writeblocks [1 ] = bdev ;
62+ self -> writeblocks [2 ] = (mp_obj_t )sdcardio_sdcard_writeblocks ; // native version
63+ self -> u .ioctl [0 ] = mp_const_none ;
64+ self -> u .ioctl [1 ] = bdev ;
65+ self -> u .ioctl [2 ] = (mp_obj_t )sdcardio_sdcard_ioctl ; // native version
66+ }
67+ #endif
68+ #if CIRCUITPY_SDIOIO
69+ if (mp_obj_get_type (bdev ) == & sdioio_SDCard_type ) {
70+ // TODO: Enable native blockdev for SDIO too.
71+ }
72+ #endif
3973 if (self -> u .ioctl [0 ] != MP_OBJ_NULL ) {
4074 // Device supports new block protocol, so indicate it
4175 self -> flags |= MP_BLOCKDEV_FLAG_HAVE_IOCTL ;
@@ -48,8 +82,8 @@ void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) {
4882
4983int mp_vfs_blockdev_read (mp_vfs_blockdev_t * self , size_t block_num , size_t num_blocks , uint8_t * buf ) {
5084 if (self -> flags & MP_BLOCKDEV_FLAG_NATIVE ) {
51- mp_uint_t (* f )(uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> readblocks [2 ];
52- return f (buf , block_num , num_blocks );
85+ mp_uint_t (* f )(mp_obj_t self , uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> readblocks [2 ];
86+ return f (self -> readblocks [ 1 ], buf , block_num , num_blocks );
5387 } else {
5488 mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , num_blocks * self -> block_size , buf };
5589 self -> readblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
@@ -80,8 +114,8 @@ int mp_vfs_blockdev_write(mp_vfs_blockdev_t *self, size_t block_num, size_t num_
80114 }
81115
82116 if (self -> flags & MP_BLOCKDEV_FLAG_NATIVE ) {
83- mp_uint_t (* f )(const uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> writeblocks [2 ];
84- return f (buf , block_num , num_blocks );
117+ mp_uint_t (* f )(mp_obj_t self , const uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> writeblocks [2 ];
118+ return f (self -> writeblocks [ 1 ], buf , block_num , num_blocks );
85119 } else {
86120 mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , num_blocks * self -> block_size , (void * )buf };
87121 self -> writeblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
@@ -112,6 +146,15 @@ int mp_vfs_blockdev_write_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t
112146
113147mp_obj_t mp_vfs_blockdev_ioctl (mp_vfs_blockdev_t * self , uintptr_t cmd , uintptr_t arg ) {
114148 if (self -> flags & MP_BLOCKDEV_FLAG_HAVE_IOCTL ) {
149+ if (self -> flags & MP_BLOCKDEV_FLAG_NATIVE ) {
150+ size_t out_value ;
151+ bool (* f )(mp_obj_t self , uint32_t , uint32_t , size_t * ) = (void * )(uintptr_t )self -> u .ioctl [2 ];
152+ bool b = f (self -> u .ioctl [1 ], cmd , arg , & out_value );
153+ if (!b ) {
154+ return mp_const_none ;
155+ }
156+ return MP_OBJ_NEW_SMALL_INT (out_value );
157+ }
115158 // New protocol with ioctl
116159 self -> u .ioctl [2 ] = MP_OBJ_NEW_SMALL_INT (cmd );
117160 self -> u .ioctl [3 ] = MP_OBJ_NEW_SMALL_INT (arg );
0 commit comments