mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-16 21:28:33 +03:00
When we reset the hub, the hub will actively drvie the PRTPWR signal of the SITMRACE12 low, resulting in the SAM3 being shut off. If we want to "survive" this, we need to set the OVERRIDE before we go into reset. Right now, we never release the signal again, keeping ST12 enabled permanently, which is of course not what we want in general.
263 lines
7.8 KiB
C
263 lines
7.8 KiB
C
// FIXME: Copyright license here
|
|
/*------------------------------------------------------------------------------
|
|
* Headers
|
|
*------------------------------------------------------------------------------*/
|
|
|
|
#include "board.h"
|
|
#include "simtrace.h"
|
|
#include "utils.h"
|
|
#include "req_ctx.h"
|
|
|
|
uint32_t g_unique_id[4];
|
|
|
|
/*------------------------------------------------------------------------------
|
|
* Internal variables
|
|
*------------------------------------------------------------------------------*/
|
|
typedef struct {
|
|
/* static initialization, called whether or not the usb config is active */
|
|
void (*configure) (void);
|
|
/* initialization function after the config was selected */
|
|
void (*init) (void);
|
|
/* de-initialization before selecting new config */
|
|
void (*exit) (void);
|
|
/* main loop content for given configuration */
|
|
void (*run) (void);
|
|
/* Interrupt handler for USART1 */
|
|
void (*usart0_irq) (void);
|
|
/* Interrupt handler for USART1 */
|
|
void (*usart1_irq) (void);
|
|
} conf_func;
|
|
|
|
static const conf_func config_func_ptrs[] = {
|
|
/* array slot 0 is empty, usb configs start at 1 */
|
|
#ifdef HAVE_SNIFFER
|
|
[CFG_NUM_SNIFF] = {
|
|
.configure = Sniffer_configure,
|
|
.init = Sniffer_init,
|
|
.exit = Sniffer_exit,
|
|
.run = Sniffer_run,
|
|
},
|
|
#endif
|
|
#ifdef HAVE_CCID
|
|
[CFG_NUM_CCID] = {
|
|
.configure = CCID_configure,
|
|
.init = CCID_init,
|
|
.exit = CCID_exit,
|
|
.run = CCID_run,
|
|
},
|
|
#endif
|
|
#ifdef HAVE_CARDEM
|
|
[CFG_NUM_PHONE] = {
|
|
.configure = mode_cardemu_configure,
|
|
.init = mode_cardemu_init,
|
|
.exit = mode_cardemu_exit,
|
|
.run = mode_cardemu_run,
|
|
.usart0_irq = mode_cardemu_usart0_irq,
|
|
.usart1_irq = mode_cardemu_usart1_irq,
|
|
},
|
|
#endif
|
|
#ifdef HAVE_MITM
|
|
[CFG_NUM_MITM] = {
|
|
.configure = MITM_configure,
|
|
.init = MITM_init,
|
|
.exit = MITM_exit,
|
|
.run = MITM_run,
|
|
},
|
|
#endif
|
|
};
|
|
|
|
/*------------------------------------------------------------------------------
|
|
* Internal variables
|
|
*------------------------------------------------------------------------------*/
|
|
#if defined(HAVE_SNIFFER)
|
|
static volatile enum confNum simtrace_config = CFG_NUM_SNIFF;
|
|
#elif defined(HAVE_CARDEM)
|
|
static volatile enum confNum simtrace_config = CFG_NUM_PHONE;
|
|
#elif defined(HAVE_CCID)
|
|
static volatile enum confNum simtrace_config = CFG_NUM_CCID;
|
|
#endif
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* Callbacks
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
|
|
{
|
|
TRACE_INFO_WP("cfgChanged%d ", cfgnum);
|
|
simtrace_config = cfgnum;
|
|
}
|
|
|
|
void USART1_IrqHandler(void)
|
|
{
|
|
config_func_ptrs[simtrace_config].usart1_irq();
|
|
}
|
|
|
|
void USART0_IrqHandler(void)
|
|
{
|
|
config_func_ptrs[simtrace_config].usart0_irq();
|
|
}
|
|
|
|
#include "i2c.h"
|
|
|
|
static int write_hub_eeprom(void)
|
|
{
|
|
const unsigned char __eeprom_bin[] = {
|
|
0x23, 0x42, 0x17, 0x25, 0x00, 0x00, 0x9b, 0x20, 0x01, 0xa0, 0x00, 0x5e,
|
|
0x01, 0x32, 0x01, 0x32, 0x32, 0x04, 0x09, 0x18, 0x0d, 0x00, 0x73, 0x00,
|
|
0x79, 0x00, 0x73, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x6f, 0x00,
|
|
0x6d, 0x00, 0x20, 0x00, 0x2d, 0x00, 0x20, 0x00, 0x73, 0x00, 0x2e, 0x00,
|
|
0x66, 0x00, 0x2e, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x63, 0x00, 0x2e, 0x00,
|
|
0x20, 0x00, 0x47, 0x00, 0x6d, 0x00, 0x62, 0x00, 0x48, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x71, 0x00, 0x75, 0x00, 0x61, 0x00, 0x64, 0x00, 0x20, 0x00, 0x6d, 0x00,
|
|
0x6f, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x76, 0x00,
|
|
0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00,
|
|
0x00, 0x00, 0x00, 0x00
|
|
};
|
|
const unsigned int __eeprom_bin_len = 256;
|
|
|
|
const Pin pin_hubpwr_override = PIN_PRTPWR_OVERRIDE;
|
|
const Pin pin_hub_rst = {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT};
|
|
int i;
|
|
|
|
/* set PIN_PRTPWR_OVERRIDE to output-low to avoid the internal
|
|
* pull-up on the input to keep SIMTRACE12 alive */
|
|
PIO_Configure(&pin_hubpwr_override, 1);
|
|
|
|
PIO_Configure(&pin_hub_rst, 1);
|
|
i2c_pin_init();
|
|
|
|
/* wait */
|
|
volatile int v;
|
|
/* 440ns per cycle here */
|
|
for (i = 0; i < 1000000; i++) {
|
|
v = 0;
|
|
}
|
|
|
|
/* write the EEPROM once */
|
|
for (i = 0; i < 256; i++) {
|
|
int rc = eeprom_write_byte(0x50, i, __eeprom_bin[i]);
|
|
/* if the result was negative, repeat that write */
|
|
if (rc < 0)
|
|
i--;
|
|
}
|
|
|
|
/* then pursue re-reading it again and again */
|
|
for (i = 0; i < 256; i++) {
|
|
int byte = eeprom_read_byte(0x50, i);
|
|
TRACE_INFO("0x%02x: %02x\r\n", i, byte);
|
|
if (byte != __eeprom_bin[i])
|
|
TRACE_ERROR("Byte %u is wrong, expected 0x%02x, found 0x%02x\r\n",
|
|
i, __eeprom_bin[i], byte);
|
|
}
|
|
PIO_Clear(&pin_hub_rst);
|
|
|
|
/* FIXME: Release PIN_PRTPWR_OVERRIDE after we know the hub is
|
|
* again powering us up */
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*------------------------------------------------------------------------------
|
|
* Main
|
|
*------------------------------------------------------------------------------*/
|
|
#define MAX_USB_ITER BOARD_MCK/72 // This should be around a second
|
|
extern int main(void)
|
|
{
|
|
uint8_t isUsbConnected = 0;
|
|
enum confNum last_simtrace_config = simtrace_config;
|
|
unsigned int i = 0;
|
|
|
|
LED_Configure(LED_NUM_RED);
|
|
LED_Configure(LED_NUM_GREEN);
|
|
LED_Set(LED_NUM_RED);
|
|
|
|
/* Disable watchdog */
|
|
WDT_Disable(WDT);
|
|
|
|
req_ctx_init();
|
|
|
|
PIO_InitializeInterrupts(0);
|
|
|
|
SIMtrace_USB_Initialize();
|
|
|
|
EEFC_ReadUniqueID(g_unique_id);
|
|
|
|
printf("\r\n\r\n"
|
|
"=============================================================================\r\n"
|
|
"SIMtrace2 firmware " GIT_VERSION " (C) 2010-2016 by Harald Welte\r\n"
|
|
"=============================================================================\r\n");
|
|
|
|
TRACE_INFO("Serial Nr. %08x-%08x-%08x-%08x\r\n",
|
|
g_unique_id[0], g_unique_id[1],
|
|
g_unique_id[2], g_unique_id[3]);
|
|
|
|
write_hub_eeprom();
|
|
|
|
TRACE_INFO("USB init...\r\n");
|
|
while (USBD_GetState() < USBD_STATE_CONFIGURED) {
|
|
#if 0
|
|
if (i >= MAX_USB_ITER * 3) {
|
|
TRACE_ERROR("Resetting board (USB could "
|
|
"not be configured)\r\n");
|
|
NVIC_SystemReset();
|
|
}
|
|
#endif
|
|
i++;
|
|
}
|
|
|
|
TRACE_INFO("calling configure of all configurations...\r\n");
|
|
for (i = 1; i < sizeof(config_func_ptrs) / sizeof(config_func_ptrs[0]);
|
|
++i) {
|
|
if (config_func_ptrs[i].configure)
|
|
config_func_ptrs[i].configure();
|
|
}
|
|
|
|
TRACE_INFO("calling init of config %u...\r\n", simtrace_config);
|
|
config_func_ptrs[simtrace_config].init();
|
|
last_simtrace_config = simtrace_config;
|
|
|
|
TRACE_INFO("entering main loop...\r\n");
|
|
while (1) {
|
|
#if TRACE_LEVEL >= TRACE_LEVEL_DEBUG
|
|
const char rotor[] = { '-', '\\', '|', '/' };
|
|
putchar('\b');
|
|
putchar(rotor[i++ % ARRAY_SIZE(rotor)]);
|
|
#endif
|
|
|
|
if (USBD_GetState() < USBD_STATE_CONFIGURED) {
|
|
|
|
if (isUsbConnected) {
|
|
isUsbConnected = 0;
|
|
}
|
|
} else if (isUsbConnected == 0) {
|
|
TRACE_INFO("USB is now configured\r\n");
|
|
LED_Set(LED_NUM_GREEN);
|
|
LED_Clear(LED_NUM_RED);
|
|
|
|
isUsbConnected = 1;
|
|
}
|
|
if (last_simtrace_config != simtrace_config) {
|
|
TRACE_INFO("USB config chg %u -> %u\r\n",
|
|
last_simtrace_config, simtrace_config);
|
|
config_func_ptrs[last_simtrace_config].exit();
|
|
config_func_ptrs[simtrace_config].init();
|
|
last_simtrace_config = simtrace_config;
|
|
} else {
|
|
config_func_ptrs[simtrace_config].run();
|
|
}
|
|
}
|
|
}
|