Change in ...simtrace2[master]: add new board and app for gpio testing on octsimtest board

laforge gerrit-no-reply at lists.osmocom.org
Tue Jul 30 12:41:30 UTC 2019


laforge has submitted this change and it was merged. ( https://gerrit.osmocom.org/c/simtrace2/+/14969 )

Change subject: add new board and app for gpio testing on octsimtest board
......................................................................

add new board and app for gpio testing on octsimtest board

Change-Id: I01243044002f51b34e8dc12c1b1f565bbf1740a2
---
M firmware/README.txt
A firmware/apps/gpio_test/Makefile
A firmware/apps/gpio_test/gpio_test.c
A firmware/apps/gpio_test/main.c
A firmware/apps/gpio_test/usb_strings.txt
A firmware/libboard/octsimtest/include/board.h
A firmware/libboard/octsimtest/include/i2c.h
A firmware/libboard/octsimtest/include/mcp23017.h
A firmware/libboard/octsimtest/source/board_octsimtest.c
A firmware/libboard/octsimtest/source/i2c.c
A firmware/libboard/octsimtest/source/mcp23017.c
11 files changed, 687 insertions(+), 0 deletions(-)

Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved



diff --git a/firmware/README.txt b/firmware/README.txt
index fa7f60a..cd04e7a 100644
--- a/firmware/README.txt
+++ b/firmware/README.txt
@@ -24,6 +24,7 @@
 * `simtrace`: The good old Osmocom SIMtrace PCB with SAM3 instead of SAM7, open hardware.
 * `qmod`: A sysmocom-proprietary quad mPCIe carrier board, publicly available
 * `owhw`: An undisclosed sysmocom-internal board, not publicly available
+* `octsimtest`: A sysmocom-proprietary production testing board, not publicly available
 
 = Firmware
 
@@ -51,6 +52,7 @@
 * `cardem`: To provide remote SIM operation capabilities.
 * `trace`:  To monitor the communication between a SIM card and a phone (corresponds to the functionality provide by the first SIMtrace)
 * `triple_play`: To support the three previous functionalities, using USB configurations.
+* `gpio_test`: internal test code
 
 == Memories
 
diff --git a/firmware/apps/gpio_test/Makefile b/firmware/apps/gpio_test/Makefile
new file mode 100644
index 0000000..b2b4707
--- /dev/null
+++ b/firmware/apps/gpio_test/Makefile
@@ -0,0 +1,3 @@
+C_FILES += $(C_LIBUSB_RT)
+
+C_FILES += gpio_test.c
diff --git a/firmware/apps/gpio_test/gpio_test.c b/firmware/apps/gpio_test/gpio_test.c
new file mode 100644
index 0000000..2ab23e7
--- /dev/null
+++ b/firmware/apps/gpio_test/gpio_test.c
@@ -0,0 +1,10 @@
+#include <stdint.h>
+#include "utils.h"
+#include "chip.h"
+
+
+
+void gpio_test_init(void)
+{
+	printf("FIXME run tests here\n\n");
+}
diff --git a/firmware/apps/gpio_test/main.c b/firmware/apps/gpio_test/main.c
new file mode 100644
index 0000000..8fe68b3
--- /dev/null
+++ b/firmware/apps/gpio_test/main.c
@@ -0,0 +1,54 @@
+
+#include "board.h"
+#include "utils.h"
+#include "osmocom/core/timer.h"
+
+extern void gpio_test_init(void);
+
+/* returns '1' in case we should break any endless loop */
+static void check_exec_dbg_cmd(void)
+{
+	int ch;
+
+	if (!UART_IsRxReady())
+		return;
+
+	ch = UART_GetChar();
+
+	board_exec_dbg_cmd(ch);
+}
+
+
+extern int main(void)
+{
+	led_init();
+	led_blink(LED_RED, BLINK_ALWAYS_ON);
+	led_blink(LED_GREEN, BLINK_ALWAYS_ON);
+
+	/* Enable watchdog for 2000 ms, with no window */
+	WDT_Enable(WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT |
+		   (WDT_GetPeriod(2000) << 16) | WDT_GetPeriod(2000));
+
+	PIO_InitializeInterrupts(0);
+
+
+	printf("\n\r\n\r"
+		"=============================================================================\n\r"
+		"GPIO Test firmware " GIT_VERSION " (C) 2019 Sysmocom GmbH\n\r"
+		"=============================================================================\n\r");
+
+	board_main_top();
+
+	TRACE_INFO("starting gpio test...\n\r");
+	gpio_test_init();
+
+	TRACE_INFO("entering main loop...\n\r");
+	while (1) {
+		WDT_Restart(WDT);
+
+		check_exec_dbg_cmd();
+		osmo_timers_prepare();
+		osmo_timers_update();
+	}
+
+}
diff --git a/firmware/apps/gpio_test/usb_strings.txt b/firmware/apps/gpio_test/usb_strings.txt
new file mode 100644
index 0000000..0e797ac
--- /dev/null
+++ b/firmware/apps/gpio_test/usb_strings.txt
@@ -0,0 +1,10 @@
+sysmocom - s.f.m.c. GmbH
+SIMtrace 2 compatible device
+SIMtrace Sniffer
+SIMtrace CCID
+SIMtrace Phone
+SIMtrace MITM
+CardEmulator Modem 1
+CardEmulator Modem 2
+CardEmulator Modem 3
+CardEmulator Modem 4
diff --git a/firmware/libboard/octsimtest/include/board.h b/firmware/libboard/octsimtest/include/board.h
new file mode 100644
index 0000000..2effc02
--- /dev/null
+++ b/firmware/libboard/octsimtest/include/board.h
@@ -0,0 +1,154 @@
+/* octSIMtest with SAM3S board definition
+ *
+ * (C) 2019 by sysmocom -s.f.m.c. GmbH, Author:Joachim Steiger <jsteiger at sysmocom.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA
+ */
+#pragma once
+#include "board_common.h"
+#include "simtrace_usb.h"
+
+/* Name of the board */
+#define BOARD_NAME "OCTSIMTEST"
+/* Board definition */
+#define octsimtest
+
+/** oscillator used as main clock source (in Hz) */
+#define BOARD_MAINOSC 18432000
+/** desired main clock frequency (in Hz, based on BOARD_MAINOSC) */
+#define BOARD_MCK 58982400 // 18.432 * 16 / 5
+
+/** Pin configuration **/
+/* Button to force bootloader start (shorted to ground when pressed */
+#define PIN_BOOTLOADER_SW      {PIO_PA5, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
+
+//FIXME SIM_PWEN_PIN collides with PA5/bootloader_sw on octsimtest
+/* Enable powering the card using the second 3.3 V output of the LDO (active high) */
+#define SIM_PWEN_PIN           {PIO_PA12, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+/* Enable powering the SIM card */
+#define PWR_PINS                SIM_PWEN_PIN
+
+// FIXME PA8 is 32khz xtal on octsimtest
+/* Card presence pin */
+#define SW_SIM                  PIO_PA11
+/* Pull card presence pin high (shorted to ground in card slot when card is present) */
+#define SMARTCARD_CONNECT_PIN  {SW_SIM, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
+
+/** Smart card connection **/
+//FIXME
+/* Card RST reset signal input (active low; RST_SIM in schematic) */
+#define PIN_SIM_RST            {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+/* Card I/O data signal input/output (I/O_SIM in schematic) */
+#define PIN_SIM_IO             {PIO_PA6A_TXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/* Card CLK clock input (CLK_SIM in schematic) */
+#define PIN_SIM_CLK            {PIO_PA2B_SCK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+/* Pin to measure card I/O timing (to start measuring the ETU on I/O activity; connected I/O_SIM in schematic) */
+#define PIN_SIM_IO_INPUT       {PIO_PA1B_TIOB0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+//FIXME PIO_PA4B_TCLK0 PA4 is LED on octsimtest
+/* Pin used as clock input (to measure the ETU duration; connected to CLK_SIM in schematic) */
+#define PIN_SIM_CLK_INPUT      {PIO_PA14, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+/* Pins used to measure ETU timing (using timer counter) */ 
+#define PINS_TC                 PIN_SIM_IO_INPUT, PIN_SIM_CLK_INPUT
+
+/** Phone connection **/
+/* Phone USIM slot 1 VCC pin (VCC_PHONE in schematic) */
+#define PIN_USIM1_VCC          {PIO_PA25, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
+/* Phone USIM slot 1 RST pin (active low; RST_PHONE in schematic) */
+#define PIN_USIM1_nRST         {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_IT_RISE_EDGE | PIO_DEGLITCH }
+/* Phone I/O data signal input/output (I/O_PHONE in schematic) */
+#define PIN_PHONE_IO           {PIO_PA22A_TXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/* Phone CLK clock input (CLK_PHONE in schematic) */
+#define PIN_PHONE_CLK          {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/* Pin used for phone USIM slot 1 communication */
+#define PINS_USIM1              PIN_PHONE_IO, PIN_PHONE_CLK, PIN_PHONE_CLK_INPUT, PIN_USIM1_VCC, PIN_PHONE_IO_INPUT, PIN_USIM1_nRST
+/* Phone I/O data signal input/output (unused USART RX input; connected to I/O_PHONE in schematic) */
+#define PIN_PHONE_IO_INPUT     {PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/* Pin used as clock input (to measure the ETU duration; connected to CLK_PHONE in schematic) */
+#define PIN_PHONE_CLK_INPUT    {PIO_PA29B_TCLK2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+
+/** Default pin configuration **/
+/* Disconnect VPP, CLK, and RST lines between card and phone using bus switch (high sets bus switch to high-impedance) */
+#define PIN_SC_SW_DEFAULT      {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+/* Disconnect I/O line between card and phone using bus switch (high sets bus switch to high-impedance) */
+#define PIN_IO_SW_DEFAULT      {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+/* Disconnect all lines (VPP, CLK, RST, and I/O) between card and phone */
+#define PINS_BUS_DEFAULT        PIN_SC_SW_DEFAULT, PIN_IO_SW_DEFAULT
+
+/** Sniffer configuration **/
+/* Connect VPP, CLK, and RST lines between card and phone using bus switch (low connects signals on bus switch) */
+#define PIN_SC_SW_SNIFF        {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+/* Connect I/O line between card and phone using bus switch (low connects signals on bus switch) */
+#define PIN_IO_SW_SNIFF        {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+/* Connect all lines (VPP, CLK, RST, and I/O) between card and phone */
+#define PINS_BUS_SNIFF          PIN_SC_SW_SNIFF, PIN_IO_SW_SNIFF
+/* Card RST reset signal input (use as input since the phone will drive it) */
+#define PIN_SIM_RST_SNIFF      {PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_IT_EDGE}
+/* Pins used to sniff phone-card communication */
+#define PINS_SIM_SNIFF          PIN_SIM_IO, PIN_SIM_CLK, PIN_SIM_RST_SNIFF
+/* Disable power converter 4.5-6V to 3.3V (active high) */
+#define PIN_SIM_PWEN_SNIFF     {SIM_PWEN, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+/* Enable power switch to forward VCC_PHONE to VCC_SIM (active high) */
+#define PIN_VCC_FWD_SNIFF      {VCC_FWD, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+/* Use phone VCC to power card */
+#define PINS_PWR_SNIFF          PIN_SIM_PWEN_SNIFF, PIN_VCC_FWD_SNIFF
+
+/** CCID configuration */
+/* Card RST reset signal input (active low; RST_SIM in schematic) */
+#define PIN_ISO7816_RSTMC      {PIO_PA7, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+/* ISO7816-communication related pins */
+#define PINS_ISO7816            PIN_SIM_IO,  PIN_SIM_CLK,  PIN_ISO7816_RSTMC // SIM_PWEN_PIN, PIN_SIM_IO2, PIN_SIM_CLK2
+
+/** External SPI flash interface   **/
+/* SPI MISO pin definition */
+#define PIN_SPI_MISO  {PIO_PA12A_MISO, PIOA, PIOA, PIO_PERIPH_A, PIO_PULLUP}
+/* SPI MOSI pin definition */
+#define PIN_SPI_MOSI  {PIO_PA13A_MOSI, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/* SPI SCK pin definition */
+#define PIN_SPI_SCK   {PIO_PA14A_SPCK, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/* SPI pins definition. Contains MISO, MOSI & SCK */
+#define PINS_SPI       PIN_SPI_MISO, PIN_SPI_MOSI, PIN_SPI_SCK
+/* SPI chip select 0 pin definition */
+#define PIN_SPI_NPCS0 {PIO_PA11A_NPCS0, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/* SPI flash write protect pin (active low, pulled low) */
+#define PIN_SPI_WP    {PA15, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+
+/** Pin configuration to control USB pull-up on D+
+ *  @details the USB pull-up on D+ is enable by default on the board but can be disabled by setting PA16 high
+ */
+#define PIN_USB_PULLUP  {PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+
+/** USB definitions */
+/* OpenMoko SIMtrace 2 USB vendor ID */
+#define BOARD_USB_VENDOR_ID	USB_VENDOR_OPENMOKO
+/* OpenMoko SIMtrace 2 USB product ID (main application/runtime mode) */
+#define BOARD_USB_PRODUCT_ID	USB_PRODUCT_SIMTRACE2
+/* OpenMoko SIMtrace 2 DFU USB product ID (DFU bootloader/DFU mode) */
+#define BOARD_DFU_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2_DFU
+/* USB release number (bcdDevice, shown as 0.00) */
+#define BOARD_USB_RELEASE	0x000
+/* Indicate SIMtrace is bus power in USB attributes */
+#define BOARD_USB_BMATTRIBUTES	USBConfigurationDescriptor_BUSPOWERED_NORWAKEUP
+
+/** Supported modes */
+/* SIMtrace board supports sniffer mode */
+//#define HAVE_SNIFFER
+/* SIMtrace board supports CCID mode */
+//#define HAVE_CCID
+/* SIMtrace board supports card emulation mode */
+//#define HAVE_CARDEM
+/* SIMtrace board supports man-in-the-middle mode */
+//#define HAVE_MITM
+/* octsimtest board supports gpio_test mode */
+#define HAVE_GPIO_TEST
diff --git a/firmware/libboard/octsimtest/include/i2c.h b/firmware/libboard/octsimtest/include/i2c.h
new file mode 100644
index 0000000..5a8c908
--- /dev/null
+++ b/firmware/libboard/octsimtest/include/i2c.h
@@ -0,0 +1,28 @@
+/* I2C EEPROM memory read and write utilities
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA
+ */
+#pragma once
+
+#include <stdbool.h>
+
+void i2c_pin_init(void);
+
+bool i2c_write_byte(bool send_start, bool send_stop, uint8_t byte);
+uint8_t i2c_read_byte(bool nack, bool send_stop);
+static void i2c_stop_cond(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/libboard/octsimtest/include/mcp23017.h b/firmware/libboard/octsimtest/include/mcp23017.h
new file mode 100644
index 0000000..dea6285
--- /dev/null
+++ b/firmware/libboard/octsimtest/include/mcp23017.h
@@ -0,0 +1,23 @@
+/* mcp23017 i2c gpio expander read and write utilities
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA
+ */
+#pragma once
+
+#define MCP23017_ADDRESS 0x20
+
+int mcp23017_init(uint8_t slave);
+//int mcp23017_write_byte(uint8_t slave, uint8_t addr, uint8_t byte);
+//int mcp23017_read_byte(uint8_t slave, uint8_t addr);
diff --git a/firmware/libboard/octsimtest/source/board_octsimtest.c b/firmware/libboard/octsimtest/source/board_octsimtest.c
new file mode 100644
index 0000000..2772015
--- /dev/null
+++ b/firmware/libboard/octsimtest/source/board_octsimtest.c
@@ -0,0 +1,72 @@
+/* SIMtrace with SAM3S specific application code
+ *
+ * (C) 2017 by Harald Welte <laforge at gnumonks.org>
+ * (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon at sysmocom.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA
+ */
+#include "board.h"
+#include "simtrace.h"
+#include "utils.h"
+#include "sim_switch.h"
+#include <osmocom/core/timer.h>
+#include "usb_buf.h"
+#include "i2c.h"
+#include "mcp23017.h"
+
+void board_exec_dbg_cmd(int ch)
+{
+	switch (ch) {
+	case '?':
+		printf("\t?\thelp\n\r");
+		printf("\tR\treset SAM3\n\r");
+		break;
+	case 'R':
+		printf("Asking NVIC to reset us\n\r");
+		USBD_Disconnect();
+		NVIC_SystemReset();
+		break;
+	default:
+		printf("Unknown command '%c'\n\r", ch);
+		break;
+	}
+}
+
+void board_main_top(void)
+{
+#ifndef APPLICATION_dfu
+	usb_buf_init();
+
+	i2c_pin_init();
+	mcp23017_init(MCP23017_ADDRESS);
+	/* Initialize checking for card insert/remove events */
+	//card_present_init();
+#endif
+}
+
+int board_override_enter_dfu(void)
+{
+	const Pin bl_sw_pin = PIN_BOOTLOADER_SW;
+
+	PIO_Configure(&bl_sw_pin, 1);
+
+	/* Enter DFU bootloader in case the respective button is pressed */
+	if (PIO_Get(&bl_sw_pin) == 0) {
+		/* do not print to early since the console is not initialized yet */
+		//printf("BOOTLOADER switch pressed -> Force DFU\n\r");
+		return 1;
+	} else
+		return 0;
+}
diff --git a/firmware/libboard/octsimtest/source/i2c.c b/firmware/libboard/octsimtest/source/i2c.c
new file mode 100644
index 0000000..a708704
--- /dev/null
+++ b/firmware/libboard/octsimtest/source/i2c.c
@@ -0,0 +1,225 @@
+/* I2C EEPROM memory read and write utilities
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA
+ */
+#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 };
+
+static void i2c_delay()
+{
+	volatile int v;
+	int i;
+
+	/* 100 cycles results in SCL peak length of 44us, so it's about
+	 * 440ns per cycle here */
+	for (i = 0; i < 14; i++) {
+		v = 0;
+	}
+}
+
+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);
+	i2c_delay();
+}
+
+static void set_sda(void)
+{
+	PIO_Set(&pin_sda);
+	i2c_delay();
+}
+
+static void clear_scl(void)
+{
+	PIO_Clear(&pin_scl);
+	i2c_delay();
+}
+
+static void clear_sda(void)
+{
+	PIO_Clear(&pin_sda);
+	i2c_delay();
+}
+
+static bool read_sda(void)
+{
+	bool ret;
+
+	PIO_Configure(&pin_sda_in, PIO_LISTSIZE(pin_sda_in));
+	if (PIO_Get(&pin_sda_in))
+		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_start_cond(void)
+{
+	if (i2c_started) {
+		set_sda();
+		set_scl();
+	}
+
+	clear_sda();
+	i2c_delay();
+	clear_scl();
+	i2c_started = true;
+}
+
+static void i2c_stop_cond(void)
+{
+	clear_sda();
+	set_scl();
+	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();
+	clear_scl();
+}
+
+static bool i2c_read_bit(void)
+{
+	bool bit;
+
+	set_sda();
+	set_scl();
+	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;
+
+	WDT_Restart(WDT);
+
+	/* 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;
+	/* Wait tWR time to ensure EEPROM is writing correctly (tWR = 5 ms for AT24C02) */
+	mdelay(5);
+
+out_stop:
+	i2c_stop_cond();
+	if (nack)
+		return -1;
+	else
+		return 0;
+}
+
+int eeprom_read_byte(uint8_t slave, uint8_t addr)
+{
+	bool nack;
+
+	WDT_Restart(WDT);
+
+	/* 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/libboard/octsimtest/source/mcp23017.c b/firmware/libboard/octsimtest/source/mcp23017.c
new file mode 100644
index 0000000..63390b4
--- /dev/null
+++ b/firmware/libboard/octsimtest/source/mcp23017.c
@@ -0,0 +1,106 @@
+#include "board.h"
+#include <stdbool.h>
+#include "i2c.h"
+#include "mcp23017.h"
+
+
+//defines from https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/blob/master/Adafruit_MCP23017.h under BSD license
+
+// registers
+#define MCP23017_IODIRA 0x00
+#define MCP23017_IPOLA 0x02
+#define MCP23017_GPINTENA 0x04
+#define MCP23017_DEFVALA 0x06
+#define MCP23017_INTCONA 0x08
+#define MCP23017_IOCONA 0x0A
+#define MCP23017_GPPUA 0x0C
+#define MCP23017_INTFA 0x0E
+#define MCP23017_INTCAPA 0x10
+#define MCP23017_GPIOA 0x12
+#define MCP23017_OLATA 0x14
+
+
+#define MCP23017_IODIRB 0x01
+#define MCP23017_IPOLB 0x03
+#define MCP23017_GPINTENB 0x05
+#define MCP23017_DEFVALB 0x07
+#define MCP23017_INTCONB 0x09
+#define MCP23017_IOCONB 0x0B
+#define MCP23017_GPPUB 0x0D
+#define MCP23017_INTFB 0x0F
+#define MCP23017_INTCAPB 0x11
+#define MCP23017_GPIOB 0x13
+#define MCP23017_OLATB 0x15
+
+#define MCP23017_INT_ERR 255
+
+
+//bool i2c_write_byte(bool send_start, bool send_stop, uint8_t byte)
+//uint8_t i2c_read_byte(bool nack, bool send_stop)
+//static void i2c_stop_cond(void)
+
+int mcp23017_write_byte(uint8_t slave, uint8_t addr, uint8_t byte)
+{
+	bool nack;
+
+	WDT_Restart(WDT);
+
+//	 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 mcp23017_read_byte(uint8_t slave, uint8_t addr)
+{
+	bool nack;
+
+	WDT_Restart(WDT);
+
+	// 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;
+}
+
+int mcp23017_init(uint8_t slave)
+{
+	printf("mcp23017_init\n");
+	// all gpio input
+	if (mcp23017_write_byte(slave, MCP23017_IODIRA, 0xff))
+		return false;
+	if (mcp23017_write_byte(slave, MCP23017_IODIRB, 0xff))
+		return false;
+	printf("mcp23017 found\n");
+	return true;
+}
+

-- 
To view, visit https://gerrit.osmocom.org/c/simtrace2/+/14969
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: simtrace2
Gerrit-Branch: master
Gerrit-Change-Id: I01243044002f51b34e8dc12c1b1f565bbf1740a2
Gerrit-Change-Number: 14969
Gerrit-PatchSet: 2
Gerrit-Owner: roh <jsteiger at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at gnumonks.org>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190730/2073f35f/attachment.html>


More information about the gerrit-log mailing list