diff options
-rw-r--r-- | firmware/Makefile | 2 | ||||
-rw-r--r-- | firmware/src_simtrace/i2c.c | 206 | ||||
-rw-r--r-- | firmware/src_simtrace/i2c.h | 5 | ||||
-rw-r--r-- | firmware/src_simtrace/main.c | 13 |
4 files changed, 225 insertions, 1 deletions
diff --git a/firmware/Makefile b/firmware/Makefile index 588601d..13766e9 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -147,7 +147,7 @@ C_CMSIS = core_cm3.o C_LOWLEVEL = board_cstartup_gnu.o board_lowlevel.o syscalls.o exceptions.o C_LIBLEVEL = spi.o pio.o pmc.o usart.o pio_it.o pio_capture.o uart_console.o iso7816_4.o wdt.o led.o tc.o unique_id.o C_CCID = cciddriver.o USBD.o USBDDriver.o USBD_HAL.o USBRequests.o USBDCallbacks.o USBDescriptors.o USBDDriverCallbacks.o -C_SIMTRACE = simtrace_iso7816.o usb.o ccid.o sniffer.o mitm.o ringbuffer.o host_communication.o iso7816_fidi.o tc_etu.o req_ctx.o card_emu.o mode_cardemu.o +C_SIMTRACE = simtrace_iso7816.o usb.o ccid.o sniffer.o mitm.o ringbuffer.o host_communication.o iso7816_fidi.o tc_etu.o req_ctx.o card_emu.o mode_cardemu.o i2c.o C_APPLEVEL = main.o C_OBJECTS = $(C_CMSIS) $(C_LOWLEVEL) $(C_LIBLEVEL) $(C_APPLEVEL) $(C_CCID) $(C_SIMTRACE) diff --git a/firmware/src_simtrace/i2c.c b/firmware/src_simtrace/i2c.c new file mode 100644 index 0000000..3a36888 --- /dev/null +++ b/firmware/src_simtrace/i2c.c @@ -0,0 +1,206 @@ +#include "board.h" +#include <stdbool.h> + +/* Low-Level I2C Routines */ + +static const Pin pin_sda = {PIO_PA30, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_OPENDRAIN }; +static const Pin pin_sda_in = {PIO_PA30, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT }; +static const Pin pin_scl = {PIO_PA31, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_OPENDRAIN }; + +void i2c_pin_init(void) +{ + PIO_Configure(&pin_scl, PIO_LISTSIZE(pin_scl)); + PIO_Configure(&pin_sda, PIO_LISTSIZE(pin_sda)); +} + +static void set_scl(void) +{ + PIO_Set(&pin_scl); +} + +static void set_sda(void) +{ + PIO_Set(&pin_sda); +} + +static void clear_scl(void) +{ + PIO_Clear(&pin_scl); +} + +static void clear_sda(void) +{ + PIO_Clear(&pin_sda); +} + +static bool read_sda(void) +{ + bool ret; + + PIO_Configure(&pin_sda_in, PIO_LISTSIZE(pin_sda_in)); + if (PIO_Get(&pin_sda)) + ret = true; + else + ret = false; + PIO_Configure(&pin_sda, PIO_LISTSIZE(pin_sda)); + + return ret; +} + +/* Core I2C Routines */ + +static bool i2c_started = false; + +static void i2c_delay() +{ + volatile int v; + int i; + + for (i = 0; i < 100; i++) { + v = 0; + } +} + +static void i2c_start_cond(void) +{ + if (i2c_started) { + set_sda(); + i2c_delay(); + set_scl(); + i2c_delay(); + } + + i2c_delay(); + clear_sda(); + i2c_delay(); + clear_scl(); + i2c_started = true; +} + +static void i2c_stop_cond(void) +{ + clear_sda(); + i2c_delay(); + set_scl(); + i2c_delay(); + set_sda(); + i2c_delay(); + i2c_started = false; +} + +static void i2c_write_bit(bool bit) +{ + if (bit) + set_sda(); + else + clear_sda(); + i2c_delay(); + set_scl(); + i2c_delay(); + clear_scl(); + i2c_delay(); +} + +static bool i2c_read_bit(void) +{ + bool bit; + + set_sda(); + i2c_delay(); + set_scl(); + i2c_delay(); + bit = read_sda(); + clear_scl(); + + return bit; +} + +bool i2c_write_byte(bool send_start, bool send_stop, uint8_t byte) +{ + uint8_t bit; + bool nack; + + if (send_start) + i2c_start_cond(); + + for (bit = 0; bit < 8; bit++) { + i2c_write_bit((byte & 0x80) != 0); + byte <<= 1; + } + + nack = i2c_read_bit(); + + if (send_stop) + i2c_stop_cond(); + + return nack; +} + +uint8_t i2c_read_byte(bool nack, bool send_stop) +{ + uint8_t byte = 0; + uint8_t bit; + + for (bit = 0; bit < 8; bit++) { + byte = (byte << 1) | i2c_read_bit(); + } + + i2c_write_bit(nack); + + if (send_stop) + i2c_stop_cond(); + + return byte; +} + + +/* EEPROM related code */ + +int eeprom_write_byte(uint8_t slave, uint8_t addr, uint8_t byte) +{ + bool nack; + + /* Write slave address */ + nack = i2c_write_byte(true, false, slave << 1); + if (nack) + goto out_stop; + nack = i2c_write_byte(false, false, addr); + if (nack) + goto out_stop; + nack = i2c_write_byte(false, true, byte); + if (nack) + goto out_stop; + +out_stop: + i2c_stop_cond(); + if (nack) + return -1; + else + return 0; +} + +int eeprom_read_byte(uint8_t slave, uint8_t addr) +{ + bool nack; + + /* dummy write cycle */ + nack = i2c_write_byte(true, false, slave << 1); + if (nack) + goto out_stop; + nack = i2c_write_byte(false, false, addr); + if (nack) + goto out_stop; + /* Re-start with read */ + nack = i2c_write_byte(true, false, (slave << 1) | 1); + if (nack) + goto out_stop; + + return i2c_read_byte(true, true); + +out_stop: + i2c_stop_cond(); + if (nack) + return -1; + else + return 0; +} diff --git a/firmware/src_simtrace/i2c.h b/firmware/src_simtrace/i2c.h new file mode 100644 index 0000000..15e4b37 --- /dev/null +++ b/firmware/src_simtrace/i2c.h @@ -0,0 +1,5 @@ +#pragma once + +void i2c_pin_init(void); +int eeprom_write_byte(uint8_t slave, uint8_t addr, uint8_t byte); +int eeprom_read_byte(uint8_t slave, uint8_t addr); diff --git a/firmware/src_simtrace/main.c b/firmware/src_simtrace/main.c index 5d5e332..c4e6f3c 100644 --- a/firmware/src_simtrace/main.c +++ b/firmware/src_simtrace/main.c @@ -97,6 +97,7 @@ void USART0_IrqHandler(void) config_func_ptrs[simtrace_config].usart0_irq(); } +#include "i2c.h" /*------------------------------------------------------------------------------ * Main *------------------------------------------------------------------------------*/ @@ -131,6 +132,18 @@ extern int main(void) g_unique_id[0], g_unique_id[1], g_unique_id[2], g_unique_id[3]); +#if 1 + static const Pin pin_hub_rst = {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}; + PIO_Configure(&pin_hub_rst, 1); + i2c_pin_init(); + while (1) { + for (i = 0; i < 256; i ++) { + int byte = eeprom_read_byte(0x50, i); + TRACE_INFO("0x%02x: %02x\r\n", i, byte); + } + } +#endif + TRACE_INFO("USB init...\r\n"); while (USBD_GetState() < USBD_STATE_CONFIGURED) { if (i >= MAX_USB_ITER * 3) { |