@@ -48,14 +48,14 @@ static_assert(MICROPY_HW_FLASH_STORAGE_BASE + MICROPY_HW_FLASH_STORAGE_BYTES <=
48
48
49
49
typedef struct _rp2_flash_obj_t {
50
50
mp_obj_base_t base ;
51
- uint32_t flash_base ;
52
- uint32_t flash_size ;
51
+ uint32_t start ;
52
+ uint32_t len ;
53
53
} rp2_flash_obj_t ;
54
54
55
55
STATIC rp2_flash_obj_t rp2_flash_obj = {
56
56
.base = { & rp2_flash_type },
57
- .flash_base = MICROPY_HW_FLASH_STORAGE_BASE ,
58
- .flash_size = MICROPY_HW_FLASH_STORAGE_BYTES ,
57
+ .start = MICROPY_HW_FLASH_STORAGE_BASE ,
58
+ .len = MICROPY_HW_FLASH_STORAGE_BYTES ,
59
59
};
60
60
61
61
// Tag the flash drive in the binary as readable/writable (but not reformatable)
@@ -70,16 +70,47 @@ bi_decl(bi_block_device(
70
70
BINARY_INFO_BLOCK_DEV_FLAG_PT_UNKNOWN ));
71
71
72
72
STATIC mp_obj_t rp2_flash_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * all_args ) {
73
- // Check args.
74
- mp_arg_check_num (n_args , n_kw , 0 , 0 , false);
73
+ // Parse arguments
74
+ enum { ARG_start , ARG_len };
75
+ static const mp_arg_t allowed_args [] = {
76
+ { MP_QSTR_start , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = -1 } },
77
+ { MP_QSTR_len , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = -1 } },
78
+ };
79
+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
80
+ mp_arg_parse_all_kw_array (n_args , n_kw , all_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
81
+
82
+ if (args [ARG_start ].u_int == -1 && args [ARG_len ].u_int == -1 ) {
83
+ #ifndef NDEBUG
84
+ extern char __flash_binary_end ;
85
+ assert ((uintptr_t )& __flash_binary_end - XIP_BASE <= MICROPY_HW_FLASH_STORAGE_BASE );
86
+ #endif
87
+
88
+ // Default singleton object that accesses entire flash, including virtual partition table
89
+ return MP_OBJ_FROM_PTR (& rp2_flash_obj );
90
+ }
91
+
92
+ rp2_flash_obj_t * self = mp_obj_malloc (rp2_flash_obj_t , & rp2_flash_type );
93
+
94
+ uint32_t bl_len = MICROPY_HW_FLASH_STORAGE_BYTES ;
95
+
96
+ mp_int_t start = args [ARG_start ].u_int ;
97
+ if (start == -1 ) {
98
+ start = 0 ;
99
+ } else if (!(0 <= start && start < bl_len && start % BLOCK_SIZE_BYTES == 0 )) {
100
+ mp_raise_ValueError (NULL );
101
+ }
102
+
103
+ mp_int_t len = args [ARG_len ].u_int ;
104
+ if (len == -1 ) {
105
+ len = MICROPY_HW_FLASH_STORAGE_BYTES ;
106
+ } else if (!(0 < len && start + len <= bl_len && len % BLOCK_SIZE_BYTES == 0 )) {
107
+ mp_raise_ValueError (NULL );
108
+ }
75
109
76
- #ifndef NDEBUG
77
- extern char __flash_binary_end ;
78
- assert ((uintptr_t )& __flash_binary_end - XIP_BASE <= MICROPY_HW_FLASH_STORAGE_BASE );
79
- #endif
110
+ self -> start = MICROPY_HW_FLASH_STORAGE_BASE + start ;
111
+ self -> len = len ;
80
112
81
- // Return singleton object.
82
- return MP_OBJ_FROM_PTR (& rp2_flash_obj );
113
+ return MP_OBJ_FROM_PTR (self );
83
114
}
84
115
85
116
STATIC mp_obj_t rp2_flash_readblocks (size_t n_args , const mp_obj_t * args ) {
@@ -90,7 +121,7 @@ STATIC mp_obj_t rp2_flash_readblocks(size_t n_args, const mp_obj_t *args) {
90
121
if (n_args == 4 ) {
91
122
offset += mp_obj_get_int (args [3 ]);
92
123
}
93
- memcpy (bufinfo .buf , (void * )(XIP_BASE + self -> flash_base + offset ), bufinfo .len );
124
+ memcpy (bufinfo .buf , (void * )(XIP_BASE + self -> start + offset ), bufinfo .len );
94
125
return mp_const_none ;
95
126
}
96
127
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (rp2_flash_readblocks_obj , 3 , 4 , rp2_flash_readblocks );
@@ -103,7 +134,7 @@ STATIC mp_obj_t rp2_flash_writeblocks(size_t n_args, const mp_obj_t *args) {
103
134
if (n_args == 3 ) {
104
135
// Flash erase/program must run in an atomic section because the XIP bit gets disabled.
105
136
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION ();
106
- flash_range_erase (self -> flash_base + offset , bufinfo .len );
137
+ flash_range_erase (self -> start + offset , bufinfo .len );
107
138
MICROPY_END_ATOMIC_SECTION (atomic_state );
108
139
MICROPY_EVENT_POLL_HOOK
109
140
// TODO check return value
@@ -112,7 +143,7 @@ STATIC mp_obj_t rp2_flash_writeblocks(size_t n_args, const mp_obj_t *args) {
112
143
}
113
144
// Flash erase/program must run in an atomic section because the XIP bit gets disabled.
114
145
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION ();
115
- flash_range_program (self -> flash_base + offset , bufinfo .buf , bufinfo .len );
146
+ flash_range_program (self -> start + offset , bufinfo .buf , bufinfo .len );
116
147
MICROPY_END_ATOMIC_SECTION (atomic_state );
117
148
MICROPY_EVENT_POLL_HOOK
118
149
// TODO check return value
@@ -131,14 +162,14 @@ STATIC mp_obj_t rp2_flash_ioctl(mp_obj_t self_in, mp_obj_t cmd_in, mp_obj_t arg_
131
162
case MP_BLOCKDEV_IOCTL_SYNC :
132
163
return MP_OBJ_NEW_SMALL_INT (0 );
133
164
case MP_BLOCKDEV_IOCTL_BLOCK_COUNT :
134
- return MP_OBJ_NEW_SMALL_INT (self -> flash_size / BLOCK_SIZE_BYTES );
165
+ return MP_OBJ_NEW_SMALL_INT (self -> len / BLOCK_SIZE_BYTES );
135
166
case MP_BLOCKDEV_IOCTL_BLOCK_SIZE :
136
167
return MP_OBJ_NEW_SMALL_INT (BLOCK_SIZE_BYTES );
137
168
case MP_BLOCKDEV_IOCTL_BLOCK_ERASE : {
138
169
uint32_t offset = mp_obj_get_int (arg_in ) * BLOCK_SIZE_BYTES ;
139
170
// Flash erase/program must run in an atomic section because the XIP bit gets disabled.
140
171
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION ();
141
- flash_range_erase (self -> flash_base + offset , BLOCK_SIZE_BYTES );
172
+ flash_range_erase (self -> start + offset , BLOCK_SIZE_BYTES );
142
173
MICROPY_END_ATOMIC_SECTION (atomic_state );
143
174
// TODO check return value
144
175
return MP_OBJ_NEW_SMALL_INT (0 );
0 commit comments