diff options
| author | Damien George | 2016-02-10 16:21:38 +0000 |
|---|---|---|
| committer | Damien George | 2016-02-10 23:40:10 +0000 |
| commit | 3770cd2e7062d0844cee7b69ec9d9f80a2ad1206 (patch) | |
| tree | ceb2161c79c2c09552e4eeaf2b36db07c2b292a5 /stmhal/sdcard.c | |
| parent | f7e5e677df120122eeaac18b81d3fccfe0965180 (diff) | |
stmhal: Expose flash and SD card as proper objects with block protocol.
You can now create (singleton) objects representing the flash and SD
card, using:
flash = pyb.Flash()
sdcard = pyb.SDCard()
These objects provide the block protocol.
Diffstat (limited to 'stmhal/sdcard.c')
| -rw-r--r-- | stmhal/sdcard.c | 84 |
1 files changed, 72 insertions, 12 deletions
diff --git a/stmhal/sdcard.c b/stmhal/sdcard.c index ae1852519..fb480bbec 100644 --- a/stmhal/sdcard.c +++ b/stmhal/sdcard.c @@ -24,10 +24,11 @@ * THE SOFTWARE. */ -#include STM32_HAL_H - #include "py/nlr.h" #include "py/runtime.h" +#include "lib/fatfs/ff.h" +#include "extmod/fsusermount.h" + #include "sdcard.h" #include "pin.h" #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 /******************************************************************************/ // Micro Python bindings // -// Note: these function are a bit ad-hoc at the moment and are mainly intended -// for testing purposes. In the future SD should be a proper class with a -// consistent interface and methods to mount/unmount it. +// Expose the SD card as an object with the block protocol. + +// there is a singleton SDCard object +const mp_obj_base_t pyb_sdcard_obj = {&pyb_sdcard_type}; + +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) { + // check arguments + mp_arg_check_num(n_args, n_kw, 0, 0, false); + + // return singleton object + return (mp_obj_t)&pyb_sdcard_obj; +} STATIC mp_obj_t sd_present(mp_obj_t self) { return mp_obj_new_bool(sdcard_is_present()); @@ -316,6 +326,7 @@ STATIC mp_obj_t sd_info(mp_obj_t self) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(sd_info_obj, sd_info); +// now obsolete, kept for backwards compatibility STATIC mp_obj_t sd_read(mp_obj_t self, mp_obj_t block_num) { uint8_t *dest = m_new(uint8_t, SDCARD_BLOCK_SIZE); 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) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(sd_read_obj, sd_read); +// now obsolete, kept for backwards compatibility STATIC mp_obj_t sd_write(mp_obj_t self, mp_obj_t block_num, mp_obj_t data) { mp_buffer_info_t bufinfo; 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) { } STATIC MP_DEFINE_CONST_FUN_OBJ_3(sd_write_obj, sd_write); -STATIC const mp_map_elem_t sdcard_locals_dict_table[] = { +STATIC mp_obj_t pyb_sdcard_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE); + mp_uint_t ret = sdcard_read_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SDCARD_BLOCK_SIZE); + return mp_obj_new_bool(ret == 0); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_sdcard_readblocks_obj, pyb_sdcard_readblocks); + +STATIC mp_obj_t pyb_sdcard_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ); + mp_uint_t ret = sdcard_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SDCARD_BLOCK_SIZE); + return mp_obj_new_bool(ret == 0); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_sdcard_writeblocks_obj, pyb_sdcard_writeblocks); + +STATIC mp_obj_t pyb_sdcard_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) { + mp_int_t cmd = mp_obj_get_int(cmd_in); + switch (cmd) { + case 1: // INIT + if (!sdcard_power_on()) { + return MP_OBJ_NEW_SMALL_INT(-1); // error + } + return MP_OBJ_NEW_SMALL_INT(0); // success + + case 2: // DEINIT + sdcard_power_off(); + return MP_OBJ_NEW_SMALL_INT(0); // success + + case 3: // SYNC + // nothing to do + return MP_OBJ_NEW_SMALL_INT(0); // success + + case 4: // SEC_COUNT + return MP_OBJ_NEW_SMALL_INT(0); // TODO + + case 5: // SEC_SIZE + return MP_OBJ_NEW_SMALL_INT(SDCARD_BLOCK_SIZE); + + default: // unknown command + return MP_OBJ_NEW_SMALL_INT(-1); // error + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_sdcard_ioctl_obj, pyb_sdcard_ioctl); + +STATIC const mp_map_elem_t pyb_sdcard_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_present), (mp_obj_t)&sd_present_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_power), (mp_obj_t)&sd_power_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&sd_info_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&sd_read_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&sd_write_obj }, + // block device protocol + { MP_OBJ_NEW_QSTR(MP_QSTR_readblocks), (mp_obj_t)&pyb_sdcard_readblocks_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_writeblocks), (mp_obj_t)&pyb_sdcard_writeblocks_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ioctl), (mp_obj_t)&pyb_sdcard_ioctl_obj }, }; -STATIC MP_DEFINE_CONST_DICT(sdcard_locals_dict, sdcard_locals_dict_table); +STATIC MP_DEFINE_CONST_DICT(pyb_sdcard_locals_dict, pyb_sdcard_locals_dict_table); -static const mp_obj_type_t sdcard_type = { +const mp_obj_type_t pyb_sdcard_type = { { &mp_type_type }, - .name = MP_QSTR_SDcard, - .locals_dict = (mp_obj_t)&sdcard_locals_dict, + .name = MP_QSTR_SDCard, + .make_new = pyb_sdcard_make_new, + .locals_dict = (mp_obj_t)&pyb_sdcard_locals_dict, }; -const mp_obj_base_t pyb_sdcard_obj = {&sdcard_type}; - #endif // MICROPY_HW_HAS_SDCARD |
