@ -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