diff options
| author | Daniel Campora | 2015-08-11 16:06:43 +0200 |
|---|---|---|
| committer | Daniel Campora | 2015-08-16 20:17:58 +0200 |
| commit | 11d21081b4321ff4a1078b728911fe15fea94509 (patch) | |
| tree | ec51b860f3736ad1a76698f660f234e771942f32 /cc3200/mods/pybsd.c | |
| parent | 34c290b678f6ba3a903754aad16758a007286b46 (diff) | |
cc3200: Rework SD API. Increase heap to avoid malloc failures.
Diffstat (limited to 'cc3200/mods/pybsd.c')
| -rw-r--r-- | cc3200/mods/pybsd.c | 168 |
1 files changed, 107 insertions, 61 deletions
diff --git a/cc3200/mods/pybsd.c b/cc3200/mods/pybsd.c index c5444b591..110356adc 100644 --- a/cc3200/mods/pybsd.c +++ b/cc3200/mods/pybsd.c @@ -58,19 +58,23 @@ typedef struct { pin_obj_t *pin_clk; bool pinsset; bool enabled; + bool mounted; } pybsd_obj_t; /****************************************************************************** DECLARE PRIVATE DATA ******************************************************************************/ -STATIC pybsd_obj_t pybsd_obj; +STATIC pybsd_obj_t pybsd_obj = {.pinsset = false, .enabled = false, .mounted = false}; /****************************************************************************** DECLARE PRIVATE FUNCTIONS ******************************************************************************/ +STATIC void pybsd_hw_init (pybsd_obj_t *self); STATIC mp_obj_t pybsd_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args); -STATIC mp_obj_t pybsd_disable (mp_obj_t self_in); -STATIC mp_obj_t pybsd_enable (mp_obj_t self_in); +STATIC mp_obj_t pybsd_init (uint n_args, const mp_obj_t *args); +STATIC mp_obj_t pybsd_deinit (mp_obj_t self_in); +STATIC mp_obj_t pybsd_mount (mp_obj_t self_in); +STATIC mp_obj_t pybsd_unmount (mp_obj_t self_in); /****************************************************************************** DEFINE PUBLIC FUNCTIONS @@ -81,15 +85,19 @@ void pybsd_init0 (void) { ASSERT ((pybsd_obj.fatfs = mem_Malloc(sizeof(FATFS))) != NULL); } -void pybsd_deinit (void) { - pybsd_disable ((mp_obj_t)&pybsd_obj); +void pybsd_disable (void) { + pybsd_deinit ((mp_obj_t)&pybsd_obj); +} + +bool pybsd_is_mounted (void) { + return pybsd_obj.mounted; } /****************************************************************************** DEFINE PRIVATE FUNCTIONS ******************************************************************************/ -/// Initalizes the sd card driver -STATIC void pybsd_init (pybsd_obj_t *self) { +/// Initalizes the sd card hardware driver +STATIC void pybsd_hw_init (pybsd_obj_t *self) { // Configure the clock pin as output only MAP_PinDirModeSet(self->pin_clk->pin_num, PIN_DIR_MODE_OUT); // Enable SD peripheral clock @@ -100,6 +108,41 @@ STATIC void pybsd_init (pybsd_obj_t *self) { MAP_SDHostInit(SDHOST_BASE); // Configure the card clock MAP_SDHostSetExpClk(SDHOST_BASE, MAP_PRCMPeripheralClockGet(PRCM_SDHOST), PYBSD_FREQUENCY_HZ); + // Set card rd/wr block len + MAP_SDHostBlockSizeSet(SDHOST_BASE, SD_SECTOR_SIZE); +} + +STATIC mp_obj_t pybsd_init_helper (pybsd_obj_t *self, uint n_args, const mp_obj_t *args) { + if (n_args > 0) { + if (mp_obj_get_type(args[0]) == &mp_type_tuple) { + mp_obj_t *items; + mp_obj_get_array_fixed_n(args[0], 6, &items); + + // save the clock pin for later use + self->pin_clk = (pin_obj_t *)pin_find(items[2]); + + // configure the data pin with pull-up enabled + pin_config ((pin_obj_t *)pin_find(items[0]), mp_obj_get_int(items[1]), 0, PIN_TYPE_STD_PU, PIN_STRENGTH_4MA); + // configure the clock pin + pin_config (self->pin_clk, mp_obj_get_int(items[3]), 0, PIN_TYPE_STD, PIN_STRENGTH_4MA); + // configure the command pin with pull-up enabled + pin_config ((pin_obj_t *)pin_find(items[4]), mp_obj_get_int(items[5]), 0, PIN_TYPE_STD_PU, PIN_STRENGTH_4MA); + self->pinsset = true; + } else { + nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments)); + } + } + + if (!self->enabled) { + if (!self->pinsset) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible)); + } + pybsd_hw_init (self); + // mark as enabled and register it with the sleep module + self->enabled = true; + pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pybsd_hw_init); + } + return mp_const_none; } /******************************************************************************/ @@ -107,95 +150,98 @@ STATIC void pybsd_init (pybsd_obj_t *self) { // /// \classmethod \constructor() -/// Configure the pins used for the sd card. -/// May receive 0, or 6 arguments. +/// Creates an SD card object. +/// Accepts a tuple of pins an alternate functions to configure the SD card interface. +/// When called with no arguments it returns the previoulsy created SD card object. /// /// Usage: /// sd = pyb.SD() -//// -/// sd = pyb.SD(d0_pin, d0_af, clk_pin, clk_af, cmd_pin, cmd_af) +/// Or: +/// sd = pyb.SD((d0_pin, d0_af, clk_pin, clk_af, cmd_pin, cmd_af)) /// STATIC mp_obj_t pybsd_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 6, false); + mp_arg_check_num(n_args, n_kw, 0, 1, false); + mp_obj_t self = &pybsd_obj; + pybsd_obj.base.type = &pyb_sd_type; - if (n_args == 6) { - // save the clock pin for later use - pybsd_obj.pin_clk = (pin_obj_t *)pin_find(args[2]); - - // configure the data pin with pull-up enabled - pin_config ((pin_obj_t *)pin_find(args[0]), mp_obj_get_int(args[1]), 0, PIN_TYPE_STD_PU, PIN_STRENGTH_4MA); - // configure the clock pin - pin_config (pybsd_obj.pin_clk, mp_obj_get_int(args[3]), 0, PIN_TYPE_STD, PIN_STRENGTH_4MA); - // configure the command pin with pull-up enabled - pin_config ((pin_obj_t *)pin_find(args[4]), mp_obj_get_int(args[5]), 0, PIN_TYPE_STD_PU, PIN_STRENGTH_4MA); - - pybsd_obj.pinsset = true; - pybsd_obj.base.type = &pyb_sd_type; - } - else if (!pybsd_obj.pinsset) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments)); + if (n_args > 0) { + pybsd_init_helper (self, n_args, args); } + return self; +} - return &pybsd_obj; +/// \method init() +/// Enables the sd card +STATIC mp_obj_t pybsd_init (uint n_args, const mp_obj_t *args) { + return pybsd_init_helper(args[0], n_args - 1, args + 1); } +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pybsd_init_obj, 1, 2, pybsd_init); -/// \method enable() -/// Enables the sd card and mounts the file system -STATIC mp_obj_t pybsd_enable (mp_obj_t self_in) { +/// \method deinit() +/// Disables the sd card +STATIC mp_obj_t pybsd_deinit (mp_obj_t self_in) { pybsd_obj_t *self = self_in; + if (self->enabled) { + // unmounted in case not done yet + pybsd_unmount (self); + self->enabled = false; + // disable the peripheral + MAP_PRCMPeripheralClkDisable(PRCM_SDHOST, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK); + // de-initialze the sd card at diskio level + sd_disk_deinit(); + // unregister it with the sleep module + pybsleep_remove (self); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pybsd_deinit_obj, pybsd_deinit); - if (!self->enabled) { - // do the init first - pybsd_init (self); - +/// \method mount() +/// Mount the sd card on /sd +STATIC mp_obj_t pybsd_mount (mp_obj_t self_in) { + pybsd_obj_t *self = self_in; + if (!self->mounted) { + if (!self->enabled) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible)); + } // try to mount the sd card on /sd if (FR_OK != f_mount(self->fatfs, "/sd", 1)) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); } - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib)); - - // register it with the sleep module - pybsleep_add ((const mp_obj_t)&pybsd_obj, (WakeUpCB_t)pybsd_init); - self->enabled = true; + self->mounted = true; } - return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(pybsd_enable_obj, pybsd_enable); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pybsd_mount_obj, pybsd_mount); -/// \method disable() -/// Disables the sd card and unmounts the file system -STATIC mp_obj_t pybsd_disable (mp_obj_t self_in) { +/// \method unmount() +/// Unmount the sd card +STATIC mp_obj_t pybsd_unmount (mp_obj_t self_in) { pybsd_obj_t *self = self_in; - if (self->enabled) { - self->enabled = false; + if (self->mounted) { + if (!self->enabled) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible)); + } // unmount the sd card f_mount (NULL, "/sd", 1); // remove sd paths from mp_sys_path mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd)); mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib)); - - // disable the peripheral - MAP_PRCMPeripheralClkDisable(PRCM_SDHOST, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK); - - // de-initialze de sd card at diskio level - sd_disk_deinit(); - - // unregister it with the sleep module - pybsleep_remove (self); - + self->mounted = false; // change the drive in case it was /sd f_chdrive("/flash"); } return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(pybsd_disable_obj, pybsd_disable); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pybsd_unmount_obj, pybsd_unmount); STATIC const mp_map_elem_t pybsd_locals_dict_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&pybsd_enable_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&pybsd_disable_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pybsd_init_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pybsd_deinit_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&pybsd_mount_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_unmount), (mp_obj_t)&pybsd_unmount_obj }, }; STATIC MP_DEFINE_CONST_DICT(pybsd_locals_dict, pybsd_locals_dict_table); |
