Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/common/mode_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ typedef struct {
uint8_t dev_polarity;
uint8_t dev_phase;
uint8_t dev_bit_lsb_msb;
uint8_t dev_bidir;
} spi_config_t;

typedef struct {
Expand Down
30 changes: 26 additions & 4 deletions src/drv/stm32cube/bsp_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,12 @@ bsp_status_t bsp_spi_init(bsp_dev_spi_t dev_num, mode_config_proto_t* mode_conf)
/* SW NSS user shall call bsp_spi_select()/bsp_spi_unselect() */
hspi->Init.NSS = SPI_NSS_SOFT;
hspi->Init.BaudRatePrescaler = ((7 - mode_conf->config.spi.dev_speed) * SPI_CR1_BR_0);
hspi->Init.Direction = SPI_DIRECTION_2LINES;
/* Half-duplex / bidirectional or normal 2-line */
if(mode_conf->config.spi.dev_bidir == 0) {
hspi->Init.Direction = SPI_DIRECTION_2LINES;
} else {
hspi->Init.Direction = SPI_DIRECTION_1LINE;
}

if(mode_conf->config.spi.dev_phase == 0)
cpha = SPI_PHASE_1EDGE;
Expand Down Expand Up @@ -221,6 +226,11 @@ bsp_status_t bsp_spi_init(bsp_dev_spi_t dev_num, mode_config_proto_t* mode_conf)
/* Enable SPI peripheral */
__HAL_SPI_ENABLE(hspi);

/* Enable TX mode to avoid spurious clock output */
if(mode_conf->config.spi.dev_bidir == 1) {
SPI_1LINE_TX(hspi);
}

return status;
}

Expand Down Expand Up @@ -351,9 +361,21 @@ bsp_status_t bsp_spi_write_read_u8(bsp_dev_spi_t dev_num, uint8_t* tx_data, uint
hspi = &spi_handle[dev_num];

bsp_status_t status;
status = (bsp_status_t) HAL_SPI_TransmitReceive(hspi, tx_data, rx_data, nb_data, SPIx_TIMEOUT_MAX);
if(status != BSP_OK) {
spi_error(dev_num);
if(hspi->Init.Direction == SPI_DIRECTION_1LINE) {
status = (bsp_status_t) HAL_SPI_Transmit(hspi, tx_data, nb_data, SPIx_TIMEOUT_MAX);
if(status != BSP_OK) {
spi_error(dev_num);
return status;
}
status = (bsp_status_t) HAL_SPI_Receive(hspi, rx_data, nb_data, SPIx_TIMEOUT_MAX);
if(status != BSP_OK) {
spi_error(dev_num);
}
} else {
status = (bsp_status_t) HAL_SPI_TransmitReceive(hspi, tx_data, rx_data, nb_data, SPIx_TIMEOUT_MAX);
if(status != BSP_OK) {
spi_error(dev_num);
}
}
return status;
}
Expand Down
6 changes: 5 additions & 1 deletion src/hydrabus/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ const t_token_dict tl_dict[] = {
{ T_POKE, "poke" },
{ T_SWIO, "swio" },
{ T_CONTINUITY, "continuity" },
{ T_BIDIR, "bidir" },
/* Developer warning add new command(s) here */

/* BP-compatible commands */
Expand Down Expand Up @@ -1065,7 +1066,10 @@ t_token tokens_i2c[] = {
{ T_MSB_FIRST, \
.help = "Send/receive MSB first" }, \
{ T_LSB_FIRST, \
.help = "Send/receive LSB first" },
.help = "Send/receive LSB first" }, \
{ T_BIDIR, \
.arg_type = T_ARG_UINT, \
.help = "Bidir mode (0/1)" }, \

t_token tokens_mode_spi[] = {
{
Expand Down
1 change: 1 addition & 0 deletions src/hydrabus/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ enum {
T_POKE,
T_SWIO,
T_CONTINUITY,
T_BIDIR,
/* Developer warning add new command(s) here */

/* BP-compatible commands */
Expand Down
3 changes: 3 additions & 0 deletions src/hydrabus/hydrabus_bbio_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,9 @@ void bbio_mode_spi(t_hydra_console *con)
} else {
bsp_spi_select(proto->dev_num);
}
//Set bidir mode
proto->config.spi.dev_bidir = (bbio_subcommand & 0b100)?1:0;

//Set AUX[0] (PC4) value
bbio_aux_write((bbio_subcommand & 0b10)>>1);

Expand Down
42 changes: 36 additions & 6 deletions src/hydrabus/hydrabus_mode_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,16 @@ static int exec(t_hydra_console *con, t_tokenline_parsed *p, int token_pos);
static int show(t_hydra_console *con, t_tokenline_parsed *p);

static const char* str_pins_spi1= {
"CS: PA15\r\nSCK: PB3\r\nMISO: PB4\r\nMOSI: PB5\r\n"
"CS: PA15\r\nSCK: PB3\r\n"
};
static const char* str_pins_spi2= {
"CS: PC1 (SW)\r\nSCK: PB10\r\nMISO: PC2\r\nMOSI: PC3\r\n"
"CS: PC1 (SW)\r\nSCK: PB10\r\n"
};
static const char* str_pins_spi1_io= {
"MISO: PB4\r\nMOSI: PB5\r\n"
};
static const char* str_pins_spi2_io= {
"MISO: PC2\r\nMOSI: PC3\r\n"
};
static const char* str_prompt_spi1= { "spi1" PROMPT };
static const char* str_prompt_spi2= { "spi2" PROMPT };
Expand Down Expand Up @@ -75,20 +81,22 @@ static void init_proto_default(t_hydra_console *con)
proto->config.spi.dev_polarity = 0;
proto->config.spi.dev_phase = 0;
proto->config.spi.dev_bit_lsb_msb = DEV_FIRSTBIT_MSB;
proto->config.spi.dev_bidir = 0;
}

static void show_params(t_hydra_console *con)
{
uint8_t i, cnt;
mode_config_proto_t* proto = &con->mode->proto;

cprintf(con, "Device: SPI%d\r\nGPIO resistor: %s\r\nMode: %s\r\n"
cprintf(con, "Device: SPI%d\r\nGPIO resistor: %s\r\nMode: %s\r\nBidir: %s\r\n"
"Frequency: ",
proto->dev_num + 1,
proto->config.spi.dev_gpio_pull == MODE_CONFIG_DEV_GPIO_PULLUP ? "pull-up" :
proto->config.spi.dev_gpio_pull == MODE_CONFIG_DEV_GPIO_PULLDOWN ? "pull-down" :
"floating",
proto->config.spi.dev_mode == DEV_MASTER ? "master" : "slave");
proto->config.spi.dev_mode == DEV_MASTER ? "master" : "slave",
proto->config.spi.dev_bidir == 0 ? "off" : "on");

print_freq(con, spi_speeds[proto->dev_num][proto->config.spi.dev_speed]);
cprintf(con, " (");
Expand Down Expand Up @@ -242,6 +250,17 @@ static int exec(t_hydra_console *con, t_tokenline_parsed *p, int token_pos)
return t;
}
break;
case T_BIDIR:
/* Integer parameter. */
t += 2;
memcpy(&arg_int, p->buf + p->tokens[t], sizeof(int));
if (arg_int > 1 ) {
cprintf(con, "Bidir must be 0 or 1.\r\n");
return t;
}
proto->config.spi.dev_bidir = arg_int;
bsp_spi_init(proto->dev_num, proto);
break;
default:
return t - token_pos;
}
Expand Down Expand Up @@ -357,10 +376,21 @@ static int show(t_hydra_console *con, t_tokenline_parsed *p)
tokens_used = 0;
if (p->tokens[1] == T_PINS) {
tokens_used++;
if (proto->dev_num == 0)
if (proto->dev_num == 0) {
cprint(con, str_pins_spi1, strlen(str_pins_spi1));
else
if (proto->config.spi.dev_bidir == 0) {
cprint(con, str_pins_spi1_io, strlen(str_pins_spi1_io));
} else {
cprintf(con, "IO: %s\r\n", proto->config.spi.dev_mode == DEV_MASTER ? "PB5" : "PB4");
}
} else {
cprint(con, str_pins_spi2, strlen(str_pins_spi2));
if (proto->config.spi.dev_bidir == 0) {
cprint(con, str_pins_spi2_io, strlen(str_pins_spi2_io));
} else {
cprintf(con, "IO: %s\r\n", proto->config.spi.dev_mode == DEV_MASTER ? "PC3" : "PC2");
}
}
} else {
show_params(con);
}
Expand Down
1 change: 1 addition & 0 deletions src/hydrabus/hydrabus_serprog.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ void bbio_serprog_init_proto_default(t_hydra_console *con)
proto->config.spi.dev_polarity = 0;
proto->config.spi.dev_phase = 0;
proto->config.spi.dev_bit_lsb_msb = DEV_FIRSTBIT_MSB;
proto->config.spi.dev_bidir = 0;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't bidir intended to be enabled by default in serprog mode?
Documentation of serprog protocol states that S_SPI_MODE command (0x17), have two available modes, and the 0x00 mode that means Half Duplex is default one.
Source: https://www.flashrom.org/supported_hw/supported_prog/serprog/serprog-protocol.html, and look for S_SPI_MODE command

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bidir uses only one data line compared to the usual two in SPI.

The two serprog modes are for deciding whether you can write and read data at the same time (ie. the same clock cycle).
That is handled by proto->config.wwr in Hydrafw SPI mode but the serprog S_SPI_MODE is currently not handled, as I have no device to test and validate this feature. If you have some, feel free to submit a PR adding this mode ;)

}

void bbio_mode_serprog(t_hydra_console *con)
Expand Down