mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-18 14:18:50 +03:00
Compare commits
8 Commits
laforge/ng
...
laforge/to
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb8fbc0296 | ||
|
|
9292d22726 | ||
|
|
d2bc858ddf | ||
|
|
29de264d6e | ||
|
|
07fda1e706 | ||
|
|
ed4ca25730 | ||
|
|
69c32f2e38 | ||
|
|
53dfaa0aab |
@@ -27,9 +27,7 @@ class Device(NamedTuple):
|
|||||||
DEVICE_SIMTRACE = Device(usb_vendor_id=0x1d50, usb_product_id=0x60e3, name="SIMtrace 2", url={"trace": "https://ftp.osmocom.org/binaries/simtrace2/firmware/latest/simtrace-trace-dfu-latest.bin", "cardem": "https://osmocom.org/attachments/download/3868/simtrace-cardem-dfu.bin"})
|
DEVICE_SIMTRACE = Device(usb_vendor_id=0x1d50, usb_product_id=0x60e3, name="SIMtrace 2", url={"trace": "https://ftp.osmocom.org/binaries/simtrace2/firmware/latest/simtrace-trace-dfu-latest.bin", "cardem": "https://osmocom.org/attachments/download/3868/simtrace-cardem-dfu.bin"})
|
||||||
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_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_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_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
|
# which firmware does the SIMtrace USN interface subclass correspond
|
||||||
FIRMWARE_SUBCLASS = {1: "trace", 2: "cardem"}
|
FIRMWARE_SUBCLASS = {1: "trace", 2: "cardem"}
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
usb_simtrace_protocol = Proto("USB_simtrace", "USB simtrace protocol")
|
|
||||||
|
|
||||||
|
|
||||||
local control_commands = {
|
|
||||||
-- /* SIMTRACE_MSGC_GENERIC */
|
|
||||||
[0x0000] = "SIMTRACE_CMD_DO_ERROR",
|
|
||||||
[0x0001] = "SIMTRACE_CMD_BD_BOARD_INFO",
|
|
||||||
|
|
||||||
-- /* SIMTRACE_MSGC_CARDEM */
|
|
||||||
[0x0101] = "SIMTRACE_MSGT_DT_CEMU_TX_DATA",
|
|
||||||
[0x0102] = "SIMTRACE_MSGT_DT_CEMU_SET_ATR",
|
|
||||||
[0x0103] = "SIMTRACE_MSGT_BD_CEMU_STATS",
|
|
||||||
[0x0104] = "SIMTRACE_MSGT_BD_CEMU_STATUS",
|
|
||||||
[0x0105] = "SIMTRACE_MSGT_DT_CEMU_CARDINSERT",
|
|
||||||
[0x0106] = "SIMTRACE_MSGT_DO_CEMU_RX_DATA",
|
|
||||||
[0x0107] = "SIMTRACE_MSGT_DO_CEMU_PTS",
|
|
||||||
[0x0108] = "SIMTRACE_MSGT_BD_CEMU_CONFIG",
|
|
||||||
|
|
||||||
-- /* SIMTRACE_MSGC_MODEM */
|
|
||||||
[0x0201] = "SIMTRACE_MSGT_DT_MODEM_RESET",
|
|
||||||
[0x0202] = "SIMTRACE_MSGT_DT_MODEM_SIM_SELECT",
|
|
||||||
[0x0203] = "SIMTRACE_MSGT_BD_MODEM_STATUS",
|
|
||||||
|
|
||||||
-- /* SIMTRACE_MSGC_SNIFF */
|
|
||||||
[0x0300] = "SIMTRACE_MSGT_SNIFF_CHANGE",
|
|
||||||
[0x0301] = "SIMTRACE_MSGT_SNIFF_FIDI",
|
|
||||||
[0x0302] = "SIMTRACE_MSGT_SNIFF_ATR",
|
|
||||||
[0x0304] = "SIMTRACE_MSGT_SNIFF_TPDU",
|
|
||||||
[0x0303] = "SIMTRACE_MSGT_SNIFF_PPS"
|
|
||||||
}
|
|
||||||
|
|
||||||
local msgtype = ProtoField.uint16("usb_simtrace.msgtype", "Message Type", base.HEX_DEC, control_commands)
|
|
||||||
local seqnr = ProtoField.uint8("usb_simtrace.seqnr", "Sequence Number", base.HEX_DEC)
|
|
||||||
local slotnr = ProtoField.uint8("usb_simtrace.slotnr", "Slot Number", base.HEX_DEC)
|
|
||||||
local reserved = ProtoField.uint16("usb_simtrace.reserved", "reserved", base.HEX_DEC)
|
|
||||||
local payloadlen = ProtoField.uint16("usb_simtrace.length", "length", base.HEX_DEC)
|
|
||||||
local payload = ProtoField.bytes("usb_simtrace.payload", "Data")
|
|
||||||
|
|
||||||
usb_simtrace_protocol.fields = {
|
|
||||||
msgtype, seqnr, slotnr, reserved, payloadlen, payload
|
|
||||||
}
|
|
||||||
|
|
||||||
function usb_simtrace_protocol.dissector(buffer, pinfo, tree)
|
|
||||||
length = buffer:len()
|
|
||||||
if length == 0 then return end
|
|
||||||
|
|
||||||
pinfo.cols.protocol = usb_simtrace_protocol.name
|
|
||||||
|
|
||||||
local subtree = tree:add(usb_simtrace_protocol, buffer(), "USB simtrace Data")
|
|
||||||
local command = buffer(0,2):uint()
|
|
||||||
|
|
||||||
subtree:add(msgtype, command):set_generated()
|
|
||||||
subtree:add(seqnr, buffer(2,1))
|
|
||||||
subtree:add(slotnr, buffer(3,1))
|
|
||||||
subtree:add_le(payloadlen, buffer(6,2))
|
|
||||||
pinfo.cols.info = string.format("Cmd 0x%04X : %s", command, control_commands[command])
|
|
||||||
subtree:add(payload, buffer(8,length-8))
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
@@ -221,6 +221,7 @@ extern int main(void)
|
|||||||
}
|
}
|
||||||
last_simtrace_config = simtrace_config;
|
last_simtrace_config = simtrace_config;
|
||||||
} else {
|
} else {
|
||||||
|
//FIXME: usb_proces() for every interface in this configuration?
|
||||||
if (config_func_ptrs[simtrace_config].run) {
|
if (config_func_ptrs[simtrace_config].run) {
|
||||||
config_func_ptrs[simtrace_config].run();
|
config_func_ptrs[simtrace_config].run();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1672,6 +1672,10 @@ uint8_t USBD_HAL_Halt(uint8_t bEndpoint, uint8_t ctl)
|
|||||||
UDP->UDP_RST_EP |= 1 << bEndpoint;
|
UDP->UDP_RST_EP |= 1 << bEndpoint;
|
||||||
UDP->UDP_RST_EP &= ~(1 << bEndpoint);
|
UDP->UDP_RST_EP &= ~(1 << bEndpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This fixes a weird bug with regard to ping-pong OUT endpoints */
|
||||||
|
UDP->UDP_RST_EP |= 1 << bEndpoint;
|
||||||
|
UDP->UDP_RST_EP &= ~(1 << bEndpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return Halt status */
|
/* Return Halt status */
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
/* Osmocom ngff-cardem board definition
|
|
||||||
*
|
|
||||||
* (C) 2021 by Harald Welte <laforge@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
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
/* card presence utilities
|
|
||||||
*
|
|
||||||
* (C) 2016-2017 by Harald Welte <hwelte@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);
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/* 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);
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/* 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);
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
ngff-cardem
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
/* sysmocom quad-modem sysmoQMOD application code
|
|
||||||
*
|
|
||||||
* (C) 2021 Harald Welte <laforge@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;
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
/* card presence utilities
|
|
||||||
*
|
|
||||||
* (C) 2016-2021 by Harald Welte <hwelte@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;
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
/* Code to switch between local (physical) and remote (emulated) SIM
|
|
||||||
*
|
|
||||||
* (C) 2015-2017 by Harald Welte <hwelte@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;
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
/* 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;
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
/* 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;
|
|
||||||
}
|
|
||||||
@@ -91,8 +91,8 @@
|
|||||||
#define PINS_WWAN_IN { PIN_WWAN1, PIN_WWAN2 }
|
#define PINS_WWAN_IN { PIN_WWAN1, PIN_WWAN2 }
|
||||||
|
|
||||||
/* outputs controlling RESET input of modems */
|
/* outputs controlling RESET input of modems */
|
||||||
#define PIN_PERST1 {PIO_PA25, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_PULLUP}
|
#define PIN_PERST1 {PIO_PA25, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_PULLUP}
|
||||||
#define PIN_PERST2 {PIO_PA26, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_PULLUP}
|
#define PIN_PERST2 {PIO_PA26, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_PULLUP}
|
||||||
#define PINS_PERST { PIN_PERST1, PIN_PERST2 }
|
#define PINS_PERST { PIN_PERST1, PIN_PERST2 }
|
||||||
|
|
||||||
#define PIN_VERSION_DET {PIO_PA19, PIOA, ID_PIOA, PIO_PERIPH_D, PIO_DEFAULT}
|
#define PIN_VERSION_DET {PIO_PA19, PIOA, ID_PIOA, PIO_PERIPH_D, PIO_DEFAULT}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
#define USB_PRODUCT_SIMTRACE2_DFU 0x60e3 /* was 0x60e2 */
|
#define USB_PRODUCT_SIMTRACE2_DFU 0x60e3 /* was 0x60e2 */
|
||||||
#define USB_PRODUCT_SIMTRACE2 0x60e3
|
#define USB_PRODUCT_SIMTRACE2 0x60e3
|
||||||
#define USB_PRODUCT_OCTSIMTEST 0x616d
|
#define USB_PRODUCT_OCTSIMTEST 0x616d
|
||||||
#define USB_PRODUCT_NGFF_CARDEM 0x616e
|
|
||||||
|
|
||||||
/* USB proprietary class */
|
/* USB proprietary class */
|
||||||
#define USB_CLASS_PROPRIETARY 0xff
|
#define USB_CLASS_PROPRIETARY 0xff
|
||||||
|
|||||||
@@ -42,5 +42,15 @@ int usb_drain_queue(uint8_t ep);
|
|||||||
void usb_buf_init(void);
|
void usb_buf_init(void);
|
||||||
struct usb_buffered_ep *usb_get_buf_ep(uint8_t ep);
|
struct usb_buffered_ep *usb_get_buf_ep(uint8_t ep);
|
||||||
|
|
||||||
int usb_refill_to_host(uint8_t ep);
|
struct usb_if {
|
||||||
int usb_refill_from_host(uint8_t ep);
|
uint8_t if_num; /* interface number */
|
||||||
|
uint8_t ep_out; /* OUT endpoint (0 if none) */
|
||||||
|
uint8_t ep_in; /* IN endpint (0 if none) */
|
||||||
|
uint8_t ep_int; /* INT endpoint (0 if none) */
|
||||||
|
void *data; /* opaque data, passed through */
|
||||||
|
struct {
|
||||||
|
/* call-back to be called for inclming messages on OUT EP */
|
||||||
|
void (*rx_out)(struct msgb *msg, const struct usb_if *usb_if);
|
||||||
|
} ops;
|
||||||
|
};
|
||||||
|
void usb_process(const struct usb_if *usb_if);
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ static void usb_write_cb(uint8_t *arg, uint8_t status, uint32_t transferred,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if the spcified IN endpoint is idle and submit the next buffer from queue */
|
/* check if the spcified IN endpoint is idle and submit the next buffer from queue */
|
||||||
int usb_refill_to_host(uint8_t ep)
|
static int usb_refill_to_host(uint8_t ep)
|
||||||
{
|
{
|
||||||
struct usb_buffered_ep *bep = usb_get_buf_ep(ep);
|
struct usb_buffered_ep *bep = usb_get_buf_ep(ep);
|
||||||
struct msgb *msg;
|
struct msgb *msg;
|
||||||
@@ -130,7 +130,7 @@ static void usb_read_cb(uint8_t *arg, uint8_t status, uint32_t transferred,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* refill the read queue for data received from host PC on OUT EP, if needed */
|
/* refill the read queue for data received from host PC on OUT EP, if needed */
|
||||||
int usb_refill_from_host(uint8_t ep)
|
static int usb_refill_from_host(uint8_t ep)
|
||||||
{
|
{
|
||||||
struct usb_buffered_ep *bep = usb_get_buf_ep(ep);
|
struct usb_buffered_ep *bep = usb_get_buf_ep(ep);
|
||||||
struct msgb *msg;
|
struct msgb *msg;
|
||||||
@@ -198,3 +198,45 @@ int usb_drain_queue(uint8_t ep)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* iterate over the queue of incoming USB commands and dispatch/execute
|
||||||
|
* them */
|
||||||
|
static void process_any_usb_commands(const struct usb_if *usb_if)
|
||||||
|
{
|
||||||
|
struct llist_head *queue = usb_get_queue(usb_if->ep_out);
|
||||||
|
struct llist_head *lh;
|
||||||
|
struct msgb *msg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* limit the number of iterations to 10, to ensure we don't get
|
||||||
|
* stuck here without returning to main loop processing */
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
/* de-queue the list head in an irq-safe way */
|
||||||
|
lh = llist_head_dequeue_irqsafe(queue);
|
||||||
|
if (!lh)
|
||||||
|
break;
|
||||||
|
msg = llist_entry(lh, struct msgb, list);
|
||||||
|
usb_if->ops.rx_out(msg, usb_if);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* perform any action related to USB processing (IRQ/INT/OUT EP refill, handling OUT) */
|
||||||
|
void usb_process(const struct usb_if *usb_if)
|
||||||
|
{
|
||||||
|
/* first try to send any pending messages on IRQ */
|
||||||
|
if (usb_if->ep_int)
|
||||||
|
usb_refill_to_host(usb_if->ep_int);
|
||||||
|
|
||||||
|
/* then try to send any pending messages on IN */
|
||||||
|
if (usb_if->ep_in)
|
||||||
|
usb_refill_to_host(usb_if->ep_in);
|
||||||
|
|
||||||
|
/* ensure we can handle incoming USB messages from the
|
||||||
|
* host */
|
||||||
|
if (usb_if->ep_out) {
|
||||||
|
usb_refill_from_host(usb_if->ep_out);
|
||||||
|
process_any_usb_commands(usb_if);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@
|
|||||||
|
|
||||||
#define TRACE_ENTRY() TRACE_DEBUG("%s entering\r\n", __func__)
|
#define TRACE_ENTRY() TRACE_DEBUG("%s entering\r\n", __func__)
|
||||||
|
|
||||||
|
static void dispatch_received_usb_msg(struct msgb *msg, const struct usb_if *usb_if);
|
||||||
|
|
||||||
#ifdef PINS_CARDSIM
|
#ifdef PINS_CARDSIM
|
||||||
static const Pin pins_cardsim[] = PINS_CARDSIM;
|
static const Pin pins_cardsim[] = PINS_CARDSIM;
|
||||||
#endif
|
#endif
|
||||||
@@ -68,12 +70,11 @@ struct cardem_inst {
|
|||||||
bool half_time_notified;
|
bool half_time_notified;
|
||||||
} wt;
|
} wt;
|
||||||
int usb_pending_old;
|
int usb_pending_old;
|
||||||
uint8_t ep_out;
|
struct usb_if usb_if;
|
||||||
uint8_t ep_in;
|
|
||||||
uint8_t ep_int;
|
|
||||||
const Pin pin_insert;
|
const Pin pin_insert;
|
||||||
#ifdef DETECT_VCC_BY_ADC
|
#ifdef DETECT_VCC_BY_ADC
|
||||||
uint32_t vcc_uv;
|
uint32_t vcc_uv;
|
||||||
|
uint32_t vcc_uv_last;
|
||||||
#endif
|
#endif
|
||||||
bool vcc_active;
|
bool vcc_active;
|
||||||
bool vcc_active_last;
|
bool vcc_active_last;
|
||||||
@@ -89,9 +90,16 @@ struct cardem_inst cardem_inst[] = {
|
|||||||
.id = ID_USART1,
|
.id = ID_USART1,
|
||||||
.state = USART_RCV
|
.state = USART_RCV
|
||||||
},
|
},
|
||||||
.ep_out = SIMTRACE_CARDEM_USB_EP_USIM1_DATAOUT,
|
.usb_if = {
|
||||||
.ep_in = SIMTRACE_CARDEM_USB_EP_USIM1_DATAIN,
|
.if_num = 0,
|
||||||
.ep_int = SIMTRACE_CARDEM_USB_EP_USIM1_INT,
|
.ep_out = SIMTRACE_CARDEM_USB_EP_USIM1_DATAOUT,
|
||||||
|
.ep_in = SIMTRACE_CARDEM_USB_EP_USIM1_DATAIN,
|
||||||
|
.ep_int = SIMTRACE_CARDEM_USB_EP_USIM1_INT,
|
||||||
|
.data = &cardem_inst[0],
|
||||||
|
.ops = {
|
||||||
|
.rx_out = dispatch_received_usb_msg,
|
||||||
|
},
|
||||||
|
},
|
||||||
#ifdef PIN_SET_USIM1_PRES
|
#ifdef PIN_SET_USIM1_PRES
|
||||||
.pin_insert = PIN_SET_USIM1_PRES,
|
.pin_insert = PIN_SET_USIM1_PRES,
|
||||||
#endif
|
#endif
|
||||||
@@ -104,9 +112,16 @@ struct cardem_inst cardem_inst[] = {
|
|||||||
.id = ID_USART0,
|
.id = ID_USART0,
|
||||||
.state = USART_RCV
|
.state = USART_RCV
|
||||||
},
|
},
|
||||||
.ep_out = SIMTRACE_CARDEM_USB_EP_USIM2_DATAOUT,
|
.usb_if = {
|
||||||
.ep_in = SIMTRACE_CARDEM_USB_EP_USIM2_DATAIN,
|
.if_num = 1,
|
||||||
.ep_int = SIMTRACE_CARDEM_USB_EP_USIM2_INT,
|
.ep_out = SIMTRACE_CARDEM_USB_EP_USIM2_DATAOUT,
|
||||||
|
.ep_in = SIMTRACE_CARDEM_USB_EP_USIM2_DATAIN,
|
||||||
|
.ep_int = SIMTRACE_CARDEM_USB_EP_USIM2_INT,
|
||||||
|
.data = &cardem_inst[1],
|
||||||
|
.ops = {
|
||||||
|
.rx_out = dispatch_received_usb_msg,
|
||||||
|
},
|
||||||
|
},
|
||||||
#ifdef PIN_SET_USIM2_PRES
|
#ifdef PIN_SET_USIM2_PRES
|
||||||
.pin_insert = PIN_SET_USIM2_PRES,
|
.pin_insert = PIN_SET_USIM2_PRES,
|
||||||
#endif
|
#endif
|
||||||
@@ -253,6 +268,7 @@ static uint16_t compute_next_timeout(struct cardem_inst *ci)
|
|||||||
* \param[in] inst_num Instance number, range 0..1 (some boards only '0' permitted) */
|
* \param[in] inst_num Instance number, range 0..1 (some boards only '0' permitted) */
|
||||||
static void usart_irq_rx(uint8_t inst_num)
|
static void usart_irq_rx(uint8_t inst_num)
|
||||||
{
|
{
|
||||||
|
OSMO_ASSERT(inst_num < ARRAY_SIZE(cardem_inst));
|
||||||
Usart *usart = get_usart_by_chan(inst_num);
|
Usart *usart = get_usart_by_chan(inst_num);
|
||||||
struct cardem_inst *ci = &cardem_inst[inst_num];
|
struct cardem_inst *ci = &cardem_inst[inst_num];
|
||||||
uint32_t csr;
|
uint32_t csr;
|
||||||
@@ -461,14 +477,14 @@ static int card_vcc_adc_init(void)
|
|||||||
|
|
||||||
static void process_vcc_adc(struct cardem_inst *ci)
|
static void process_vcc_adc(struct cardem_inst *ci)
|
||||||
{
|
{
|
||||||
#ifdef octsimtest
|
if (ci->vcc_uv >= VCC_UV_THRESH_3V &&
|
||||||
if (ci->vcc_uv >= VCC_UV_THRESH_1V8)
|
ci->vcc_uv_last < VCC_UV_THRESH_3V) {
|
||||||
#else
|
|
||||||
if (ci->vcc_uv >= VCC_UV_THRESH_3V)
|
|
||||||
#endif
|
|
||||||
ci->vcc_active = true;
|
ci->vcc_active = true;
|
||||||
else
|
} else if (ci->vcc_uv < VCC_UV_THRESH_3V &&
|
||||||
|
ci->vcc_uv_last >= VCC_UV_THRESH_3V) {
|
||||||
ci->vcc_active = false;
|
ci->vcc_active = false;
|
||||||
|
}
|
||||||
|
ci->vcc_uv_last = ci->vcc_uv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADC_IrqHandler(void)
|
void ADC_IrqHandler(void)
|
||||||
@@ -709,7 +725,6 @@ static void dispatch_usb_command_cardem(struct msgb *msg, struct cardem_inst *ci
|
|||||||
case SIMTRACE_MSGT_BD_CEMU_CONFIG:
|
case SIMTRACE_MSGT_BD_CEMU_CONFIG:
|
||||||
cfg = (struct cardemu_usb_msg_config *) msg->l2h;
|
cfg = (struct cardemu_usb_msg_config *) msg->l2h;
|
||||||
card_emu_set_config(ci->ch, cfg, msgb_l2len(msg));
|
card_emu_set_config(ci->ch, cfg, msgb_l2len(msg));
|
||||||
usb_buf_free(msg);
|
|
||||||
break;
|
break;
|
||||||
case SIMTRACE_MSGT_BD_CEMU_STATS:
|
case SIMTRACE_MSGT_BD_CEMU_STATS:
|
||||||
default:
|
default:
|
||||||
@@ -786,8 +801,9 @@ static void dispatch_usb_command_modem(struct msgb *msg, struct cardem_inst *ci)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* handle a single USB command as received from the USB host */
|
/* handle a single USB command as received from the USB host */
|
||||||
static void dispatch_usb_command(struct msgb *msg, struct cardem_inst *ci)
|
static void dispatch_usb_command(struct msgb *msg, const struct usb_if *usb_if)
|
||||||
{
|
{
|
||||||
|
struct cardem_inst *ci = usb_if->data;
|
||||||
struct simtrace_msg_hdr *sh = (struct simtrace_msg_hdr *) msg->l1h;
|
struct simtrace_msg_hdr *sh = (struct simtrace_msg_hdr *) msg->l1h;
|
||||||
|
|
||||||
if (msgb_length(msg) < sizeof(*sh)) {
|
if (msgb_length(msg) < sizeof(*sh)) {
|
||||||
@@ -816,7 +832,8 @@ static void dispatch_usb_command(struct msgb *msg, struct cardem_inst *ci)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dispatch_received_msg(struct msgb *msg, struct cardem_inst *ci)
|
/* handle a single USB transfer as received from the USB host */
|
||||||
|
static void dispatch_received_usb_msg(struct msgb *msg, const struct usb_if *usb_if)
|
||||||
{
|
{
|
||||||
struct msgb *segm;
|
struct msgb *segm;
|
||||||
struct simtrace_msg_hdr *mh;
|
struct simtrace_msg_hdr *mh;
|
||||||
@@ -827,7 +844,7 @@ static void dispatch_received_msg(struct msgb *msg, struct cardem_inst *ci)
|
|||||||
mh = (struct simtrace_msg_hdr *) msg->data;
|
mh = (struct simtrace_msg_hdr *) msg->data;
|
||||||
if (mh->msg_len == msgb_length(msg)) {
|
if (mh->msg_len == msgb_length(msg)) {
|
||||||
/* fast path: only one message in buffer */
|
/* fast path: only one message in buffer */
|
||||||
dispatch_usb_command(msg, ci);
|
dispatch_usb_command(msg, usb_if);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -836,23 +853,23 @@ static void dispatch_received_msg(struct msgb *msg, struct cardem_inst *ci)
|
|||||||
while (1) {
|
while (1) {
|
||||||
mh = (struct simtrace_msg_hdr *) msg->data;
|
mh = (struct simtrace_msg_hdr *) msg->data;
|
||||||
|
|
||||||
segm = usb_buf_alloc(ci->ep_out);
|
segm = usb_buf_alloc(usb_if->ep_out);
|
||||||
if (!segm) {
|
if (!segm) {
|
||||||
TRACE_ERROR("%u: ENOMEM during msg segmentation\r\n",
|
TRACE_ERROR("%u: ENOMEM during msg segmentation\r\n",
|
||||||
ci->num);
|
usb_if->if_num);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mh->msg_len > msgb_length(msg)) {
|
if (mh->msg_len > msgb_length(msg)) {
|
||||||
TRACE_ERROR("%u: Unexpected large message (%u bytes)\r\n",
|
TRACE_ERROR("%u: Unexpected large message (%u bytes)\r\n",
|
||||||
ci->num, mh->msg_len);
|
usb_if->if_num, mh->msg_len);
|
||||||
usb_buf_free(segm);
|
usb_buf_free(segm);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
uint8_t *cur = msgb_put(segm, mh->msg_len);
|
uint8_t *cur = msgb_put(segm, mh->msg_len);
|
||||||
segm->l1h = segm->head;
|
segm->l1h = segm->head;
|
||||||
memcpy(cur, mh, mh->msg_len);
|
memcpy(cur, mh, mh->msg_len);
|
||||||
dispatch_usb_command(segm, ci);
|
dispatch_usb_command(segm, usb_if);
|
||||||
}
|
}
|
||||||
/* pull this message */
|
/* pull this message */
|
||||||
msgb_pull(msg, mh->msg_len);
|
msgb_pull(msg, mh->msg_len);
|
||||||
@@ -864,35 +881,14 @@ static void dispatch_received_msg(struct msgb *msg, struct cardem_inst *ci)
|
|||||||
usb_buf_free(msg);
|
usb_buf_free(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* iterate over the queue of incoming USB commands and dispatch/execute
|
|
||||||
* them */
|
|
||||||
static void process_any_usb_commands(struct llist_head *main_q,
|
|
||||||
struct cardem_inst *ci)
|
|
||||||
{
|
|
||||||
struct llist_head *lh;
|
|
||||||
struct msgb *msg;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* limit the number of iterations to 10, to ensure we don't get
|
|
||||||
* stuck here without returning to main loop processing */
|
|
||||||
for (i = 0; i < 10; i++) {
|
|
||||||
/* de-queue the list head in an irq-safe way */
|
|
||||||
lh = llist_head_dequeue_irqsafe(main_q);
|
|
||||||
if (!lh)
|
|
||||||
break;
|
|
||||||
msg = llist_entry(lh, struct msgb, list);
|
|
||||||
dispatch_received_msg(msg, ci);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* main loop function, called repeatedly */
|
/* main loop function, called repeatedly */
|
||||||
void mode_cardemu_run(void)
|
void mode_cardemu_run(void)
|
||||||
{
|
{
|
||||||
struct llist_head *queue;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(cardem_inst); i++) {
|
for (i = 0; i < ARRAY_SIZE(cardem_inst); i++) {
|
||||||
struct cardem_inst *ci = &cardem_inst[i];
|
struct cardem_inst *ci = &cardem_inst[i];
|
||||||
|
struct usb_if *usb_if = &ci->usb_if;
|
||||||
|
|
||||||
/* drain the ring buffer from UART into card_emu */
|
/* drain the ring buffer from UART into card_emu */
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -909,16 +905,6 @@ void mode_cardemu_run(void)
|
|||||||
|
|
||||||
process_io_statechg(ci);
|
process_io_statechg(ci);
|
||||||
|
|
||||||
/* first try to send any pending messages on IRQ */
|
usb_process(&ci->usb_if);
|
||||||
usb_refill_to_host(ci->ep_int);
|
|
||||||
|
|
||||||
/* then try to send any pending messages on IN */
|
|
||||||
usb_refill_to_host(ci->ep_in);
|
|
||||||
|
|
||||||
/* ensure we can handle incoming USB messages from the
|
|
||||||
* host */
|
|
||||||
usb_refill_from_host(ci->ep_out);
|
|
||||||
queue = usb_get_queue(ci->ep_out);
|
|
||||||
process_any_usb_commands(queue, ci);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -975,20 +975,42 @@ static void usb_send_change(uint32_t flags)
|
|||||||
usb_msg_upd_len_and_submit(usb_msg);
|
usb_msg_upd_len_and_submit(usb_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* handle incoming message from USB OUT EP */
|
||||||
|
static void dispatch_usb_out(struct msgb *msg, const struct usb_if *usb_if)
|
||||||
|
{
|
||||||
|
struct simtrace_msg_hdr *sh = (struct simtrace_msg_hdr *) msg->l1h;
|
||||||
|
|
||||||
|
if (msgb_length(msg) < sizeof(*sh)) {
|
||||||
|
usb_buf_free(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
msg->l2h = msg->l1h + sizeof(*sh);
|
||||||
|
|
||||||
|
switch (sh->msg_class) {
|
||||||
|
case SIMTRACE_MSGC_GENERIC:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
usb_buf_free(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct usb_if sniffer_usb_if = {
|
||||||
|
.if_num = 0,
|
||||||
|
.ep_in = SIMTRACE_USB_EP_CARD_DATAIN,
|
||||||
|
.ep_int = SIMTRACE_USB_EP_CARD_INT,
|
||||||
|
.ep_out = SIMTRACE_USB_EP_CARD_DATAOUT,
|
||||||
|
.ops = {
|
||||||
|
.rx_out = dispatch_usb_out,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* Main (idle/busy) loop of this USB configuration */
|
/* Main (idle/busy) loop of this USB configuration */
|
||||||
void Sniffer_run(void)
|
void Sniffer_run(void)
|
||||||
{
|
{
|
||||||
/* Handle USB queue */
|
/* Handle USB queue */
|
||||||
/* first try to send any pending messages on INT */
|
usb_process(&sniffer_usb_if);
|
||||||
usb_refill_to_host(SIMTRACE_USB_EP_CARD_INT);
|
|
||||||
/* then try to send any pending messages on IN */
|
|
||||||
usb_refill_to_host(SIMTRACE_USB_EP_CARD_DATAIN);
|
|
||||||
/* ensure we can handle incoming USB messages from the host */
|
|
||||||
/* currently we don't need any incoming data
|
|
||||||
usb_refill_from_host(SIMTRACE_USB_EP_CARD_DATAOUT);
|
|
||||||
struct llist_head *queue = usb_get_queue(SIMTRACE_USB_EP_CARD_DATAOUT);
|
|
||||||
process_any_usb_commands(queue);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* WARNING: the signal data and flags are not synchronized. We have to hope
|
/* WARNING: the signal data and flags are not synchronized. We have to hope
|
||||||
* the processing is fast enough to not land in the wrong state while data
|
* the processing is fast enough to not land in the wrong state while data
|
||||||
|
|||||||
Binary file not shown.
@@ -16,10 +16,6 @@ ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="4002", GROUP="plugdev"
|
|||||||
# sysmocom QMOD SAM3 (DFU and runtime)
|
# sysmocom QMOD SAM3 (DFU and runtime)
|
||||||
ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="4003", GROUP="plugdev"
|
ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="4003", GROUP="plugdev"
|
||||||
ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="4004", GROUP="plugdev"
|
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
|
# All done
|
||||||
LABEL="simtrace2_rules_end"
|
LABEL="simtrace2_rules_end"
|
||||||
|
|||||||
@@ -33,6 +33,5 @@ const struct dev_id osmo_st2_compatible_dev_ids[] = {
|
|||||||
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_QMOD_SAM3 },
|
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_QMOD_SAM3 },
|
||||||
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_SIMTRACE2 },
|
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_SIMTRACE2 },
|
||||||
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_OCTSIMTEST },
|
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_OCTSIMTEST },
|
||||||
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_NGFF_CARDEM },
|
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user