From 53ab788fa02beac41ae7e1d3e392f5bc38fd8b83 Mon Sep 17 00:00:00 2001 From: bvernoux Date: Mon, 11 Apr 2016 21:40:56 +0200 Subject: [PATCH] Initial BBIO I2C support --- hydrabus/hydrabus.mk | 3 +- hydrabus/hydrabus_bbio.c | 6 +- hydrabus/hydrabus_bbio.h | 18 +++- hydrabus/hydrabus_bbio_i2c.c | 186 +++++++++++++++++++++++++++++++++++ hydrabus/hydrabus_bbio_i2c.h | 22 +++++ 5 files changed, 229 insertions(+), 6 deletions(-) create mode 100644 hydrabus/hydrabus_bbio_i2c.c create mode 100644 hydrabus/hydrabus_bbio_i2c.h diff --git a/hydrabus/hydrabus.mk b/hydrabus/hydrabus.mk index 140644b7..cf716315 100644 --- a/hydrabus/hydrabus.mk +++ b/hydrabus/hydrabus.mk @@ -18,7 +18,8 @@ HYDRABUSSRC = hydrabus/hydrabus.c \ hydrabus/hydrabus_bbio_spi.c \ hydrabus/hydrabus_bbio_pin.c \ hydrabus/hydrabus_bbio_can.c \ - hydrabus/hydrabus_bbio_uart.c + hydrabus/hydrabus_bbio_uart.c \ + hydrabus/hydrabus_bbio_i2c.c # Required include directories HYDRABUSINC = ./hydrabus diff --git a/hydrabus/hydrabus_bbio.c b/hydrabus/hydrabus_bbio.c index 1f3248da..78a68646 100644 --- a/hydrabus/hydrabus_bbio.c +++ b/hydrabus/hydrabus_bbio.c @@ -2,7 +2,7 @@ * HydraBus/HydraNFC * * Copyright (C) 2014-2016 Benjamin VERNOUX - * Copyright (C) 2015 Nicolas OBERLI + * Copyright (C) 2015-2016 Nicolas OBERLI * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ #include "hydrabus_mode_jtag.h" #include "hydrabus_bbio_can.h" #include "hydrabus_bbio_uart.h" +#include "hydrabus_bbio_i2c.h" int cmd_bbio(t_hydra_console *con) { @@ -45,12 +46,11 @@ int cmd_bbio(t_hydra_console *con) break; case BBIO_I2C: cprint(con, "I2C1", 4); - //TODO + bbio_mode_i2c(con); break; case BBIO_UART: cprint(con, "ART1", 4); bbio_mode_uart(con); - //TODO break; case BBIO_1WIRE: cprint(con, "1W01", 4); diff --git a/hydrabus/hydrabus_bbio.h b/hydrabus/hydrabus_bbio.h index b547b3db..ea5c8493 100644 --- a/hydrabus/hydrabus_bbio.h +++ b/hydrabus/hydrabus_bbio.h @@ -1,7 +1,8 @@ /* * HydraBus/HydraNFC * - * Copyright (C) 2015 Nicolas OBERLI + * Copyright (C) 2015-2016 Nicolas OBERLI + * Copyright (C) 2016 Benjamin VERNOUX * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +39,6 @@ #define BBIO_VOLT_CONT 0b00010101 #define BBIO_FREQ 0b00010110 - /* * SPI-specific commands */ @@ -55,6 +55,20 @@ #define BBIO_SPI_SET_SPEED 0b01100000 #define BBIO_SPI_CONFIG 0b10000000 +/* + * I2C-specific commands + */ +#define BBIO_I2C_START_BIT 0b00000010 +#define BBIO_I2C_STOP_BIT 0b00000011 +#define BBIO_I2C_READ_BYTE 0b00000100 +#define BBIO_I2C_ACK_BIT 0b00000110 +#define BBIO_I2C_NACK_BIT 0b00000111 +#define BBIO_I2C_WRITE_READ 0b00001000 +#define BBIO_I2C_START_SNIFF 0b00001111 +#define BBIO_I2C_BULK_WRITE 0b00010000 +#define BBIO_I2C_CONFIG_PERIPH 0b01000000 +#define BBIO_I2C_SET_SPEED 0b01100000 + /* * CAN-specific commands */ diff --git a/hydrabus/hydrabus_bbio_i2c.c b/hydrabus/hydrabus_bbio_i2c.c new file mode 100644 index 00000000..6ac3a534 --- /dev/null +++ b/hydrabus/hydrabus_bbio_i2c.c @@ -0,0 +1,186 @@ +/* + * HydraBus/HydraNFC + * + * Copyright (C) 2015-2016 Nicolas OBERLI + * Copyright (C) 2016 Benjamin VERNOUX + * + * 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 "stm32f4xx_hal.h" +#include +#include +#include + +#include "hydrabus_bbio.h" +#include "bsp_i2c.h" + +#define I2C_DEV_NUM (1) + +void bbio_i2c_init_proto_default(t_hydra_console *con) +{ + mode_config_proto_t* proto = &con->mode->proto; + + /* Defaults */ + proto->dev_num = I2C_DEV_NUM; + proto->dev_gpio_pull = MODE_CONFIG_DEV_GPIO_PULLUP; + proto->dev_speed = 1; + proto->ack_pending = 0; +} + +void bbio_i2c_sniff(t_hydra_console *con) +{ + /* TODO bbio_i2c_sniff code */ +} + +void bbio_mode_i2c(t_hydra_console *con) +{ + uint8_t bbio_subcommand; + uint16_t to_rx, to_tx, i; + uint8_t *tx_data = (uint8_t *)g_sbuf; + uint8_t *rx_data = (uint8_t *)g_sbuf+4096; + uint8_t data; + bool tx_ack_flag; + bsp_status_t status; + mode_config_proto_t* proto = &con->mode->proto; + + bbio_i2c_init_proto_default(con); + bsp_i2c_init(proto->dev_num, proto); + + while (!USER_BUTTON) { + if(chSequentialStreamRead(con->sdu, &bbio_subcommand, 1) == 1) { + switch(bbio_subcommand) { + case BBIO_RESET: + bsp_i2c_deinit(proto->dev_num); + return; + case BBIO_I2C_START_BIT: + bsp_i2c_start(proto->dev_num); + cprint(con, "\x01", 1); + break; + case BBIO_I2C_STOP_BIT: + bsp_i2c_stop(proto->dev_num); + cprint(con, "\x01", 1); + break; + case BBIO_I2C_READ_BYTE: + status = bsp_i2c_master_read_u8(proto->dev_num, &data); + cprintf(con, "\x01%c", data & 0xff); + break; + case BBIO_I2C_ACK_BIT: + bsp_i2c_read_ack(proto->dev_num, TRUE); + cprint(con, "\x01", 1); + break; + case BBIO_I2C_NACK_BIT: + bsp_i2c_read_ack(proto->dev_num, FALSE); + cprint(con, "\x01", 1); + break; + case BBIO_I2C_START_SNIFF: + bbio_i2c_sniff(con); + break; + case BBIO_I2C_WRITE_READ: + chSequentialStreamRead(con->sdu, rx_data, 4); + to_tx = (rx_data[0] << 8) + rx_data[1]; + to_rx = (rx_data[2] << 8) + rx_data[3]; + if ((to_tx > 4096) || (to_rx > 4096)) { + cprint(con, "\x00", 1); + break; + } + chSequentialStreamRead(con->sdu, tx_data, to_tx); + + /* Send I2C Start */ + bsp_i2c_start(proto->dev_num); + + /* Send all I2C Data */ + for(i = 0; i < to_tx; i++) + { + bsp_i2c_master_write_u8(proto->dev_num, tx_data[i], &tx_ack_flag); + if(tx_ack_flag != TRUE) + { + break; /* Error */ + } + } + if(tx_ack_flag != TRUE) + { + /* Error */ + cprint(con, "\x00", 1); + break; /* Return now */ + } + + /* Read all I2C Data */ + if(to_rx >= 1) + { + /* Read I2C bytes with ACK */ + for(i = 0; i < to_rx - 1; i++) + { + bsp_i2c_master_read_u8(proto->dev_num, &rx_data[i]); + bsp_i2c_read_ack(proto->dev_num, TRUE); + } + + /* Send NACK for last I2C byte read */ + bsp_i2c_master_read_u8(proto->dev_num, &rx_data[i]); + bsp_i2c_read_ack(proto->dev_num, FALSE); + } + + /* Send I2C Stop */ + bsp_i2c_stop(proto->dev_num); + + i=0; + cprint(con, "\x01", 1); + while(i < to_rx) { + cprintf(con, "%c", rx_data[i]); + i++; + } + break; + default: + if ((bbio_subcommand & BBIO_I2C_BULK_WRITE) == BBIO_I2C_BULK_WRITE) { + // data contains the number of bytes to + // write + data = (bbio_subcommand & 0b1111) + 1; + cprint(con, "\x01", 1); + + chSequentialStreamRead(con->sdu, tx_data, data); + /* Send all I2C Data */ + for(i = 0; i < data; i++) + { + bsp_i2c_master_write_u8(proto->dev_num, tx_data[i], &tx_ack_flag); + if(tx_ack_flag == TRUE) + { + cprintf(con, "\x00", 1); // ACK (0x00) + }else + { + cprintf(con, "\x01", 1); // NACK (0x01) + } + } + } else if ((bbio_subcommand & BBIO_I2C_SET_SPEED) == BBIO_I2C_SET_SPEED) { + proto->dev_speed = bbio_subcommand & 0b11; + status = bsp_i2c_init(proto->dev_num, proto); + if(status == BSP_OK) { + cprint(con, "\x01", 1); + } else { + cprint(con, "\x00", 1); + } + } else if ((bbio_subcommand & BBIO_I2C_CONFIG_PERIPH) == BBIO_I2C_CONFIG_PERIPH) { + proto->dev_gpio_pull = (bbio_subcommand & 0b100)?1:0; + status = bsp_i2c_init(proto->dev_num, proto); + if(status == BSP_OK) { + cprint(con, "\x01", 1); + } else { + cprint(con, "\x00", 1); + } + } + + } + } + } +} diff --git a/hydrabus/hydrabus_bbio_i2c.h b/hydrabus/hydrabus_bbio_i2c.h new file mode 100644 index 00000000..0e5f2afc --- /dev/null +++ b/hydrabus/hydrabus_bbio_i2c.h @@ -0,0 +1,22 @@ +/* + * HydraBus/HydraNFC + * + * Copyright (C) 2015-2016 Nicolas OBERLI + * Copyright (C) 2016 Benjamin VERNOUX + * + * 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. + */ + +void bbio_i2c_init_proto_default(t_hydra_console *con); +void bbio_i2c_sniff(t_hydra_console *con); +void bbio_mode_i2c(t_hydra_console *con);