30
30
#include "py/mperrno.h"
31
31
#include "extmod/vfs.h"
32
32
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
+
33
41
#if MICROPY_VFS
34
42
35
43
void mp_vfs_blockdev_init (mp_vfs_blockdev_t * self , mp_obj_t bdev ) {
36
44
mp_load_method (bdev , MP_QSTR_readblocks , self -> readblocks );
37
45
mp_load_method_maybe (bdev , MP_QSTR_writeblocks , self -> writeblocks );
38
46
mp_load_method_maybe (bdev , MP_QSTR_ioctl , self -> u .ioctl );
47
+
48
+ // CIRCUITPY-CHANGE: Support native SD cards.
49
+ #if CIRCUITPY_SDCARDIO
50
+ if (mp_obj_get_type (bdev ) == & sdcardio_SDCard_type ) {
51
+ self -> flags |= MP_BLOCKDEV_FLAG_NATIVE | MP_BLOCKDEV_FLAG_HAVE_IOCTL ;
52
+ self -> readblocks [0 ] = mp_const_none ;
53
+ self -> readblocks [1 ] = bdev ;
54
+ self -> readblocks [2 ] = (mp_obj_t )sdcardio_sdcard_readblocks ; // native version
55
+ self -> writeblocks [0 ] = mp_const_none ;
56
+ self -> writeblocks [1 ] = bdev ;
57
+ self -> writeblocks [2 ] = (mp_obj_t )sdcardio_sdcard_writeblocks ; // native version
58
+ self -> u .ioctl [0 ] = mp_const_none ;
59
+ self -> u .ioctl [1 ] = bdev ;
60
+ self -> u .ioctl [2 ] = (mp_obj_t )sdcardio_sdcard_ioctl ; // native version
61
+ }
62
+ #endif
63
+ #if CIRCUITPY_SDIOIO
64
+ if (mp_obj_get_type (bdev ) == & sdioio_SDCard_type ) {
65
+ // TODO: Enable native blockdev for SDIO too.
66
+ }
67
+ #endif
39
68
if (self -> u .ioctl [0 ] != MP_OBJ_NULL ) {
40
69
// Device supports new block protocol, so indicate it
41
70
self -> flags |= MP_BLOCKDEV_FLAG_HAVE_IOCTL ;
@@ -48,8 +77,8 @@ void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) {
48
77
49
78
int mp_vfs_blockdev_read (mp_vfs_blockdev_t * self , size_t block_num , size_t num_blocks , uint8_t * buf ) {
50
79
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 );
80
+ mp_uint_t (* f )(mp_obj_t self , uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> readblocks [2 ];
81
+ return f (self -> readblocks [ 1 ], buf , block_num , num_blocks );
53
82
} else {
54
83
mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , num_blocks * self -> block_size , buf };
55
84
self -> readblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
@@ -80,8 +109,8 @@ int mp_vfs_blockdev_write(mp_vfs_blockdev_t *self, size_t block_num, size_t num_
80
109
}
81
110
82
111
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 );
112
+ mp_uint_t (* f )(mp_obj_t self , const uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> writeblocks [2 ];
113
+ return f (self -> writeblocks [ 1 ], buf , block_num , num_blocks );
85
114
} else {
86
115
mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , num_blocks * self -> block_size , (void * )buf };
87
116
self -> writeblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
@@ -112,6 +141,15 @@ int mp_vfs_blockdev_write_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t
112
141
113
142
mp_obj_t mp_vfs_blockdev_ioctl (mp_vfs_blockdev_t * self , uintptr_t cmd , uintptr_t arg ) {
114
143
if (self -> flags & MP_BLOCKDEV_FLAG_HAVE_IOCTL ) {
144
+ if (self -> flags & MP_BLOCKDEV_FLAG_NATIVE ) {
145
+ size_t out_value ;
146
+ bool (* f )(mp_obj_t self , uint32_t , uint32_t , size_t * ) = (void * )(uintptr_t )self -> u .ioctl [2 ];
147
+ bool b = f (self -> u .ioctl [1 ], cmd , arg , & out_value );
148
+ if (!b ) {
149
+ return mp_const_none ;
150
+ }
151
+ return MP_OBJ_NEW_SMALL_INT (out_value );
152
+ }
115
153
// New protocol with ioctl
116
154
self -> u .ioctl [2 ] = MP_OBJ_NEW_SMALL_INT (cmd );
117
155
self -> u .ioctl [3 ] = MP_OBJ_NEW_SMALL_INT (arg );
0 commit comments