Skip to content

Commit

Permalink
Add serprog protocol
Browse files Browse the repository at this point in the history
Serprog is fully supported by flashrom. This fixes #76 (...)
  • Loading branch information
Baldanos committed Aug 28, 2020
1 parent 6c13e20 commit c10868f
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/hydrabus/hydrabus.mk
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ HYDRABUSSRC = hydrabus/hydrabus.c \
hydrabus/hydrabus_mode_wiegand.c \
hydrabus/hydrabus_mode_lin.c \
hydrabus/hydrabus_bbio_aux.c \
hydrabus/hydrabus_aux.c
hydrabus/hydrabus_aux.c \
hydrabus/hydrabus_serprog.c

# Required include directories
HYDRABUSINC = ./hydrabus
173 changes: 173 additions & 0 deletions src/hydrabus/hydrabus_serprog.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/*
* HydraBus/HydraNFC
*
* Copyright (C) 2014-2020 Benjamin VERNOUX
* Copyright (C) 2020 Nicolas OBERLI
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "common.h"
#include "tokenline.h"

#include "hydrabus_bbio.h"
#include "hydrabus_serprog.h"
#include "bsp_spi.h"

void bbio_serprog_init_proto_default(t_hydra_console *con)
{
mode_config_proto_t* proto = &con->mode->proto;

/* Defaults */
proto->dev_num = BSP_DEV_SPI2;
proto->config.spi.dev_gpio_pull = MODE_CONFIG_DEV_GPIO_NOPULL;
proto->config.spi.dev_mode = DEV_MASTER;
proto->config.spi.dev_speed = 7;
proto->config.spi.dev_polarity = 0;
proto->config.spi.dev_phase = 0;
proto->config.spi.dev_bit_lsb_msb = DEV_FIRSTBIT_MSB;
}

void bbio_mode_serprog(t_hydra_console *con)
{
uint8_t serprog_command;
uint32_t to_rx, to_tx, i;
uint8_t *tx_data = (uint8_t *)g_sbuf;
uint8_t *rx_data = (uint8_t *)g_sbuf+4096;
mode_config_proto_t* proto = &con->mode->proto;

bbio_serprog_init_proto_default(con);

// We no not initialize here, since flashrom takes care of starting the
// SPI interface. this allows to avoid potential electrical issues.
//bsp_spi_init(proto->dev_num, proto);

while (!hydrabus_ubtn()) {
if(chnRead(con->sdu, &serprog_command, 1) == 1) {
switch(serprog_command) {
case S_CMD_NOP:
break;
case S_CMD_Q_IFACE:
//TODO
cprint(con, S_ACK, 1);
cprint(con, "\x01\x00", 2);
break;
case S_CMD_Q_CMDMAP:
cprint(con, S_ACK, 1);
//TODO
cprint(con, "\x3f\x01\x3f\x00", 4);
cprint(con, "\x00\x00\x00\x00", 4);
cprint(con, "\x00\x00\x00\x00", 4);
cprint(con, "\x00\x00\x00\x00", 4);
cprint(con, "\x00\x00\x00\x00", 4);
cprint(con, "\x00\x00\x00\x00", 4);
cprint(con, "\x00\x00\x00\x00", 4);
cprint(con, "\x00\x00\x00\x00", 4);
break;
case S_CMD_Q_PGMNAME:
cprint(con, S_ACK, 1);
cprint(con, "Hydrabus\x00\x00\x00\x00\x00\x00\x00\x00", 16);
break;
case S_CMD_Q_SERBUF:
cprint(con, S_ACK, 1);
//16 bytes UART buffer
cprint(con, "\x10\x00", 2);
break;
case S_CMD_Q_BUSTYPE:
cprint(con, S_ACK, 1);
cprint(con, "\x08", 1);
break;
case S_CMD_SYNCNOP:
cprint(con, S_NAK, 1);
cprint(con, S_ACK, 1);
break;
case S_CMD_S_BUSTYPE:
// Dummy read
chnRead(con->sdu, &serprog_command, 1);
cprint(con, S_ACK, 1);
break;
case S_CMD_Q_WRNMAXLEN:
cprint(con, S_ACK, 1);
//4096 bytes write buffer
cprint(con, "\x00\x10\x00", 3);
break;
case S_CMD_Q_RDNMAXLEN:
cprint(con, S_ACK, 1);
//4096 bytes write buffer
cprint(con, "\x00\x10\x00", 3);
break;
case S_CMD_O_SPIOP:
chnRead(con->sdu, rx_data, 6);
to_tx = (rx_data[2] << 16) + (rx_data[1] << 8) + rx_data[0];
to_rx = (rx_data[5] << 16) + (rx_data[4] << 8) + rx_data[3];
if ((to_tx > 4096) || (to_rx > 4096)) {
cprint(con, S_NAK, 1);
break;
}
bsp_spi_select(proto->dev_num);
if(to_tx > 0) {
chnRead(con->sdu, tx_data, to_tx);
i=0;
while(i<to_tx) {
if((to_tx-i) >= 255) {
bsp_spi_write_u8(proto->dev_num,
tx_data+i,
255);
} else {
bsp_spi_write_u8(proto->dev_num,
tx_data+i,
to_tx-i);
}
i+=255;
}
}
i=0;
while(i<to_rx) {
if((to_rx-i) >= 255) {
bsp_spi_read_u8(proto->dev_num,
rx_data+i,
255);
} else {
bsp_spi_read_u8(proto->dev_num,
rx_data+i,
to_rx-i);
}
i+=255;
}
bsp_spi_unselect(proto->dev_num);
cprint(con, S_ACK, 1);
cprint(con, (char *)rx_data, to_rx);
break;
case S_CMD_S_SPI_FREQ:
chnRead(con->sdu, rx_data, 4);
//TODO: define variable speed.
cprint(con, S_ACK, 1);
break;
case S_CMD_S_PIN_STATE:
chnRead(con->sdu, rx_data, 1);

if(rx_data[0] == 0) {
bsp_spi_deinit(proto->dev_num);
} else {
bsp_spi_init(proto->dev_num, proto);
}
cprint(con, S_ACK, 1);
break;
default:
break;
}
}
}
bsp_spi_deinit(proto->dev_num);
return;
}
46 changes: 46 additions & 0 deletions src/hydrabus/hydrabus_serprog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* HydraBus/HydraNFC
*
* Copyright (C) 2020 Nicolas OBERLI
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* According to Serial Flasher Protocol Specification - version 1 */
#define S_ACK "\x06"
#define S_NAK "\x15"
#define S_CMD_NOP 0x00 /* No operation */
#define S_CMD_Q_IFACE 0x01 /* Query interface version */
#define S_CMD_Q_CMDMAP 0x02 /* Query supported commands bitmap */
#define S_CMD_Q_PGMNAME 0x03 /* Query programmer name */
#define S_CMD_Q_SERBUF 0x04 /* Query Serial Buffer Size */
#define S_CMD_Q_BUSTYPE 0x05 /* Query supported bustypes */
#define S_CMD_Q_CHIPSIZE 0x06 /* Query supported chipsize (2^n format) */
#define S_CMD_Q_OPBUF 0x07 /* Query operation buffer size */
#define S_CMD_Q_WRNMAXLEN 0x08 /* Query Write to opbuf: Write-N maximum length */
#define S_CMD_R_BYTE 0x09 /* Read a single byte */
#define S_CMD_R_NBYTES 0x0A /* Read n bytes */
#define S_CMD_O_INIT 0x0B /* Initialize operation buffer */
#define S_CMD_O_WRITEB 0x0C /* Write opbuf: Write byte with address */
#define S_CMD_O_WRITEN 0x0D /* Write to opbuf: Write-N */
#define S_CMD_O_DELAY 0x0E /* Write opbuf: udelay */
#define S_CMD_O_EXEC 0x0F /* Execute operation buffer */
#define S_CMD_SYNCNOP 0x10 /* Special no-operation that returns NAK+ACK */
#define S_CMD_Q_RDNMAXLEN 0x11 /* Query read-n maximum length */
#define S_CMD_S_BUSTYPE 0x12 /* Set used bustype(s). */
#define S_CMD_O_SPIOP 0x13 /* Perform SPI operation. */
#define S_CMD_S_SPI_FREQ 0x14 /* Set SPI clock frequency */
#define S_CMD_S_PIN_STATE 0x15 /* Enable/disable output drivers */

void bbio_serprog_init_proto_default(t_hydra_console *con);
void bbio_mode_serprog(t_hydra_console *con);
8 changes: 8 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#endif
#include "hydrabus/hydrabus_bbio.h"
#include "hydrabus/hydrabus_sump.h"
#include "hydrabus/hydrabus_serprog.h"

#include "bsp.h"

Expand Down Expand Up @@ -100,6 +101,13 @@ THD_FUNCTION(console, arg)
sump(con);
}
break;
/* SERPROG identification is 8*\x00, then \x10 */
/* Enter SERPROG mode automatically */
case 0x10:
if(i == 8) {
bbio_mode_serprog(con);
}
break;
default:
i=0;
tl_input(con->tl, input);
Expand Down

0 comments on commit c10868f

Please sign in to comment.