Change in simtrace2[master]: WIP: introduce support for new ngff_cardem board

laforge gerrit-no-reply at lists.osmocom.org
Wed Jul 7 20:27:42 UTC 2021


laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/simtrace2/+/24879 )


Change subject: WIP: introduce support for new ngff_cardem board
......................................................................

WIP: introduce support for new ngff_cardem board

This adds support for the new ngff_cardem board, a board that
basically combines a ngff breakout board with a built-in SIMtrace2.

The firmware support added by this ptach is currently untested,
and serves as a basis for testing the ngff_cardem prototypes.

Change-Id: I9649c853271c22d5403cdf3a7ec9029c9cecfa32
---
M contrib/flash.py
M contrib/simtrace.lua
A firmware/libboard/ngff_cardem/include/board.h
A firmware/libboard/ngff_cardem/include/card_pres.h
A firmware/libboard/ngff_cardem/include/wwan_led.h
A firmware/libboard/ngff_cardem/include/wwan_perst.h
A firmware/libboard/ngff_cardem/product_string.txt
A firmware/libboard/ngff_cardem/source/board_ngff_cardem.c
A firmware/libboard/ngff_cardem/source/card_pres.c
A firmware/libboard/ngff_cardem/source/sim_switch.c
A firmware/libboard/ngff_cardem/source/wwan_led.c
A firmware/libboard/ngff_cardem/source/wwan_perst.c
M firmware/libcommon/include/simtrace_usb.h
M host/contrib/99-simtrace2.rules
M host/lib/usb_util.c
15 files changed, 716 insertions(+), 1 deletion(-)



  git pull ssh://gerrit.osmocom.org:29418/simtrace2 refs/changes/79/24879/1

diff --git a/contrib/flash.py b/contrib/flash.py
index 21903bb..01fe7c9 100755
--- a/contrib/flash.py
+++ b/contrib/flash.py
@@ -28,7 +28,8 @@
 DEVICE_QMOD = Device(usb_vendor_id=0x1d50, usb_product_id=0x4004, name="sysmoQMOD (Quad Modem)", url={"cardem": "https://ftp.osmocom.org/binaries/simtrace2/firmware/latest/qmod-cardem-dfu-latest.bin"})
 DEVICE_OWHW = Device(usb_vendor_id=0x1d50, usb_product_id=0x4001, name="OWHW", url={"cardem": "https://ftp.osmocom.org/binaries/simtrace2/firmware/latest/owhw-cardem-dfu-latest.bin"})
 DEVICE_OCTSIMTEST = Device(usb_vendor_id=0x1d50, usb_product_id=0x616d, name="OCTSIMTEST", url={"cardem": "https://ftp.osmocom.org/binaries/simtrace2/firmware/latest/octsimtest-cardem-dfu-latest.bin"})
-DEVICES = [DEVICE_SIMTRACE, DEVICE_QMOD, DEVICE_OCTSIMTEST]
+DEVICE_NGFF_CARDEM = Device(usb_vendor_id=0x1d50, usb_product_id=0x616e, name="ngff-cardem", url={"cardem": "https://ftp.osmocom.org/binaries/simtrace2/firmware/latest/ngff_cardem-cardem-dfu-latest.bin"})
+DEVICES = [DEVICE_SIMTRACE, DEVICE_QMOD, DEVICE_OCTSIMTEST, DEVICE_NGFF_CARDEM]
 
 # which firmware does the SIMtrace USN interface subclass correspond
 FIRMWARE_SUBCLASS = {1: "trace", 2: "cardem"}
diff --git a/contrib/simtrace.lua b/contrib/simtrace.lua
index 68eb961..8298265 100644
--- a/contrib/simtrace.lua
+++ b/contrib/simtrace.lua
@@ -62,6 +62,7 @@
 function usb_simtrace_protocol.init()
 local usb_product_dissectors = DissectorTable.get("usb.product")
 usb_product_dissectors:add(0x1d50616d, usb_simtrace_protocol)
+usb_product_dissectors:add(0x1d50616e, usb_simtrace_protocol)
 
 -- DissectorTable.get("usb.bulk"):add(0xffff, usb_simtrace_protocol)
 end
diff --git a/firmware/libboard/ngff_cardem/include/board.h b/firmware/libboard/ngff_cardem/include/board.h
new file mode 100644
index 0000000..8520d6b
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/include/board.h
@@ -0,0 +1,107 @@
+/* Osmocom ngff-cardem board definition
+ *
+ * (C) 2021 by Harald Welte <laforge at osmocom.org>
+ *
+ * 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 "NGFF-CARDEM"
+/** Board definition */
+#define ngff_cardem
+
+/** oscillator used as main clock source (in Hz) */
+#define BOARD_MAINOSC 12000000
+/** desired main clock frequency (in Hz, based on BOARD_MAINOSC) */
+#define BOARD_MCK 58000000 // 12.000 * 29 / 6
+
+/** MCU pin connected to red LED */
+#define PIO_LED_RED     PIO_PA17
+/** MCU pin connected to green LED */
+#define PIO_LED_GREEN   PIO_PA18
+/** red LED pin definition */
+#define PIN_LED_RED     {PIO_LED_RED, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+/** green LED pin definition */
+#define PIN_LED_GREEN   {PIO_LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+/** LEDs pin definition */
+#define PINS_LEDS       PIN_LED_RED, PIN_LED_GREEN 
+/** index for red LED in LEDs pin definition array */
+#define LED_NUM_RED     0
+/** index for green LED in LEDs pin definition array */
+#define LED_NUM_GREEN   1
+/** the green LED is actually red and used as indication for USIM1 */
+#define LED_USIM1	LED_GREEN
+
+/* USIM 2 interface (USART) */
+#define PIN_USIM2_CLK		{PIO_PA2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PIN_USIM2_IO		{PIO_PA6, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PINS_ISO7816_USIM2	PIN_USIM2_CLK, PIN_USIM2_IO
+
+/* USIM 2 interface (TC) */
+#define PIN_USIM2_IO_TC		{PIO_PA1, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PIN_USIM2_CLK_TC	{PIO_PA4, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PINS_TC_USIM2		PIN_USIM2_IO_TC, PIN_USIM2_CLK_TC
+
+/* USIM 1 interface (USART) */
+#define PIN_USIM1_IO		{PIO_PA22, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PIN_USIM1_CLK		{PIO_PA23, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PINS_ISO7816_USIM1	PIN_USIM1_CLK, PIN_USIM1_IO
+
+/* USIM 1 interface (TC) */
+#define PIN_USIM1_IO_TC		{PIO_PA27, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PIN_USIM1_CLK_TC	{PIO_PA29, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PINS_TC_USIM1		PIN_USIM1_IO_TC, PIN_USIM1_CLK_TC
+
+#define PIN_USIM1_nRST		{PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
+#define PIN_USIM1_VCC		{PIO_PB2, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
+
+#define PIN_USIM2_nRST		{PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
+//#define PIN_USIM2_VCC		{PIO_PB2, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
+
+#define PINS_USIM1		PINS_TC_USIM1, PINS_ISO7816_USIM1, PIN_USIM1_nRST
+#define PINS_USIM2		PINS_TC_USIM2, PINS_ISO7816_USIM2, PIN_USIM2_nRST
+
+/* from v3 and onwards only (!) */
+#define PIN_DET_USIM1_PRES	{PIO_PA8, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEGLITCH | PIO_IT_EDGE}
+
+/* inputs reading the WWAN LED level */
+#define PIN_WWAN1		{PIO_PA15, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEGLITCH | PIO_IT_EDGE}
+#define PINS_WWAN_IN		{ PIN_WWAN1 }
+
+/* outputs controlling RESET input of modems */
+#define PIN_PERST1		{PIO_PA25, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_PULLUP}
+#define PINS_PERST		{ PIN_PERST1 }
+
+#define PIN_VERSION_DET		{PIO_PA19, PIOA, ID_PIOA, PIO_PERIPH_D, PIO_DEFAULT}
+
+/* GPIO towards SPDT switches between real SIM and SAM3 */
+//#define PIN_SIM_SWITCH1 {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+//#define PIN_SIM_SWITCH2 {PIO_PA28, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+
+#define BOARD_USB_BMATTRIBUTES	USBConfigurationDescriptor_SELFPOWERED_NORWAKEUP
+
+#define BOARD_USB_VENDOR_ID	USB_VENDOR_OPENMOKO
+#define BOARD_USB_PRODUCT_ID	USB_PRODUCT_NGFF_CARDEM
+#define BOARD_DFU_USB_PRODUCT_ID USB_PRODUCT_NGFF_CARDEM
+#define BOARD_USB_RELEASE	0x010
+
+#define DETECT_VCC_BY_ADC
+#define VCC_UV_THRESH_1V8	1500000
+#define VCC_UV_THRESH_3V	2500000
+
+#define HAVE_CARDEM
diff --git a/firmware/libboard/ngff_cardem/include/card_pres.h b/firmware/libboard/ngff_cardem/include/card_pres.h
new file mode 100644
index 0000000..81f0613
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/include/card_pres.h
@@ -0,0 +1,22 @@
+/* card presence utilities
+ *
+ * (C) 2016-2017 by Harald Welte <hwelte at hmw-consulting.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
+
+int is_card_present(int port);
+int card_present_init(void);
diff --git a/firmware/libboard/ngff_cardem/include/wwan_led.h b/firmware/libboard/ngff_cardem/include/wwan_led.h
new file mode 100644
index 0000000..77887c7
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/include/wwan_led.h
@@ -0,0 +1,20 @@
+/* Code to read/track the status of the WWAN LEDs of attached modems
+ * 
+ * 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
+
+int wwan_led_active(int wwan);
+int wwan_led_init(void);
diff --git a/firmware/libboard/ngff_cardem/include/wwan_perst.h b/firmware/libboard/ngff_cardem/include/wwan_perst.h
new file mode 100644
index 0000000..c934afc
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/include/wwan_perst.h
@@ -0,0 +1,21 @@
+/* Code to control the PERST lines of attached modems
+ *
+ * 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
+
+int wwan_perst_set(int modem_nr, int active);
+int wwan_perst_do_reset_pulse(int modem_nr, unsigned int duration_ms);
+int wwan_perst_init(void);
diff --git a/firmware/libboard/ngff_cardem/product_string.txt b/firmware/libboard/ngff_cardem/product_string.txt
new file mode 100644
index 0000000..09a33c6
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/product_string.txt
@@ -0,0 +1 @@
+ngff-cardem
diff --git a/firmware/libboard/ngff_cardem/source/board_ngff_cardem.c b/firmware/libboard/ngff_cardem/source/board_ngff_cardem.c
new file mode 100644
index 0000000..742ec55
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/source/board_ngff_cardem.c
@@ -0,0 +1,152 @@
+/* sysmocom quad-modem sysmoQMOD application code
+ *
+ * (C) 2021 Harald Welte <laforge at osmocom.org>
+ *
+ * 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 "led.h"
+#include "wwan_led.h"
+#include "wwan_perst.h"
+#include "sim_switch.h"
+#include "boardver_adc.h"
+#include "card_pres.h"
+#include <osmocom/core/timer.h>
+#include "usb_buf.h"
+
+/* array of generated USB Strings */
+extern unsigned char *usb_strings[];
+
+/* returns '1' in case we should break any endless loop */
+void board_exec_dbg_cmd(int ch)
+{
+	switch (ch) {
+	case '?':
+		printf("\t?\thelp\n\r");
+		printf("\tR\treset SAM3\n\r");
+		printf("\tl\tswitch off LED 1\n\r");
+		printf("\tL\tswitch on  LED 1\n\r");
+		printf("\tg\tswitch off LED 2\n\r");
+		printf("\tG\tswitch on  LED 2\n\r");
+		printf("\tU\tProceed to USB Initialization\n\r");
+		printf("\t1\tGenerate 1ms reset pulse on WWAN1\n\r");
+		printf("\t!\tSwitch Channel A from physical -> remote\n\r");
+		printf("\t@\tSwitch Channel B from physical -> remote\n\r");
+		printf("\tt\t(pseudo)talloc report\n\r");
+		break;
+	case 'R':
+		printf("Asking NVIC to reset us\n\r");
+		USBD_Disconnect();
+		NVIC_SystemReset();
+		break;
+	case 'l':
+		led_blink(LED_GREEN, BLINK_ALWAYS_OFF);
+		printf("LED 1 switched off\n\r");
+		break;
+	case 'L':
+		led_blink(LED_GREEN, BLINK_ALWAYS_ON);
+		printf("LED 1 switched on\n\r");
+		break;
+	case 'g':
+		led_blink(LED_RED, BLINK_ALWAYS_OFF);
+		printf("LED 2 switched off\n\r");
+		break;
+	case 'G':
+		led_blink(LED_RED, BLINK_ALWAYS_ON);
+		printf("LED 2 switched on\n\r");
+		break;
+	case '1':
+		printf("Resetting Modem\n\r");
+		wwan_perst_do_reset_pulse(0, 300);
+		break;
+	case '!':
+		sim_switch_use_physical(0, 0);
+		break;
+	case 't':
+		talloc_report(NULL, stdout);
+		break;
+	default:
+		printf("Unknown command '%c'\n\r", ch);
+		break;
+	}
+}
+
+void board_main_top(void)
+{
+#ifndef APPLICATION_dfu
+	usb_buf_init();
+
+	wwan_led_init();
+	wwan_perst_init();
+	sim_switch_init();
+#endif
+
+	/* Obtain the circuit board version (currently just prints voltage */
+	get_board_version_adc();
+#ifndef APPLICATION_dfu
+	/* Initialize checking for card insert/remove events */
+	card_present_init();
+#endif
+}
+
+static int uart_has_loopback_jumper(void)
+{
+	unsigned int i;
+	const Pin uart_loopback_pins[] = {
+		{PIO_PA9A_URXD0, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT},
+		{PIO_PA10A_UTXD0, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+	};
+
+	/* Configure UART pins as I/O */
+	PIO_Configure(uart_loopback_pins, PIO_LISTSIZE(uart_loopback_pins));
+
+	/* Send pattern over UART TX and check if it is received on RX
+	 * If the loop doesn't get interrupted, RxD always follows TxD and thus a
+	 * loopback jumper has been placed on RxD/TxD, and we will boot
+	 * into DFU unconditionally
+	 */
+	int has_loopback_jumper = 1;
+	for (i = 0; i < 10; i++) {
+		/* Set TxD high; abort if RxD doesn't go high either */
+		PIO_Set(&uart_loopback_pins[1]);
+		if (!PIO_Get(&uart_loopback_pins[0])) {
+			has_loopback_jumper = 0;
+			break;
+		}
+		/* Set TxD low, abort if RxD doesn't go low either */
+		PIO_Clear(&uart_loopback_pins[1]);
+		if (PIO_Get(&uart_loopback_pins[0])) {
+			has_loopback_jumper = 0;
+			break;
+		}
+	}
+
+	/* Put pins back to UART mode */
+	const Pin uart_pins[] = {PINS_UART};
+	PIO_Configure(uart_pins, PIO_LISTSIZE(uart_pins));
+
+	return has_loopback_jumper;
+}
+
+int board_override_enter_dfu(void)
+{
+	/* If the loopback jumper is set, we enter DFU mode */
+	if (uart_has_loopback_jumper())
+		return 1;
+
+	return 0;
+}
diff --git a/firmware/libboard/ngff_cardem/source/card_pres.c b/firmware/libboard/ngff_cardem/source/card_pres.c
new file mode 100644
index 0000000..198318f
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/source/card_pres.c
@@ -0,0 +1,76 @@
+/* card presence utilities
+ *
+ * (C) 2016-2021 by Harald Welte <hwelte at hmw-consulting.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 <osmocom/core/timer.h>
+#include "board.h"
+#include "utils.h"
+#include "card_pres.h"
+
+#define NUM_CARDPRES	1
+
+#define TIMER_INTERVAL_MS	500
+
+static const Pin pin_cardpres[NUM_CARDPRES] = { PIN_DET_USIM1_PRES };
+static int last_state[NUM_CARDPRES] = { -1 };
+static struct osmo_timer_list cardpres_timer;
+
+/* Determine if a SIM card is present in the given slot */
+int is_card_present(int port)
+{
+	const Pin *pin;
+	int present;
+
+	if (port < 0 || port >= NUM_CARDPRES)
+		return -1;
+	pin = &pin_cardpres[port];
+
+	/* Card present signals are low-active, as we have a switch
+	 * against GND and an internal-pull-up in the SAM3 */
+	present = PIO_Get(pin) ? 0 : 1;
+
+	return present;
+}
+
+static void cardpres_tmr_cb(void *data)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(pin_cardpres); i++) {
+		int state = is_card_present(i);
+		if (state != last_state[i]) {
+			TRACE_INFO("%u: Card Detect Status %d -> %d\r\n", i, last_state[i], state);
+			/* FIXME: report to USB host */
+			last_state[i] = state;
+		}
+	}
+
+	osmo_timer_schedule(&cardpres_timer, 0, TIMER_INTERVAL_MS*1000);
+}
+
+int card_present_init(void)
+{
+	unsigned int i;
+
+	PIO_Configure(pin_cardpres, ARRAY_SIZE(pin_cardpres));
+
+	/* start timer */
+	cardpres_timer.cb = cardpres_tmr_cb;
+	osmo_timer_schedule(&cardpres_timer, 0, TIMER_INTERVAL_MS*1000);
+
+	return 2;
+}
diff --git a/firmware/libboard/ngff_cardem/source/sim_switch.c b/firmware/libboard/ngff_cardem/source/sim_switch.c
new file mode 100644
index 0000000..59513ad
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/source/sim_switch.c
@@ -0,0 +1,90 @@
+/* Code to switch between local (physical) and remote (emulated) SIM
+ *
+ * (C) 2015-2017 by Harald Welte <hwelte at hmw-consulting.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 "trace.h"
+#include "led.h"
+#include "sim_switch.h"
+
+#ifdef PIN_SIM_SWITCH1
+static const Pin pin_conn_usim1 = {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
+#endif
+#ifdef PIN_SIM_SWITCH2
+static const Pin pin_conn_usim2 = {PIO_PA28, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
+#endif
+
+static int initialized = 0;
+
+int sim_switch_use_physical(unsigned int nr, int physical)
+{
+	const Pin *pin;
+	enum led led;
+
+	if (!initialized) {
+		TRACE_ERROR("Somebody forgot to call sim_switch_init()\r\n");
+		sim_switch_init();
+	}
+
+	TRACE_INFO("Modem %d: %s SIM\n\r", nr,
+		   physical ? "physical" : "virtual");
+
+	switch (nr) {
+#ifdef PIN_SIM_SWITCH1
+	case 0:
+		pin = &pin_conn_usim1;
+		led = LED_USIM1;
+		break;
+#endif
+#ifdef PIN_SIM_SWITCH2
+	case 1:
+		pin = &pin_conn_usim2;
+		led = LED_USIM2;
+		break;
+#endif
+	default:
+		TRACE_ERROR("Invalid SIM%u\n\r", nr);
+		return -1;
+	}
+
+	if (physical) {
+		TRACE_INFO("%u: Use local/physical SIM\r\n", nr);
+		PIO_Clear(pin);
+		led_blink(led, BLINK_ALWAYS_ON);
+	} else {
+		TRACE_INFO("%u: Use remote/emulated SIM\r\n", nr);
+		PIO_Set(pin);
+		led_blink(led, BLINK_ALWAYS_OFF);
+	}
+
+	return 0;
+}
+
+int sim_switch_init(void)
+{
+	int num_switch = 0;
+#ifdef PIN_SIM_SWITCH1
+	PIO_Configure(&pin_conn_usim1, 1);
+	num_switch++;
+#endif
+#ifdef PIN_SIM_SWITCH2
+	PIO_Configure(&pin_conn_usim2, 1);
+	num_switch++;
+#endif
+	initialized = 1;
+	return num_switch;
+}
diff --git a/firmware/libboard/ngff_cardem/source/wwan_led.c b/firmware/libboard/ngff_cardem/source/wwan_led.c
new file mode 100644
index 0000000..b3b5693
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/source/wwan_led.c
@@ -0,0 +1,93 @@
+/* Code to read/track the status of the WWAN LEDs of attached modems
+ *
+ * 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
+ */
+/* Depending on the board this is running on,  it might be possible
+ * for the controller to read the status of the WWAN LED output lines of
+ * the cellular modem.  If the board supports this, it sets the
+ * PIN_WWAN1 and/or PIN_WWAN2 defines in its board.h file.
+ */
+#include "board.h"
+#include "wwan_led.h"
+
+#ifdef PIN_WWAN1
+static const Pin pin_wwan1 = PIN_WWAN1;
+
+static void wwan1_irqhandler(const Pin *pPin)
+{
+	int active = wwan_led_active(0);
+
+	TRACE_INFO("0: WWAN LED %u\r\n", active);
+
+	/* TODO: notify host via USB */
+}
+#endif
+
+#ifdef PIN_WWAN2
+static const Pin pin_wwan2 = PIN_WWAN2;
+
+static void wwan2_irqhandler(const Pin *pPin)
+{
+	int active = wwan_led_active(1);
+	TRACE_INFO("1: WWAN LED %u\r\n", active);
+
+	/* TODO: notify host via USB */
+}
+#endif
+
+/* determine if a tiven WWAN led is currently active or not */
+int wwan_led_active(int wwan)
+{
+	const Pin *pin;
+	int active;
+
+	switch (wwan) {
+#ifdef PIN_WWAN1
+	case 0:
+		pin = &pin_wwan1;
+		break;
+#endif
+#ifdef PIN_WWAN2
+	case 1:
+		pin = &pin_wwan2;
+		break;
+#endif
+	default:
+		return -1;
+	}
+
+	active = PIO_Get(pin) ? 0 : 1;
+	return active;
+}
+
+int wwan_led_init(void)
+{
+	int num_leds = 0;
+
+#ifdef PIN_WWAN1
+	PIO_Configure(&pin_wwan1, 1);
+	PIO_ConfigureIt(&pin_wwan1, wwan1_irqhandler);
+	PIO_EnableIt(&pin_wwan1);
+	num_leds++;
+#endif
+
+#ifdef PIN_WWAN2
+	PIO_Configure(&pin_wwan2, 1);
+	PIO_ConfigureIt(&pin_wwan2, wwan2_irqhandler);
+	PIO_EnableIt(&pin_wwan2);
+	num_leds++;
+#endif
+	return num_leds;
+}
diff --git a/firmware/libboard/ngff_cardem/source/wwan_perst.c b/firmware/libboard/ngff_cardem/source/wwan_perst.c
new file mode 100644
index 0000000..95a7c7b
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/source/wwan_perst.c
@@ -0,0 +1,127 @@
+/* Code to control the PERST lines of attached modems
+ *
+ * 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
+ */
+/* Depending on the board this is running on,  it might be possible
+ * for the controller to set the status of the PERST input line of
+ * the cellular modem.  If the board supports this, it sets the
+ * PIN_PERST1 and/or PIN_PERST2 defines in its board.h file.
+ */
+#include "board.h"
+#include "trace.h"
+#include "wwan_perst.h"
+#include <osmocom/core/timer.h>
+
+struct wwan_perst {
+	uint8_t idx;
+	const Pin pin;
+	struct osmo_timer_list timer;
+};
+
+#ifdef PIN_PERST1
+static struct wwan_perst perst1 = {
+	.idx = 0,
+	.pin = PIN_PERST1,
+};
+#endif
+
+#ifdef PIN_PERST2
+static struct wwan_perst perst2 = {
+	.idx = 1,
+	.pin = PIN_PERST2,
+};
+#endif
+
+static int initialized = 0;
+
+static void perst_tmr_cb(void *data)
+{
+	struct wwan_perst *perst = data;
+	/* release the (low-active) reset */
+	TRACE_INFO("%u: De-asserting modem reset\r\n", perst->idx);
+	PIO_Clear(&perst->pin);
+}
+
+static struct wwan_perst *get_perst_for_modem(int modem_nr)
+{
+	if (!initialized) {
+		TRACE_ERROR("Somebody forgot to call wwan_perst_init()\r\n");
+		wwan_perst_init();
+	}
+
+	switch (modem_nr) {
+#ifdef PIN_PERST1
+	case 0:
+		return &perst1;
+#endif
+#ifdef PIN_PERST2
+	case 1:
+		return &perst2;
+#endif
+	default:
+		return NULL;
+	}
+}
+
+int wwan_perst_do_reset_pulse(int modem_nr, unsigned int duration_ms)
+{
+	struct wwan_perst *perst = get_perst_for_modem(modem_nr);
+	if (!perst)
+		return -1;
+
+	TRACE_INFO("%u: Asserting modem reset\r\n", modem_nr);
+	PIO_Set(&perst->pin);
+	osmo_timer_schedule(&perst->timer, duration_ms/1000, (duration_ms%1000)*1000);
+
+	return 0;
+}
+
+int wwan_perst_set(int modem_nr, int active)
+{
+	struct wwan_perst *perst = get_perst_for_modem(modem_nr);
+	if (!perst)
+		return -1;
+
+	osmo_timer_del(&perst->timer);
+	if (active) {
+		TRACE_INFO("%u: Asserting modem reset\r\n", modem_nr);
+		PIO_Set(&perst->pin);
+	} else {
+		TRACE_INFO("%u: De-asserting modem reset\r\n", modem_nr);
+		PIO_Clear(&perst->pin);
+	}
+
+	return 0;
+}
+
+int wwan_perst_init(void)
+{
+	int num_perst = 0;
+#ifdef PIN_PERST1
+	PIO_Configure(&perst1.pin, 1);
+	perst1.timer.cb = perst_tmr_cb;
+	perst1.timer.data = (void *) &perst1;
+	num_perst++;
+#endif
+
+#ifdef PIN_PERST2
+	PIO_Configure(&perst2.pin, 1);
+	perst2.timer.cb = perst_tmr_cb;
+	perst2.timer.data = (void *) &perst2;
+	num_perst++;
+#endif
+	initialized = 1;
+	return num_perst;
+}
diff --git a/firmware/libcommon/include/simtrace_usb.h b/firmware/libcommon/include/simtrace_usb.h
index a232ac5..7bf401c 100644
--- a/firmware/libcommon/include/simtrace_usb.h
+++ b/firmware/libcommon/include/simtrace_usb.h
@@ -26,6 +26,7 @@
 #define USB_PRODUCT_SIMTRACE2_DFU	0x60e3	/* was 0x60e2 */
 #define USB_PRODUCT_SIMTRACE2		0x60e3
 #define USB_PRODUCT_OCTSIMTEST		0x616d
+#define USB_PRODUCT_NGFF_CARDEM		0x616e
 
 /* USB proprietary class */
 #define USB_CLASS_PROPRIETARY			0xff
diff --git a/host/contrib/99-simtrace2.rules b/host/contrib/99-simtrace2.rules
index b576389..5ae04e2 100644
--- a/host/contrib/99-simtrace2.rules
+++ b/host/contrib/99-simtrace2.rules
@@ -18,6 +18,8 @@
 ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="4004", GROUP="plugdev"
 # sysmocom OCTSIMTEST
 ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="616d", GROUP="plugdev"
+# ngff-cardem
+ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="616e", GROUP="plugdev"
 
 # All done
 LABEL="simtrace2_rules_end"
diff --git a/host/lib/usb_util.c b/host/lib/usb_util.c
index 4d3b2b9..872d185 100644
--- a/host/lib/usb_util.c
+++ b/host/lib/usb_util.c
@@ -33,5 +33,6 @@
 	{ USB_VENDOR_OPENMOKO, USB_PRODUCT_QMOD_SAM3 },
 	{ USB_VENDOR_OPENMOKO, USB_PRODUCT_SIMTRACE2 },
 	{ USB_VENDOR_OPENMOKO, USB_PRODUCT_OCTSIMTEST },
+	{ USB_VENDOR_OPENMOKO, USB_PRODUCT_NGFF_CARDEM },
 	{ 0, 0 }
 };

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

Gerrit-Project: simtrace2
Gerrit-Branch: master
Gerrit-Change-Id: I9649c853271c22d5403cdf3a7ec9029c9cecfa32
Gerrit-Change-Number: 24879
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210707/0df7eb7c/attachment.htm>


More information about the gerrit-log mailing list