From 2e7866f634ddf31530c0c83ff8bdfc3b75f42e82 Mon Sep 17 00:00:00 2001 From: gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> Date: Sat, 30 Apr 2011 07:52:35 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2905 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/sdc_lld.c | 66 ++++++++++++++++++++++++++++++++++++++++ os/hal/platforms/STM32/sdc_lld.h | 12 ++++++++ os/hal/src/sdc.c | 2 ++ 3 files changed, 80 insertions(+) (limited to 'os') diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c index 48f8561f9..25c7b6897 100644 --- a/os/hal/platforms/STM32/sdc_lld.c +++ b/os/hal/platforms/STM32/sdc_lld.c @@ -119,6 +119,72 @@ void sdc_lld_stop(SDCDriver *sdcp) { } } +/** + * @brief Starts the SDIO clock and sets it to init mode (400KHz or less). + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @notapi + */ +void sdc_lld_start_clk(SDCDriver *sdcp) { + + (void)sdcp; + /* Initial clock setting: 400KHz, 1bit mode.*/ + SDIO->CLKCR = STM32_SDIO_DIV_LS; + SDIO->POWER |= SDIO_POWER_PWRCTRL_0 | SDIO_POWER_PWRCTRL_1; + SDIO->CLKCR |= SDIO_CLKCR_CLKEN; +} + +/** + * @brief Sets the SDIO clock to data mode (25MHz or less). + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @notapi + */ +void sdc_lld_set_data_clk(SDCDriver *sdcp) { + + (void)sdcp; + SDIO->CLKCR = (SDIO->CLKCR & 0xFFFFFF00) | STM32_SDIO_DIV_HS; +} + +/** + * @brief Stops the SDIO clock. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @notapi + */ +void sdc_lld_stop_clk(SDCDriver *sdcp) { + + (void)sdcp; + SDIO->CLKCR = 0; + SDIO->POWER = 0; +} + +/** + * @brief Switches the bus to 4 bits mode. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @notapi + */ +void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) { + uint32_t clk = SDIO->CLKCR & ~SDIO_CLKCR_WIDBUS; + + (void)sdcp; + switch (mode) { + case SDC_MODE_1BIT: + SDIO->CLKCR = clk; + break; + case SDC_MODE_4BIT: + SDIO->CLKCR = clk | SDIO_CLKCR_WIDBUS_0; + break; + case SDC_MODE_8BIT: + SDIO->CLKCR = clk | SDIO_CLKCR_WIDBUS_1; + } +} + /** * @brief Sends an SDIO command with no response expected. * diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h index 012fdb1c7..8ed64a5b0 100644 --- a/os/hal/platforms/STM32/sdc_lld.h +++ b/os/hal/platforms/STM32/sdc_lld.h @@ -89,6 +89,14 @@ /* Driver data structures and types. */ /*===========================================================================*/ +/** + * @brief Type of SDIO bus mode. + */ +typedef enum { + SDC_MODE_1BIT = 0, + SDC_MODE_4BIT, + SDC_MODE_8BIT +} sdcbusmode_t; /** * @brief Type of a structure representing an SDC driver. @@ -136,6 +144,10 @@ extern "C" { void sdc_lld_init(void); void sdc_lld_start(SDCDriver *sdcp); void sdc_lld_stop(SDCDriver *sdcp); + void sdc_lld_set_init_clk(SDCDriver *sdcp); + void sdc_lld_set_data_clk(SDCDriver *sdcp); + void sdc_lld_stop_clk(SDCDriver *sdcp); + void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode); void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg); bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, uint32_t *resp); diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 33f2b3612..701071b8b 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -135,6 +135,8 @@ bool_t sdcConnect(SDCDriver *sdcp) { sdcp->state = SDC_INITNG; chSysUnlock(); + sdc_lld_start_clk(sdcp); + sdcp->state = SDC_ACTIVE; return FALSE; } -- cgit v1.2.3