From 858de3f1fe260b07ad0d0893f3bded5ee730b018 Mon Sep 17 00:00:00 2001 From: Baldanos Date: Tue, 2 Apr 2019 20:54:47 +0200 Subject: [PATCH] Initial auxiliary pin feature --- contrib/pyHydrabus/pyHydrabus/aux.py | 138 ++++++++++++++++++++++ contrib/pyHydrabus/pyHydrabus/common.py | 10 ++ contrib/pyHydrabus/pyHydrabus/protocol.py | 6 + src/common/mode_config.h | 1 + src/hydrabus/hydrabus.mk | 3 +- src/hydrabus/hydrabus_bbio.c | 5 + src/hydrabus/hydrabus_bbio.h | 13 +- src/hydrabus/hydrabus_bbio_aux.c | 108 +++++++++++++++++ src/hydrabus/hydrabus_bbio_aux.h | 24 ++++ src/hydrabus/hydrabus_bbio_can.c | 5 +- src/hydrabus/hydrabus_bbio_i2c.c | 5 +- src/hydrabus/hydrabus_bbio_onewire.c | 4 +- src/hydrabus/hydrabus_bbio_rawwire.c | 5 +- src/hydrabus/hydrabus_bbio_smartcard.c | 5 +- src/hydrabus/hydrabus_bbio_spi.c | 7 +- src/hydrabus/hydrabus_bbio_uart.c | 5 +- 16 files changed, 327 insertions(+), 17 deletions(-) create mode 100644 contrib/pyHydrabus/pyHydrabus/aux.py create mode 100644 src/hydrabus/hydrabus_bbio_aux.c create mode 100644 src/hydrabus/hydrabus_bbio_aux.h diff --git a/contrib/pyHydrabus/pyHydrabus/aux.py b/contrib/pyHydrabus/pyHydrabus/aux.py new file mode 100644 index 00000000..7fff5aa6 --- /dev/null +++ b/contrib/pyHydrabus/pyHydrabus/aux.py @@ -0,0 +1,138 @@ +import logging + +from .common import set_bit + +class AUXPin(): + """ + Auxilary pin base class + + This class is meant to be used in any mode and is instanciated in the + Protocol class + + :example: + + >>> import pyHydrabus + >>> i=pyHydrabus.I2C('/dev/hydrabus') + >>> # Set AUX pin 0 (PC4) to output + >>> i.AUX[0].direction = 0 + >>> # Set AUX pin to logical 1 + >>> i.AUX[0].value = 1 + >>> # Read Auxiliary pin 2 (PC5) value + >>> i.AUX[1].value + + """ + + OUTPUT = 0 + INPUT = 1 + + def __init__(self, number, hydrabus): + """ + AUXPin constructor + + :param number: Auxilary pin number (0-3) + :param hydrabus: Initialized pyHydrabus.Hydrabus instance + """ + self.number = number + self._hydrabus = hydrabus + self._logger = logging.getLogger(__name__) + + def _get_config(self): + """ + Gets Auxiliary pin config from Hydrabus + + :return: Auxilary pin config (4 bits pullup for AUX[0-3], 4 bits value for AUX[0-3]) + :rtype: byte + """ + CMD = 0b11100000 + self._hydrabus.write(CMD.to_bytes(1, byteorder="big")) + return self._hydrabus.read(1) + + def _get_values(self): + """ + Gets Auxiliary pin values from Hydrabus + + :return: Auxilary pin values AUX[0-3] + :rtype: byte + """ + CMD = 0b11000000 + self._hydrabus.write(CMD.to_bytes(1, byteorder="big")) + return self._hydrabus.read(1) + + @property + def value(self): + """ + Auxiliary pin getter + """ + return (ord(self._get_values()) >> self.number) & 0b1 + + @value.setter + def value(self, value): + """ + Auxiliary pin setter + + :param value: auxiliary pin value (0 or 1) + """ + CMD = 0b11010000 + CMD = CMD | ord(set_bit(self._get_values(), value, self.number)) + self._hydrabus.write(CMD.to_bytes(1, byteorder="big")) + if self._hydrabus.read(1) == b"\x01": + return + else: + self._logger.error("Error setting auxiliary pins value.") + + @property + def direction(self): + """ + Auxiliary pin direction getter + + :return: The pin direction (0=output, 1=input) + :rtype: int + """ + return (ord(self._get_config()) >> self.number) & 0b1 + + @direction.setter + def direction(self, value): + """ + Auxiliary pin direction setter + + :param value: The pin direction (0=output, 1=input) + """ + CMD = 0b11110000 + PARAM = self._get_config() + PARAM = set_bit(PARAM, value, self.number) + + self._hydrabus.write(CMD.to_bytes(1, byteorder="big")) + self._hydrabus.write(PARAM) + if self._hydrabus.read(1) == b"\x01": + return + else: + self._logger.error("Error setting auxiliary pins direction.") + + @property + def pullup(self): + """ + Auxiliary pin pullup getter + + :return: Auxiliary pin pullup status (1=enabled, 0=disabled") + :rtype: int + """ + return (ord(self._get_config()) >> (4 + self.number)) & 0b1 + + @pullup.setter + def pullup(self, value): + """ + Auxiliary pin pullup setter + + :param value: Auxiliary pin pullup (1=enabled, 0=disabled") + """ + CMD = 0b11110000 + PARAM = self._get_config() + PARAM = set_bit(PARAM, value, 4+self.number) + + self._hydrabus.write(CMD.to_bytes(1, byteorder="big")) + self._hydrabus.write(PARAM) + if self._hydrabus.read(1) == b"\x01": + return + else: + self._logger.error("Error setting auxiliary pins value.") + diff --git a/contrib/pyHydrabus/pyHydrabus/common.py b/contrib/pyHydrabus/pyHydrabus/common.py index b56df33c..f5897913 100644 --- a/contrib/pyHydrabus/pyHydrabus/common.py +++ b/contrib/pyHydrabus/pyHydrabus/common.py @@ -17,3 +17,13 @@ def split(seq, length): Split a list in chunks of specific length """ return [seq[i:i+length] for i in range(0, len(seq), length)] + +def set_bit(byte, bit, position): + v = ord(byte) + if bit == 1: + v = v | (1 << position) + elif bit == 0: + v = v & (~(1 << position)) & 0xff + else: + raise ValueError("Bit must be 0 or 1") + return v.to_bytes(1, byteorder="big") diff --git a/contrib/pyHydrabus/pyHydrabus/protocol.py b/contrib/pyHydrabus/pyHydrabus/protocol.py index 94d6ca5f..4e9f5d1f 100644 --- a/contrib/pyHydrabus/pyHydrabus/protocol.py +++ b/contrib/pyHydrabus/pyHydrabus/protocol.py @@ -14,6 +14,7 @@ import logging from .hydrabus import Hydrabus +from .aux import AUXPin class Protocol: @@ -40,6 +41,11 @@ def __init__(self, name="", fname="", mode_byte=b"\x00", port=""): self._enter() self._hydrabus.flush_input() + self.AUX = [] + for i in range(4): + self.AUX.append(AUXPin(i, self._hydrabus)) + + def _enter(self): self._hydrabus.write(self._mode_byte) if self._hydrabus.read(4) == self.name: diff --git a/src/common/mode_config.h b/src/common/mode_config.h index 4337d698..a8494c92 100644 --- a/src/common/mode_config.h +++ b/src/common/mode_config.h @@ -182,6 +182,7 @@ typedef struct { hydranfc_config_t hydranfc; } config; + uint8_t aux_config; uint8_t wwr : 1; // write with read uint8_t buffer_tx[MODE_CONFIG_PROTO_BUFFER_SIZE]; uint8_t buffer_rx[MODE_CONFIG_PROTO_BUFFER_SIZE]; diff --git a/src/hydrabus/hydrabus.mk b/src/hydrabus/hydrabus.mk index c79a67a2..45270fe9 100644 --- a/src/hydrabus/hydrabus.mk +++ b/src/hydrabus/hydrabus.mk @@ -34,7 +34,8 @@ HYDRABUSSRC = hydrabus/hydrabus.c \ hydrabus/hydrabus_sd.c \ hydrabus/hydrabus_trigger.c \ hydrabus/hydrabus_mode_wiegand.c \ - hydrabus/hydrabus_mode_lin.c + hydrabus/hydrabus_mode_lin.c \ + hydrabus/hydrabus_bbio_aux.c # Required include directories HYDRABUSINC = ./hydrabus diff --git a/src/hydrabus/hydrabus_bbio.c b/src/hydrabus/hydrabus_bbio.c index 864d7075..826c661f 100644 --- a/src/hydrabus/hydrabus_bbio.c +++ b/src/hydrabus/hydrabus_bbio.c @@ -37,10 +37,15 @@ #include "hydrabus_bbio_smartcard.h" #include "hydrabus_bbio_adc.h" #include "hydrabus_bbio_freq.h" +#include "hydrabus_bbio_aux.h" int cmd_bbio(t_hydra_console *con) { uint8_t bbio_mode; + + // Init auxiliary pins + bbio_aux_init_proto_default(con); + cprint(con, "BBIO1", 5); while (!palReadPad(GPIOA, 0)) { diff --git a/src/hydrabus/hydrabus_bbio.h b/src/hydrabus/hydrabus_bbio.h index da7eb6a1..95489520 100644 --- a/src/hydrabus/hydrabus_bbio.h +++ b/src/hydrabus/hydrabus_bbio.h @@ -17,6 +17,8 @@ * limitations under the License. */ +#include "hydrabus_bbio_aux.h" + /* * Basic BBIO modes */ @@ -87,9 +89,9 @@ #define BBIO_CAN_FILTER_ON 0b00000101 #define BBIO_CAN_FILTER 0b00000110 #define BBIO_CAN_WRITE 0b00001000 +#define BBIO_CAN_SET_TIMINGS 0b00010000 #define BBIO_CAN_SET_SPEED 0b01100000 #define BBIO_CAN_SLCAN 0b10100000 -#define BBIO_CAN_SET_TIMINGS 0b11000000 /* * PIN control-specific commands @@ -168,4 +170,13 @@ #define BBIO_SMARTCARD_SET_SPEED 0b01100000 #define BBIO_SMARTCARD_CONFIG 0b10000000 +/* + * Auxilary pins commands + */ +#define BBIO_AUX_MASK 0b11000000 +#define BBIO_AUX_READ 0b11000000 +#define BBIO_AUX_WRITE 0b11010000 +#define BBIO_AUX_MODE_READ 0b11100000 +#define BBIO_AUX_MODE_SET 0b11110000 + int cmd_bbio(t_hydra_console *con); diff --git a/src/hydrabus/hydrabus_bbio_aux.c b/src/hydrabus/hydrabus_bbio_aux.c new file mode 100644 index 00000000..cd641a10 --- /dev/null +++ b/src/hydrabus/hydrabus_bbio_aux.c @@ -0,0 +1,108 @@ +/* + * HydraBus/HydraNFC + * + * Copyright (C) 2014-2019 Benjamin VERNOUX + * Copyright (C) 2019 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 "stm32f4xx_hal.h" + +#include "hydrabus_bbio.h" +#include "hydrabus_bbio_aux.h" +#include "bsp_gpio.h" + +void bbio_aux_init_proto_default(t_hydra_console *con) +{ + mode_config_proto_t* proto = &con->mode->proto; + + //Default to input no pullup + proto->aux_config = 0b00001111; + + bbio_aux_mode_set(con); +} + +uint8_t bbio_aux_mode_get(t_hydra_console *con) +{ + mode_config_proto_t* proto = &con->mode->proto; + return proto->aux_config; +} + +void bbio_aux_mode_set(t_hydra_console *con) +{ + mode_config_proto_t* proto = &con->mode->proto; + + mode_dev_gpio_mode_t mode; + mode_dev_gpio_pull_t pull; + uint8_t i=0; + + for(i=0; i<4; i++) { + if( (proto->aux_config >> i) & 0b1) { + mode = MODE_CONFIG_DEV_GPIO_IN; + } else { + mode = MODE_CONFIG_DEV_GPIO_OUT_PUSHPULL; + } + if( (proto->aux_config >> (4 + i)) & 0b1) { + pull = MODE_CONFIG_DEV_GPIO_PULLUP; + } else { + pull = MODE_CONFIG_DEV_GPIO_NOPULL; + } + bsp_gpio_init(BSP_GPIO_PORTC, 4+i, mode, pull); + } +} + +uint8_t bbio_aux_read(void) +{ + uint16_t data; + data = bsp_gpio_port_read(BSP_GPIO_PORTC); + return (uint8_t)(data>>4) & 0b1111; +} + +void bbio_aux_write(uint8_t command) +{ + uint8_t i=0; + for(i=0; i<4; i++){ + if((command>>i)&1){ + bsp_gpio_set(BSP_GPIO_PORTC, 4+i); + }else{ + bsp_gpio_clr(BSP_GPIO_PORTC, 4+i); + } + } +} + +uint8_t bbio_aux(t_hydra_console *con, uint8_t command) +{ + mode_config_proto_t* proto = &con->mode->proto; + + uint8_t config; + + switch(command & 0b11110000){ + case BBIO_AUX_MODE_READ: + return bbio_aux_mode_get(con); + case BBIO_AUX_MODE_SET: + chnRead(con->sdu, &config, 1); + proto->aux_config = config; + bbio_aux_mode_set(con); + return 1; + case BBIO_AUX_READ: + return bbio_aux_read(); + case BBIO_AUX_WRITE: + bbio_aux_write(command); + return 1; + default: + return 0; + } +} diff --git a/src/hydrabus/hydrabus_bbio_aux.h b/src/hydrabus/hydrabus_bbio_aux.h new file mode 100644 index 00000000..0c2eefcf --- /dev/null +++ b/src/hydrabus/hydrabus_bbio_aux.h @@ -0,0 +1,24 @@ +/* + * HydraBus/HydraNFC + * + * Copyright (C) 2019 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_aux_init_proto_default(t_hydra_console *con); +uint8_t bbio_aux_mode_get(t_hydra_console *con); +void bbio_aux_mode_set(t_hydra_console *con); +uint8_t bbio_aux_read(void); +void bbio_aux_write(uint8_t command); +uint8_t bbio_aux(t_hydra_console *con, uint8_t command); diff --git a/src/hydrabus/hydrabus_bbio_can.c b/src/hydrabus/hydrabus_bbio_can.c index 45681fc7..9f3c5b3c 100644 --- a/src/hydrabus/hydrabus_bbio_can.c +++ b/src/hydrabus/hydrabus_bbio_can.c @@ -159,7 +159,9 @@ void bbio_mode_can(t_hydra_console *con) } break; default: - if ((bbio_subcommand & BBIO_CAN_WRITE) == BBIO_CAN_WRITE) { + if ((bbio_subcommand & BBIO_AUX_MASK) == BBIO_AUX_MASK) { + cprintf(con, "%c", bbio_aux(con, bbio_subcommand)); + } else if ((bbio_subcommand & BBIO_CAN_WRITE) == BBIO_CAN_WRITE) { if (can_id < 0b11111111111) { tx_msg.header.StdId = can_id; @@ -244,7 +246,6 @@ void bbio_mode_can(t_hydra_console *con) cprint(con, "\x00", 1); } } - } } } diff --git a/src/hydrabus/hydrabus_bbio_i2c.c b/src/hydrabus/hydrabus_bbio_i2c.c index c743c737..52f29dc4 100644 --- a/src/hydrabus/hydrabus_bbio_i2c.c +++ b/src/hydrabus/hydrabus_bbio_i2c.c @@ -151,7 +151,9 @@ void bbio_mode_i2c(t_hydra_console *con) cprint(con, (char *)rx_data, to_rx); break; default: - if ((bbio_subcommand & BBIO_I2C_BULK_WRITE) == BBIO_I2C_BULK_WRITE) { + if ((bbio_subcommand & BBIO_AUX_MASK) == BBIO_AUX_MASK) { + cprintf(con, "%c", bbio_aux(con, bbio_subcommand)); + } else if ((bbio_subcommand & BBIO_I2C_BULK_WRITE) == BBIO_I2C_BULK_WRITE) { // data contains the number of bytes to // write data = (bbio_subcommand & 0b1111) + 1; @@ -187,7 +189,6 @@ void bbio_mode_i2c(t_hydra_console *con) cprint(con, "\x00", 1); } } - } } } diff --git a/src/hydrabus/hydrabus_bbio_onewire.c b/src/hydrabus/hydrabus_bbio_onewire.c index cad9f1c9..6012f64f 100644 --- a/src/hydrabus/hydrabus_bbio_onewire.c +++ b/src/hydrabus/hydrabus_bbio_onewire.c @@ -64,7 +64,9 @@ void bbio_mode_onewire(t_hydra_console *con) cprint(con, (char *)&rx_data[0], 1); break; default: - if ((bbio_subcommand & BBIO_ONEWIRE_BULK_TRANSFER) == BBIO_ONEWIRE_BULK_TRANSFER) { + if ((bbio_subcommand & BBIO_AUX_MASK) == BBIO_AUX_MASK) { + cprintf(con, "%c", bbio_aux(con, bbio_subcommand)); + } else if ((bbio_subcommand & BBIO_ONEWIRE_BULK_TRANSFER) == BBIO_ONEWIRE_BULK_TRANSFER) { // data contains the number of bytes to // write data = (bbio_subcommand & 0b1111) + 1; diff --git a/src/hydrabus/hydrabus_bbio_rawwire.c b/src/hydrabus/hydrabus_bbio_rawwire.c index 84d0551d..cab399be 100644 --- a/src/hydrabus/hydrabus_bbio_rawwire.c +++ b/src/hydrabus/hydrabus_bbio_rawwire.c @@ -127,7 +127,9 @@ void bbio_mode_rawwire(t_hydra_console *con) cprint(con, "\x01", 1); break; default: - if ((bbio_subcommand & BBIO_RAWWIRE_BULK_TRANSFER) == BBIO_RAWWIRE_BULK_TRANSFER) { + if ((bbio_subcommand & BBIO_AUX_MASK) == BBIO_AUX_MASK) { + cprintf(con, "%c", bbio_aux(con, bbio_subcommand)); + } else if ((bbio_subcommand & BBIO_RAWWIRE_BULK_TRANSFER) == BBIO_RAWWIRE_BULK_TRANSFER) { // data contains the number of bytes to // write data = (bbio_subcommand & 0b1111) + 1; @@ -201,7 +203,6 @@ void bbio_mode_rawwire(t_hydra_console *con) } else if ((bbio_subcommand & BBIO_RAWWIRE_CONFIG_PERIPH) == BBIO_RAWWIRE_CONFIG_PERIPH) { cprint(con, "\x01", 1); } - } } } diff --git a/src/hydrabus/hydrabus_bbio_smartcard.c b/src/hydrabus/hydrabus_bbio_smartcard.c index 732b91c1..47e52ac8 100644 --- a/src/hydrabus/hydrabus_bbio_smartcard.c +++ b/src/hydrabus/hydrabus_bbio_smartcard.c @@ -175,7 +175,9 @@ void bbio_mode_smartcard(t_hydra_console *con) } break; default: - if ((bbio_subcommand & BBIO_SMARTCARD_CONFIG) == BBIO_SMARTCARD_CONFIG) { + if ((bbio_subcommand & BBIO_AUX_MASK) == BBIO_AUX_MASK) { + cprintf(con, "%c", bbio_aux(con, bbio_subcommand)); + } else if ((bbio_subcommand & BBIO_SMARTCARD_CONFIG) == BBIO_SMARTCARD_CONFIG) { proto->config.smartcard.dev_polarity = (bbio_subcommand & 0b1)?1:0; proto->config.smartcard.dev_stop_bit = @@ -190,7 +192,6 @@ void bbio_mode_smartcard(t_hydra_console *con) cprint(con, "\x00", 1); } } - } } } diff --git a/src/hydrabus/hydrabus_bbio_spi.c b/src/hydrabus/hydrabus_bbio_spi.c index 99cdc44e..e37b6384 100644 --- a/src/hydrabus/hydrabus_bbio_spi.c +++ b/src/hydrabus/hydrabus_bbio_spi.c @@ -245,10 +245,10 @@ void bbio_mode_spi(t_hydra_console *con) } break; - - default: - if ((bbio_subcommand & BBIO_SPI_BULK_TRANSFER) == BBIO_SPI_BULK_TRANSFER) { + if ((bbio_subcommand & BBIO_AUX_MASK) == BBIO_AUX_MASK) { + cprintf(con, "%c", bbio_aux(con, bbio_subcommand)); + } else if ((bbio_subcommand & BBIO_SPI_BULK_TRANSFER) == BBIO_SPI_BULK_TRANSFER) { // data contains the number of bytes to // write data = (bbio_subcommand & 0b1111) + 1; @@ -290,7 +290,6 @@ void bbio_mode_spi(t_hydra_console *con) } cprint(con, "\x01", 1); } - } } } diff --git a/src/hydrabus/hydrabus_bbio_uart.c b/src/hydrabus/hydrabus_bbio_uart.c index 20c8cf0b..2d31363e 100644 --- a/src/hydrabus/hydrabus_bbio_uart.c +++ b/src/hydrabus/hydrabus_bbio_uart.c @@ -122,7 +122,9 @@ void bbio_mode_uart(t_hydra_console *con) } break; default: - if ((bbio_subcommand & BBIO_UART_BULK_TRANSFER) == BBIO_UART_BULK_TRANSFER) { + if ((bbio_subcommand & BBIO_AUX_MASK) == BBIO_AUX_MASK) { + cprintf(con, "%c", bbio_aux(con, bbio_subcommand)); + } else if ((bbio_subcommand & BBIO_UART_BULK_TRANSFER) == BBIO_UART_BULK_TRANSFER) { // data contains the number of bytes to // write data = (bbio_subcommand & 0b1111) + 1; @@ -204,7 +206,6 @@ void bbio_mode_uart(t_hydra_console *con) } else if ((bbio_subcommand & BBIO_UART_CONFIG_PERIPH) == BBIO_UART_CONFIG_PERIPH) { cprint(con, "\x01", 1); } - } } }