Skip to content

Commit

Permalink
Add BBIO SDIO frequency switch
Browse files Browse the repository at this point in the history
  • Loading branch information
Baldanos committed May 10, 2023
1 parent d6d6586 commit 4d74500
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/common/mode_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ typedef struct {

typedef struct {
uint8_t bus_width;
uint8_t frequency_divider;
} sdio_config_t;

#define MODE_CONFIG_PROTO_BUFFER_SIZE (256)
Expand Down
84 changes: 68 additions & 16 deletions src/drv/stm32cube/bsp_sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ limitations under the License.
/*
Warning in order to use this driver all GPIOs peripherals shall be enabled.
*/
#define SDIO_TIMEOUT_MAX (100000) // About 10sec (see common/chconf.h/CH_CFG_ST_FREQUENCY) can be aborted by UBTN too
#define SDIO_TIMEOUT_MAX (0x100000) // About 10sec (see common/chconf.h/CH_CFG_ST_FREQUENCY)
#define NB_SDIO (1)

static mode_config_proto_t* sdio_mode_conf[NB_SDIO];
Expand Down Expand Up @@ -56,6 +56,27 @@ static void sdio_gpio_hw_init(bsp_dev_sdio_t dev_num)
HAL_GPIO_Init(BSP_SDIO_D0_PORT, &GPIO_InitStructure);
}

/**
* @brief Switch CMD and Data line to push-pull
* @param dev_num: SDIO dev num
* @retval None
*/
static void sdio_gpio_hw_init_high(bsp_dev_sdio_t dev_num)
{
GPIO_InitTypeDef GPIO_InitStructure;
(void)dev_num;

GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = BSP_SDIO_GPIO_SPEED;
GPIO_InitStructure.Alternate = BSP_SDIO_AF;

GPIO_InitStructure.Pin = BSP_SDIO_CMD_PIN;
HAL_GPIO_Init(BSP_SDIO_CMD_PORT, &GPIO_InitStructure);

GPIO_InitStructure.Pin = BSP_SDIO_D0_PIN;
HAL_GPIO_Init(BSP_SDIO_D0_PORT, &GPIO_InitStructure);
}
/**
* @brief DeInit low level hardware: GPIO, CLOCK, NVIC...
* @param dev_num: SDIO dev num
Expand Down Expand Up @@ -122,7 +143,7 @@ bsp_status_t bsp_sdio_init(bsp_dev_sdio_t dev_num, mode_config_proto_t* mode_con
init.BusWide = SDIO_BUS_WIDE_1B;
}
init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
init.ClockDiv = SDIO_INIT_CLK_DIV;
init.ClockDiv = sdio_mode_conf[dev_num]->config.sdio.frequency_divider;

status = (bsp_status_t) SDIO_Init(hsdio, init);

Expand Down Expand Up @@ -214,7 +235,7 @@ bsp_status_t bsp_sdio_write_data(bsp_dev_sdio_t dev_num, uint8_t cmdid, uint32_t
uint16_t count, remaining=512;

/* Configure the SD DPSM (Data Path State Machine) */
config.DataTimeOut = SDMMC_DATATIMEOUT;
config.DataTimeOut = SDIO_TIMEOUT_MAX;
config.DataLength = BSP_SDIO_BLOCK_LEN;
config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
Expand All @@ -229,19 +250,26 @@ bsp_status_t bsp_sdio_write_data(bsp_dev_sdio_t dev_num, uint8_t cmdid, uint32_t
if(__SDIO_GET_FLAG(SDIO, SDIO_FLAG_TXFIFOHE) && (remaining > 0)) {
for(count = 0; count < 8; count++) {
tmp = pData[(BSP_SDIO_BLOCK_LEN-remaining)>>2];
tmp = reverse_u32(tmp);
(void)SDIO_WriteFIFO(SDIO, &tmp);
remaining -=4;
}
}
}

__SDIO_CLEAR_FLAG(SDIO, SDIO_STATIC_CMD_FLAGS);
__SDIO_CLEAR_FLAG(SDIO, SDIO_STATIC_DATA_FLAGS);
if(remaining == 0) {
__SDIO_CLEAR_FLAG(SDIO, SDIO_STATIC_DATA_FLAGS);
return BSP_OK;
} else {
return BSP_ERROR;
if (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_DTIMEOUT)) {
__SDIO_CLEAR_FLAG(SDIO, SDIO_STATIC_DATA_FLAGS);
return BSP_TIMEOUT;
} else {
__SDIO_CLEAR_FLAG(SDIO, SDIO_STATIC_DATA_FLAGS);
config.DPSM = SDIO_DPSM_DISABLE;
(void)SDIO_ConfigData(SDIO, &config);
return BSP_ERROR;
}
}
}

Expand All @@ -254,7 +282,7 @@ bsp_status_t bsp_sdio_read_data(bsp_dev_sdio_t dev_num, uint8_t cmdid, uint32_t
uint16_t count, remaining = 512;

/* Configure the SD DPSM (Data Path State Machine) */
config.DataTimeOut = SDMMC_DATATIMEOUT;
config.DataTimeOut = SDIO_TIMEOUT_MAX;
config.DataLength = BSP_SDIO_BLOCK_LEN;
config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
Expand All @@ -271,18 +299,25 @@ bsp_status_t bsp_sdio_read_data(bsp_dev_sdio_t dev_num, uint8_t cmdid, uint32_t
/* Read data from SDIO Rx FIFO */
for(count = 0; count < 8; count++) {
tmp = SDIO_ReadFIFO(SDIO);
tmp = reverse_u32(tmp);
pData[(BSP_SDIO_BLOCK_LEN-remaining)>>2] = tmp;
remaining -=4;
}
}
}
__SDIO_CLEAR_FLAG(SDIO, SDIO_STATIC_CMD_FLAGS);
__SDIO_CLEAR_FLAG(SDIO, SDIO_STATIC_DATA_FLAGS);
if(remaining == 0) {
__SDIO_CLEAR_FLAG(SDIO, SDIO_STATIC_DATA_FLAGS);
return BSP_OK;
} else {
return BSP_ERROR;
if (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_DTIMEOUT)) {
__SDIO_CLEAR_FLAG(SDIO, SDIO_STATIC_DATA_FLAGS);
return BSP_TIMEOUT;
} else {
__SDIO_CLEAR_FLAG(SDIO, SDIO_STATIC_DATA_FLAGS);
config.DPSM = SDIO_DPSM_DISABLE;
(void)SDIO_ConfigData(SDIO, &config);
return BSP_ERROR;
}
}
}

Expand All @@ -295,14 +330,31 @@ bsp_status_t bsp_sdio_change_bus_width(bsp_dev_sdio_t dev_num, uint8_t bus_size)
case 1:
case 4:
sdio_mode_conf[dev_num]->config.sdio.bus_width = bus_size;
if(bsp_sdio_deinit(dev_num) == BSP_OK) {
/* Re-Initialize the SDIO comunication bus */
bsp_sdio_init(dev_num, sdio_mode_conf[dev_num]);
}
status = BSP_OK;
break;
default:
status = BSP_ERROR;
return BSP_ERROR;
}
SDIO_TypeDef* hsdio;
SDIO_InitTypeDef init;

hsdio = SDIO;

init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
if(sdio_mode_conf[dev_num]->config.sdio.bus_width ==4) {
init.BusWide = SDIO_BUS_WIDE_4B;
} else {
init.BusWide = SDIO_BUS_WIDE_1B;
}
init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
init.ClockDiv = sdio_mode_conf[dev_num]->config.sdio.frequency_divider;

if(init.ClockDiv < BSP_SDIO_CLOCK_SLOW) {
sdio_gpio_hw_init_high(dev_num);
}

status = (bsp_status_t) SDIO_Init(hsdio, init);

return status;
}
2 changes: 2 additions & 0 deletions src/drv/stm32cube/bsp_sdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ limitations under the License.
#include "mode_config.h"

#define BSP_SDIO_BLOCK_LEN 512
#define BSP_SDIO_CLOCK_SLOW SDIO_INIT_CLK_DIV
#define BSP_SDIO_CLOCK_FAST 0x0

typedef enum {
BSP_DEV_SDIO1 = 0,
Expand Down
6 changes: 5 additions & 1 deletion src/hydrabus/hydrabus_bbio_sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void bbio_sdio_init_proto_default(t_hydra_console *con)
mode_config_proto_t* proto = &con->mode->proto;

proto->config.sdio.bus_width = 1;
proto->config.sdio.frequency_divider = BSP_SDIO_CLOCK_SLOW;

/* Defaults */
proto->dev_num = BSP_DEV_SDIO1;
Expand Down Expand Up @@ -133,8 +134,11 @@ void bbio_mode_sdio(t_hydra_console *con)
}
break;
}
if ((bbio_subcommand & BBIO_SDIO_CONFIG) == BBIO_SDIO_CONFIG) {
if ((bbio_subcommand & BBIO_AUX_MASK) == BBIO_AUX_MASK) {
cprintf(con, "%c", bbio_aux(con, bbio_subcommand));
} else if ((bbio_subcommand & BBIO_SDIO_CONFIG) == BBIO_SDIO_CONFIG) {
proto->config.sdio.bus_width = (bbio_subcommand & 0b1)?4:1;
proto->config.sdio.frequency_divider = (bbio_subcommand & 0b10)?BSP_SDIO_CLOCK_FAST:BSP_SDIO_CLOCK_SLOW;
status = bsp_sdio_change_bus_width(proto->dev_num, proto->config.sdio.bus_width);
if(status == BSP_OK) {
cprint(con, "\x01", 1);
Expand Down

0 comments on commit 4d74500

Please sign in to comment.