Skip to content

Commit

Permalink
Initial BBIO 2-Wire support (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
Baldanos authored and bvernoux committed Apr 14, 2016
1 parent b3f679d commit 3679dc0
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 24 deletions.
3 changes: 2 additions & 1 deletion hydrabus/hydrabus.mk
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ HYDRABUSSRC = hydrabus/hydrabus.c \
hydrabus/hydrabus_bbio_pin.c \
hydrabus/hydrabus_bbio_can.c \
hydrabus/hydrabus_bbio_uart.c \
hydrabus/hydrabus_bbio_i2c.c
hydrabus/hydrabus_bbio_i2c.c \
hydrabus/hydrabus_bbio_twowire.c

# Required include directories
HYDRABUSINC = ./hydrabus
3 changes: 2 additions & 1 deletion hydrabus/hydrabus_bbio.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "hydrabus_bbio_can.h"
#include "hydrabus_bbio_uart.h"
#include "hydrabus_bbio_i2c.h"
#include "hydrabus_bbio_twowire.h"

int cmd_bbio(t_hydra_console *con)
{
Expand Down Expand Up @@ -58,7 +59,7 @@ int cmd_bbio(t_hydra_console *con)
break;
case BBIO_RAWWIRE:
cprint(con, "RAW1", 4);
//TODO
bbio_mode_twowire(con);
break;
case BBIO_JTAG:
cprint(con, "OCD1", 4);
Expand Down
22 changes: 22 additions & 0 deletions hydrabus/hydrabus_bbio.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,26 @@
#define BBIO_UART_SET_SPEED 0b01100000
#define BBIO_UART_CONFIG 0b10000000

/*
* 2-Wire-specific commands
*/
#define BBIO_2WIRE_I2C_START 0b00000010
#define BBIO_2WIRE_I2C_STOP 0b00000011
#define BBIO_2WIRE_CS_LOW 0b00000100
#define BBIO_2WIRE_CS_HIGH 0b00000101
#define BBIO_2WIRE_READ_BYTE 0b00000110
#define BBIO_2WIRE_READ_BIT 0b00000111
#define BBIO_2WIRE_PEEK_INPUT 0b00001000
#define BBIO_2WIRE_CLK_TICK 0b00001001
#define BBIO_2WIRE_CLK_LOW 0b00001010
#define BBIO_2WIRE_CLK_HIGH 0b00001011
#define BBIO_2WIRE_DATA_LOW 0b00001100
#define BBIO_2WIRE_DATA_HIGH 0b00001101
#define BBIO_2WIRE_BULK_TRANSFER 0b00010000
#define BBIO_2WIRE_BULK_CLK 0b00100000
#define BBIO_2WIRE_BULK_BIT 0b00110000
#define BBIO_2WIRE_CONFIG_PERIPH 0b01000000
#define BBIO_2WIRE_SET_SPEED 0b01100000
#define BBIO_2WIRE_CONFIG 0b10000000

int cmd_bbio(t_hydra_console *con);
146 changes: 146 additions & 0 deletions hydrabus/hydrabus_bbio_twowire.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
* HydraBus/HydraNFC
*
* Copyright (C) 2014-2016 Benjamin VERNOUX
* Copyright (C) 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.
* 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 <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "hydrabus_bbio.h"
#include "hydrabus_mode_twowire.h"

void bbio_mode_twowire(t_hydra_console *con)
{
uint8_t bbio_subcommand, i;
uint8_t rx_data[16], tx_data[16];
uint8_t data;
mode_config_proto_t* proto = &con->mode->proto;

init_proto_default(con);
twowire_pin_init(con);
tim_init(con);
twowire_clk_low();
twowire_sda_low();

while (!USER_BUTTON) {
if(chSequentialStreamRead(con->sdu, &bbio_subcommand, 1) == 1) {
switch(bbio_subcommand) {
case BBIO_RESET:
return;
case BBIO_2WIRE_READ_BYTE:
rx_data[0] = twowire_read_u8(con);
cprint(con, (char *)&rx_data[0], 1);
break;
case BBIO_2WIRE_READ_BIT:
rx_data[0] = twowire_read_bit_clock();
cprint(con, (char *)&rx_data[0], 1);
break;
case BBIO_2WIRE_PEEK_INPUT:
rx_data[0] = twowire_read_bit();
cprint(con, (char *)&rx_data[0], 1);
break;
case BBIO_2WIRE_CLK_TICK:
twowire_clock();
cprint(con, "\x01", 1);
break;
case BBIO_2WIRE_CLK_LOW:
twowire_clk_low();
cprint(con, "\x01", 1);
break;
case BBIO_2WIRE_CLK_HIGH:
twowire_clk_high();
cprint(con, "\x01", 1);
break;
case BBIO_2WIRE_DATA_LOW:
twowire_sda_low();
cprint(con, "\x01", 1);
break;
case BBIO_2WIRE_DATA_HIGH:
twowire_sda_high();
cprint(con, "\x01", 1);
break;
default:
if ((bbio_subcommand & BBIO_2WIRE_BULK_TRANSFER) == BBIO_2WIRE_BULK_TRANSFER) {
// data contains the number of bytes to
// write
data = (bbio_subcommand & 0b1111) + 1;

chSequentialStreamRead(con->sdu, tx_data, data);
for(i=0; i<data; i++) {
twowire_write_u8(con, tx_data[i]);
}
cprint(con, "\x01", 1);
} else if ((bbio_subcommand & BBIO_2WIRE_BULK_BIT) == BBIO_2WIRE_BULK_BIT) {
// data contains the number of bits to
// write
data = (bbio_subcommand & 0b1111) + 1;

chSequentialStreamRead(con->sdu, &tx_data[0], 1);
if(proto->dev_bit_lsb_msb == DEV_SPI_FIRSTBIT_LSB) {
for (i=0; i<data; i++) {
twowire_send_bit((tx_data[0]>>i) & 1);
}
} else {
for (i=0; i<data; i++) {
twowire_send_bit((tx_data[0]>>(7-i)) & 1);
}
}
cprint(con, "\x01", 1);

} else if ((bbio_subcommand & BBIO_2WIRE_BULK_CLK) == BBIO_2WIRE_BULK_CLK) {
// data contains the number of bytes to
// write
data = (bbio_subcommand & 0b1111) + 1;

for(i=0; i<data; i++) {
twowire_clock();
}
cprint(con, "\x01", 1);
} else if ((bbio_subcommand & BBIO_SPI_SET_SPEED) == BBIO_SPI_SET_SPEED) {
switch(bbio_subcommand & 0b11){
case 0:
proto->dev_speed = 5000;
break;
case 1:
proto->dev_speed = 50000;
break;
case 2:
proto->dev_speed = 100000;
break;
case 3:
proto->dev_speed = 1000000;
break;
}
tim_set_prescaler(con);
} else if ((bbio_subcommand & BBIO_2WIRE_CONFIG) == BBIO_2WIRE_CONFIG) {
if(bbio_subcommand & 0b10){
proto->dev_bit_lsb_msb = DEV_SPI_FIRSTBIT_MSB;
} else {
proto->dev_bit_lsb_msb = DEV_SPI_FIRSTBIT_LSB;
}
cprint(con, "\x01", 1);
} else if ((bbio_subcommand & BBIO_2WIRE_CONFIG_PERIPH) == BBIO_2WIRE_CONFIG_PERIPH) {
cprint(con, "\x01", 1);
}

}
}
}
}
20 changes: 20 additions & 0 deletions hydrabus/hydrabus_bbio_twowire.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* HydraBus/HydraNFC
*
* Copyright (C) 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.
* 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_twowire_init_proto_default(t_hydra_console *con);
void bbio_mode_twowire(t_hydra_console *con);
45 changes: 24 additions & 21 deletions hydrabus/hydrabus_mode_twowire.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static const char* str_prompt_twowire[] = {
"twowire1" PROMPT,
};

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

Expand All @@ -44,8 +44,8 @@ static void init_proto_default(t_hydra_console *con)
proto->dev_gpio_mode = MODE_CONFIG_DEV_GPIO_OUT_PUSHPULL;
proto->dev_gpio_pull = MODE_CONFIG_DEV_GPIO_NOPULL;
proto->dev_bit_lsb_msb = DEV_SPI_FIRSTBIT_MSB;
proto->dev_speed = TWOWIRE_MAX_FREQ;

config.divider = 1;
config.clk_pin = 3;
config.sda_pin = 4;
}
Expand All @@ -61,10 +61,10 @@ static void show_params(t_hydra_console *con)
"floating");

cprintf(con, "Frequency: %dHz\r\nBit order: %s first\r\n",
(TWOWIRE_MAX_FREQ/(int)config.divider), proto->dev_bit_lsb_msb == DEV_SPI_FIRSTBIT_MSB ? "MSB" : "LSB");
(proto->dev_speed), proto->dev_bit_lsb_msb == DEV_SPI_FIRSTBIT_MSB ? "MSB" : "LSB");
}

static bool twowire_pin_init(t_hydra_console *con)
bool twowire_pin_init(t_hydra_console *con)
{
mode_config_proto_t* proto = &con->mode->proto;

Expand All @@ -75,12 +75,13 @@ static bool twowire_pin_init(t_hydra_console *con)
return true;
}

static void tim_init(void)
void tim_init(t_hydra_console *con)
{
mode_config_proto_t* proto = &con->mode->proto;
htim.Instance = TIM4;

htim.Init.Period = 42 - 1;
htim.Init.Prescaler = (config.divider) - 1;
htim.Init.Prescaler = (TWOWIRE_MAX_FREQ/proto->dev_speed) - 1;
htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim.Init.CounterMode = TIM_COUNTERMODE_UP;

Expand All @@ -91,11 +92,13 @@ static void tim_init(void)
HAL_TIM_Base_Start(&htim);
}

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

HAL_TIM_Base_Stop(&htim);
HAL_TIM_Base_DeInit(&htim);
htim.Init.Prescaler = (config.divider) - 1;
htim.Init.Prescaler = (TWOWIRE_MAX_FREQ/proto->dev_speed) - 1;
HAL_TIM_Base_Init(&htim);
TIM4->SR &= ~TIM_SR_UIF; //clear overflow flag
HAL_TIM_Base_Start(&htim);
Expand All @@ -115,39 +118,39 @@ static void twowire_sda_mode_output(t_hydra_console *con)
proto->dev_gpio_mode, proto->dev_gpio_pull);
}

static inline void twowire_sda_high(void)
inline void twowire_sda_high(void)
{
bsp_gpio_set(BSP_GPIO_PORTB, config.sda_pin);
}

static inline void twowire_sda_low(void)
inline void twowire_sda_low(void)
{
bsp_gpio_clr(BSP_GPIO_PORTB, config.sda_pin);
}

static inline void twowire_clk_high(void)
inline void twowire_clk_high(void)
{
while (!(TIM4->SR & TIM_SR_UIF)) {
}
bsp_gpio_set(BSP_GPIO_PORTB, config.clk_pin);
TIM4->SR &= ~TIM_SR_UIF; //clear overflow flag
}

static inline void twowire_clk_low(void)
inline void twowire_clk_low(void)
{
while (!(TIM4->SR & TIM_SR_UIF)) {
}
bsp_gpio_clr(BSP_GPIO_PORTB, config.clk_pin);
TIM4->SR &= ~TIM_SR_UIF; //clear overflow flag
}

static inline void twowire_clock(void)
inline void twowire_clock(void)
{
twowire_clk_high();
twowire_clk_low();
}

static void twowire_send_bit(uint8_t bit)
void twowire_send_bit(uint8_t bit)
{
if (bit) {
twowire_sda_high();
Expand All @@ -157,12 +160,12 @@ static void twowire_send_bit(uint8_t bit)
twowire_clock();
}

static uint8_t twowire_read_bit(void)
uint8_t twowire_read_bit(void)
{
return bsp_gpio_pin_read(BSP_GPIO_PORTB, config.sda_pin);
}

static uint8_t twowire_read_bit_clock(void)
uint8_t twowire_read_bit_clock(void)
{
uint8_t bit;
twowire_clock();
Expand Down Expand Up @@ -212,7 +215,7 @@ static void bitr(t_hydra_console *con)
cprintf(con, hydrabus_mode_str_read_one_u8, rx_data);
}

static void twowire_write_u8(t_hydra_console *con, uint8_t tx_data)
void twowire_write_u8(t_hydra_console *con, uint8_t tx_data)
{
mode_config_proto_t* proto = &con->mode->proto;
uint8_t i;
Expand All @@ -230,7 +233,7 @@ static void twowire_write_u8(t_hydra_console *con, uint8_t tx_data)
}
}

static uint8_t twowire_read_u8(t_hydra_console *con)
uint8_t twowire_read_u8(t_hydra_console *con)
{
mode_config_proto_t* proto = &con->mode->proto;
uint8_t value;
Expand Down Expand Up @@ -262,7 +265,7 @@ static int init(t_hydra_console *con, t_tokenline_parsed *p)
tokens_used = 1 + exec(con, p, 1);

twowire_pin_init(con);
tim_init();
tim_init(con);

twowire_clk_low();
twowire_sda_low();
Expand Down Expand Up @@ -309,8 +312,8 @@ static int exec(t_hydra_console *con, t_tokenline_parsed *p, int token_pos)
if(arg_float > TWOWIRE_MAX_FREQ) {
cprintf(con, "Frequency too high\r\n");
} else {
config.divider = TWOWIRE_MAX_FREQ/(int)arg_float;
tim_set_prescaler();
proto->dev_speed = (int)arg_float;
tim_set_prescaler(con);
}
break;
default:
Expand Down
Loading

0 comments on commit 3679dc0

Please sign in to comment.