diff --git a/ports/zephyr/modzephyr.c b/ports/zephyr/modzephyr.c index e24bdd0b9f..02ad35685b 100644 --- a/ports/zephyr/modzephyr.c +++ b/ports/zephyr/modzephyr.c @@ -95,6 +95,9 @@ STATIC const mp_rom_map_elem_t mp_module_time_globals_table[] = { #ifdef CONFIG_DISK_ACCESS { MP_ROM_QSTR(MP_QSTR_DiskAccess), MP_ROM_PTR(&zephyr_disk_access_type) }, #endif + #ifdef CONFIG_FLASH_MAP + { MP_ROM_QSTR(MP_QSTR_FlashArea), MP_ROM_PTR(&zephyr_flash_area_type) }, + #endif }; STATIC MP_DEFINE_CONST_DICT(mp_module_time_globals, mp_module_time_globals_table); diff --git a/ports/zephyr/modzephyr.h b/ports/zephyr/modzephyr.h index 28cb3dfe7c..f9b7e8eea1 100644 --- a/ports/zephyr/modzephyr.h +++ b/ports/zephyr/modzephyr.h @@ -33,4 +33,8 @@ extern const mp_obj_type_t zephyr_disk_access_type; #endif +#ifdef CONFIG_FLASH_MAP +extern const mp_obj_type_t zephyr_flash_area_type; +#endif + #endif // MICROPY_INCLUDED_ZEPHYR_MODZEPHYR_H diff --git a/ports/zephyr/prj_frdm_k64f.conf b/ports/zephyr/prj_frdm_k64f.conf index c2166c00df..483e9a29bb 100644 --- a/ports/zephyr/prj_frdm_k64f.conf +++ b/ports/zephyr/prj_frdm_k64f.conf @@ -8,3 +8,8 @@ CONFIG_I2C=y CONFIG_FXOS8700=y CONFIG_FXOS8700_MODE_HYBRID=y CONFIG_FXOS8700_TEMP=y + +# Flash drivers +CONFIG_FLASH=y +CONFIG_FLASH_MAP=y +CONFIG_MPU_ALLOW_FLASH_WRITE=y diff --git a/ports/zephyr/prj_reel_board.conf b/ports/zephyr/prj_reel_board.conf new file mode 100644 index 0000000000..a7ed230d14 --- /dev/null +++ b/ports/zephyr/prj_reel_board.conf @@ -0,0 +1,4 @@ +# Flash drivers +CONFIG_FLASH=y +CONFIG_FLASH_MAP=y +CONFIG_MPU_ALLOW_FLASH_WRITE=y diff --git a/ports/zephyr/prj_rv32m1_vega_ri5cy.conf b/ports/zephyr/prj_rv32m1_vega_ri5cy.conf new file mode 100644 index 0000000000..dcd6d7a08f --- /dev/null +++ b/ports/zephyr/prj_rv32m1_vega_ri5cy.conf @@ -0,0 +1,3 @@ +# Flash drivers +CONFIG_FLASH=y +CONFIG_FLASH_MAP=y diff --git a/ports/zephyr/zephyr_storage.c b/ports/zephyr/zephyr_storage.c index cd672dc0e9..ccbd06c141 100644 --- a/ports/zephyr/zephyr_storage.c +++ b/ports/zephyr/zephyr_storage.c @@ -35,6 +35,10 @@ #include #endif +#ifdef CONFIG_FLASH_MAP +#include +#endif + #ifdef CONFIG_DISK_ACCESS typedef struct _zephyr_disk_access_obj_t { mp_obj_base_t base; @@ -133,3 +137,125 @@ const mp_obj_type_t zephyr_disk_access_type = { .locals_dict = (mp_obj_dict_t*)&zephyr_disk_access_locals_dict, }; #endif // CONFIG_DISK_ACCESS + +#ifdef CONFIG_FLASH_MAP +const mp_obj_type_t zephyr_flash_area_type; + +typedef struct _zephyr_flash_area_obj_t { + mp_obj_base_t base; + const struct flash_area *area; + int block_size; + int block_count; + u8_t id; +} zephyr_flash_area_obj_t; + +STATIC void zephyr_flash_area_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + zephyr_flash_area_obj_t *self = self_in; + mp_printf(print, "FlashArea(%d)", self->id); +} + +STATIC mp_obj_t zephyr_flash_area_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 2, 2, false); + zephyr_flash_area_obj_t *self = m_new_obj(zephyr_flash_area_obj_t); + self->base.type = type; + self->id = mp_obj_get_int(args[0]); + self->block_size = mp_obj_get_int(args[1]); + + if (self->block_size <= 0) { + mp_raise_ValueError("invalid block size"); + } + + if (flash_area_open(self->id, &self->area) != 0) { + mp_raise_ValueError("unable to open flash area"); + } + + self->block_count = self->area->fa_size / self->block_size; + + return MP_OBJ_FROM_PTR(self); +} + +STATIC mp_obj_t zephyr_flash_area_readblocks(size_t n_args, const mp_obj_t *args) { + zephyr_flash_area_obj_t *self = MP_OBJ_TO_PTR(args[0]); + uint32_t block_num = mp_obj_get_int(args[1]); + off_t offset = block_num * self->block_size; + mp_buffer_info_t bufinfo; + int ret; + + if (n_args >= 4) { + offset += mp_obj_get_int(args[3]); + } + + mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_WRITE); + ret = flash_area_read(self->area, offset, bufinfo.buf, bufinfo.len); + return MP_OBJ_NEW_SMALL_INT(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(zephyr_flash_area_readblocks_obj, 3, 4, zephyr_flash_area_readblocks); + +STATIC mp_obj_t zephyr_flash_area_writeblocks(size_t n_args, const mp_obj_t *args) { + zephyr_flash_area_obj_t *self = MP_OBJ_TO_PTR(args[0]); + uint32_t block_num = mp_obj_get_int(args[1]); + off_t offset = block_num * self->block_size; + mp_buffer_info_t bufinfo; + int ret; + + if (n_args == 3) { + ret = flash_area_erase(self->area, offset, self->block_size); + if (ret) { + return MP_OBJ_NEW_SMALL_INT(ret); + } + } else { + offset += mp_obj_get_int(args[3]); + } + + mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ); + ret = flash_area_write(self->area, offset, bufinfo.buf, bufinfo.len); + return MP_OBJ_NEW_SMALL_INT(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(zephyr_flash_area_writeblocks_obj, 3, 4, zephyr_flash_area_writeblocks); + +STATIC mp_obj_t zephyr_flash_area_ioctl(mp_obj_t self_in, mp_obj_t cmd_in, mp_obj_t arg_in) { + zephyr_flash_area_obj_t *self = self_in; + mp_int_t cmd = mp_obj_get_int(cmd_in); + mp_int_t block_num = mp_obj_get_int(arg_in); + int ret; + + switch (cmd) { + case MP_BLOCKDEV_IOCTL_INIT: + case MP_BLOCKDEV_IOCTL_DEINIT: + case MP_BLOCKDEV_IOCTL_SYNC: + return MP_OBJ_NEW_SMALL_INT(0); + + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + return MP_OBJ_NEW_SMALL_INT(self->block_count); + + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + return MP_OBJ_NEW_SMALL_INT(self->block_size); + + case MP_BLOCKDEV_IOCTL_BLOCK_ERASE: + ret = flash_area_erase(self->area, block_num * self->block_size, self->block_size); + return MP_OBJ_NEW_SMALL_INT(ret); + + default: + return MP_OBJ_NEW_SMALL_INT(-1); + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(zephyr_flash_area_ioctl_obj, zephyr_flash_area_ioctl); + +STATIC const mp_rom_map_elem_t zephyr_flash_area_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&zephyr_flash_area_readblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&zephyr_flash_area_writeblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&zephyr_flash_area_ioctl_obj) }, + #ifdef DT_FLASH_AREA_STORAGE_ID + { MP_ROM_QSTR(MP_QSTR_STORAGE), MP_ROM_INT(DT_FLASH_AREA_STORAGE_ID) }, + #endif +}; +STATIC MP_DEFINE_CONST_DICT(zephyr_flash_area_locals_dict, zephyr_flash_area_locals_dict_table); + +const mp_obj_type_t zephyr_flash_area_type = { + { &mp_type_type }, + .name = MP_QSTR_FlashArea, + .print = zephyr_flash_area_print, + .make_new = zephyr_flash_area_make_new, + .locals_dict = (mp_obj_dict_t*)&zephyr_flash_area_locals_dict, +}; +#endif // CONFIG_FLASH_MAP