@@ -58,19 +58,23 @@ typedef struct {
5858 pin_obj_t * pin_clk ;
5959 bool pinsset ;
6060 bool enabled ;
61+ bool mounted ;
6162} pybsd_obj_t ;
6263
6364/******************************************************************************
6465 DECLARE PRIVATE DATA
6566 ******************************************************************************/
66- STATIC pybsd_obj_t pybsd_obj ;
67+ STATIC pybsd_obj_t pybsd_obj = {. pinsset = false, . enabled = false, . mounted = false} ;
6768
6869/******************************************************************************
6970 DECLARE PRIVATE FUNCTIONS
7071 ******************************************************************************/
72+ STATIC void pybsd_hw_init (pybsd_obj_t * self );
7173STATIC 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 );
72- STATIC mp_obj_t pybsd_disable (mp_obj_t self_in );
73- STATIC mp_obj_t pybsd_enable (mp_obj_t self_in );
74+ STATIC mp_obj_t pybsd_init (uint n_args , const mp_obj_t * args );
75+ STATIC mp_obj_t pybsd_deinit (mp_obj_t self_in );
76+ STATIC mp_obj_t pybsd_mount (mp_obj_t self_in );
77+ STATIC mp_obj_t pybsd_unmount (mp_obj_t self_in );
7478
7579/******************************************************************************
7680 DEFINE PUBLIC FUNCTIONS
@@ -81,15 +85,19 @@ void pybsd_init0 (void) {
8185 ASSERT ((pybsd_obj .fatfs = mem_Malloc (sizeof (FATFS ))) != NULL );
8286}
8387
84- void pybsd_deinit (void ) {
85- pybsd_disable ((mp_obj_t )& pybsd_obj );
88+ void pybsd_disable (void ) {
89+ pybsd_deinit ((mp_obj_t )& pybsd_obj );
90+ }
91+
92+ bool pybsd_is_mounted (void ) {
93+ return pybsd_obj .mounted ;
8694}
8795
8896/******************************************************************************
8997 DEFINE PRIVATE FUNCTIONS
9098 ******************************************************************************/
91- /// Initalizes the sd card driver
92- STATIC void pybsd_init (pybsd_obj_t * self ) {
99+ /// Initalizes the sd card hardware driver
100+ STATIC void pybsd_hw_init (pybsd_obj_t * self ) {
93101 // Configure the clock pin as output only
94102 MAP_PinDirModeSet (self -> pin_clk -> pin_num , PIN_DIR_MODE_OUT );
95103 // Enable SD peripheral clock
@@ -100,102 +108,140 @@ STATIC void pybsd_init (pybsd_obj_t *self) {
100108 MAP_SDHostInit (SDHOST_BASE );
101109 // Configure the card clock
102110 MAP_SDHostSetExpClk (SDHOST_BASE , MAP_PRCMPeripheralClockGet (PRCM_SDHOST ), PYBSD_FREQUENCY_HZ );
111+ // Set card rd/wr block len
112+ MAP_SDHostBlockSizeSet (SDHOST_BASE , SD_SECTOR_SIZE );
113+ }
114+
115+ STATIC mp_obj_t pybsd_init_helper (pybsd_obj_t * self , uint n_args , const mp_obj_t * args ) {
116+ if (n_args > 0 ) {
117+ if (mp_obj_get_type (args [0 ]) == & mp_type_tuple ) {
118+ mp_obj_t * items ;
119+ mp_obj_get_array_fixed_n (args [0 ], 6 , & items );
120+
121+ // save the clock pin for later use
122+ self -> pin_clk = (pin_obj_t * )pin_find (items [2 ]);
123+
124+ // configure the data pin with pull-up enabled
125+ pin_config ((pin_obj_t * )pin_find (items [0 ]), mp_obj_get_int (items [1 ]), 0 , PIN_TYPE_STD_PU , PIN_STRENGTH_4MA );
126+ // configure the clock pin
127+ pin_config (self -> pin_clk , mp_obj_get_int (items [3 ]), 0 , PIN_TYPE_STD , PIN_STRENGTH_4MA );
128+ // configure the command pin with pull-up enabled
129+ pin_config ((pin_obj_t * )pin_find (items [4 ]), mp_obj_get_int (items [5 ]), 0 , PIN_TYPE_STD_PU , PIN_STRENGTH_4MA );
130+ self -> pinsset = true;
131+ } else {
132+ nlr_raise (mp_obj_new_exception_msg (& mp_type_TypeError , mpexception_num_type_invalid_arguments ));
133+ }
134+ }
135+
136+ if (!self -> enabled ) {
137+ if (!self -> pinsset ) {
138+ nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , mpexception_os_request_not_possible ));
139+ }
140+ pybsd_hw_init (self );
141+ // mark as enabled and register it with the sleep module
142+ self -> enabled = true;
143+ pybsleep_add ((const mp_obj_t )self , (WakeUpCB_t )pybsd_hw_init );
144+ }
145+ return mp_const_none ;
103146}
104147
105148/******************************************************************************/
106149// Micro Python bindings
107150//
108151
109152/// \classmethod \constructor()
110- /// Configure the pins used for the sd card.
111- /// May receive 0, or 6 arguments.
153+ /// Creates an SD card object.
154+ /// Accepts a tuple of pins an alternate functions to configure the SD card interface.
155+ /// When called with no arguments it returns the previoulsy created SD card object.
112156///
113157/// Usage:
114158/// sd = pyb.SD()
115- ////
116- /// sd = pyb.SD(d0_pin, d0_af, clk_pin, clk_af, cmd_pin, cmd_af)
159+ /// Or:
160+ /// sd = pyb.SD(( d0_pin, d0_af, clk_pin, clk_af, cmd_pin, cmd_af) )
117161///
118162STATIC 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 ) {
119- mp_arg_check_num (n_args , n_kw , 0 , 6 , false);
163+ mp_arg_check_num (n_args , n_kw , 0 , 1 , false);
164+ mp_obj_t self = & pybsd_obj ;
165+ pybsd_obj .base .type = & pyb_sd_type ;
120166
121- if (n_args == 6 ) {
122- // save the clock pin for later use
123- pybsd_obj .pin_clk = (pin_obj_t * )pin_find (args [2 ]);
124-
125- // configure the data pin with pull-up enabled
126- pin_config ((pin_obj_t * )pin_find (args [0 ]), mp_obj_get_int (args [1 ]), 0 , PIN_TYPE_STD_PU , PIN_STRENGTH_4MA );
127- // configure the clock pin
128- pin_config (pybsd_obj .pin_clk , mp_obj_get_int (args [3 ]), 0 , PIN_TYPE_STD , PIN_STRENGTH_4MA );
129- // configure the command pin with pull-up enabled
130- pin_config ((pin_obj_t * )pin_find (args [4 ]), mp_obj_get_int (args [5 ]), 0 , PIN_TYPE_STD_PU , PIN_STRENGTH_4MA );
131-
132- pybsd_obj .pinsset = true;
133- pybsd_obj .base .type = & pyb_sd_type ;
134- }
135- else if (!pybsd_obj .pinsset ) {
136- nlr_raise (mp_obj_new_exception_msg (& mp_type_TypeError , mpexception_num_type_invalid_arguments ));
167+ if (n_args > 0 ) {
168+ pybsd_init_helper (self , n_args , args );
137169 }
170+ return self ;
171+ }
138172
139- return & pybsd_obj ;
173+ /// \method init()
174+ /// Enables the sd card
175+ STATIC mp_obj_t pybsd_init (uint n_args , const mp_obj_t * args ) {
176+ return pybsd_init_helper (args [0 ], n_args - 1 , args + 1 );
140177}
178+ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (pybsd_init_obj , 1 , 2 , pybsd_init );
141179
142- /// \method enable ()
143- /// Enables the sd card and mounts the file system
144- STATIC mp_obj_t pybsd_enable (mp_obj_t self_in ) {
180+ /// \method deinit ()
181+ /// Disables the sd card
182+ STATIC mp_obj_t pybsd_deinit (mp_obj_t self_in ) {
145183 pybsd_obj_t * self = self_in ;
184+ if (self -> enabled ) {
185+ // unmounted in case not done yet
186+ pybsd_unmount (self );
187+ self -> enabled = false;
188+ // disable the peripheral
189+ MAP_PRCMPeripheralClkDisable (PRCM_SDHOST , PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK );
190+ // de-initialze the sd card at diskio level
191+ sd_disk_deinit ();
192+ // unregister it with the sleep module
193+ pybsleep_remove (self );
194+ }
195+ return mp_const_none ;
196+ }
197+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (pybsd_deinit_obj , pybsd_deinit );
146198
147- if (!self -> enabled ) {
148- // do the init first
149- pybsd_init (self );
150-
199+ /// \method mount()
200+ /// Mount the sd card on /sd
201+ STATIC mp_obj_t pybsd_mount (mp_obj_t self_in ) {
202+ pybsd_obj_t * self = self_in ;
203+ if (!self -> mounted ) {
204+ if (!self -> enabled ) {
205+ nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , mpexception_os_request_not_possible ));
206+ }
151207 // try to mount the sd card on /sd
152208 if (FR_OK != f_mount (self -> fatfs , "/sd" , 1 )) {
153209 nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , mpexception_os_operation_failed ));
154210 }
155-
156211 mp_obj_list_append (mp_sys_path , MP_OBJ_NEW_QSTR (MP_QSTR__slash_sd ));
157212 mp_obj_list_append (mp_sys_path , MP_OBJ_NEW_QSTR (MP_QSTR__slash_sd_slash_lib ));
158-
159- // register it with the sleep module
160- pybsleep_add ((const mp_obj_t )& pybsd_obj , (WakeUpCB_t )pybsd_init );
161- self -> enabled = true;
213+ self -> mounted = true;
162214 }
163-
164215 return mp_const_none ;
165216}
166- STATIC MP_DEFINE_CONST_FUN_OBJ_1 (pybsd_enable_obj , pybsd_enable );
217+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (pybsd_mount_obj , pybsd_mount );
167218
168- /// \method disable ()
169- /// Disables the sd card and unmounts the file system
170- STATIC mp_obj_t pybsd_disable (mp_obj_t self_in ) {
219+ /// \method unmount ()
220+ /// Unmount the sd card
221+ STATIC mp_obj_t pybsd_unmount (mp_obj_t self_in ) {
171222 pybsd_obj_t * self = self_in ;
172- if (self -> enabled ) {
173- self -> enabled = false;
223+ if (self -> mounted ) {
224+ if (!self -> enabled ) {
225+ nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , mpexception_os_request_not_possible ));
226+ }
174227 // unmount the sd card
175228 f_mount (NULL , "/sd" , 1 );
176229 // remove sd paths from mp_sys_path
177230 mp_obj_list_remove (mp_sys_path , MP_OBJ_NEW_QSTR (MP_QSTR__slash_sd ));
178231 mp_obj_list_remove (mp_sys_path , MP_OBJ_NEW_QSTR (MP_QSTR__slash_sd_slash_lib ));
179-
180- // disable the peripheral
181- MAP_PRCMPeripheralClkDisable (PRCM_SDHOST , PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK );
182-
183- // de-initialze de sd card at diskio level
184- sd_disk_deinit ();
185-
186- // unregister it with the sleep module
187- pybsleep_remove (self );
188-
232+ self -> mounted = false;
189233 // change the drive in case it was /sd
190234 f_chdrive ("/flash" );
191235 }
192236 return mp_const_none ;
193237}
194- STATIC MP_DEFINE_CONST_FUN_OBJ_1 (pybsd_disable_obj , pybsd_disable );
238+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (pybsd_unmount_obj , pybsd_unmount );
195239
196240STATIC const mp_map_elem_t pybsd_locals_dict_table [] = {
197- { MP_OBJ_NEW_QSTR (MP_QSTR_enable ), (mp_obj_t )& pybsd_enable_obj },
198- { MP_OBJ_NEW_QSTR (MP_QSTR_disable ), (mp_obj_t )& pybsd_disable_obj },
241+ { MP_OBJ_NEW_QSTR (MP_QSTR_init ), (mp_obj_t )& pybsd_init_obj },
242+ { MP_OBJ_NEW_QSTR (MP_QSTR_deinit ), (mp_obj_t )& pybsd_deinit_obj },
243+ { MP_OBJ_NEW_QSTR (MP_QSTR_mount ), (mp_obj_t )& pybsd_mount_obj },
244+ { MP_OBJ_NEW_QSTR (MP_QSTR_unmount ), (mp_obj_t )& pybsd_unmount_obj },
199245};
200246STATIC MP_DEFINE_CONST_DICT (pybsd_locals_dict , pybsd_locals_dict_table );
201247
0 commit comments