From 4086f4cf46a8f508766eeaad03450a4d7845f194 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 22 Mar 2012 22:55:14 +0100 Subject: simtrace: implement SIM power switching API there is now a high-level command by which we can swithc the VCC supply of the SIM cards. For some reason, the _PASS variant (passing through the voltage from the phone) doesn't seem to work reliably. It might be that we are draining reverse current throught the LDO once we supply SIM power that way. --- firmware/src/simtrace/main_simtrace.c | 62 ++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 16 deletions(-) (limited to 'firmware/src/simtrace') diff --git a/firmware/src/simtrace/main_simtrace.c b/firmware/src/simtrace/main_simtrace.c index 733f060..0f2bfc5 100644 --- a/firmware/src/simtrace/main_simtrace.c +++ b/firmware/src/simtrace/main_simtrace.c @@ -52,6 +52,46 @@ enum simtrace_md { SIMTRACE_PIO_IO | \ SIMTRACE_PIO_IO_T) +enum simtrace_power_mode { + SIMTRACE_PWR_OFF, + SIMTRACE_PWR_PASS, + SIMTRACE_PWR_LDO +}; + +void simtrace_set_power(enum simtrace_power_mode mode) +{ + switch (mode) { + case SIMTRACE_PWR_PASS: + /* switch VCC_SIM pin into output mode, as in the first + * generation prototype we use it directly to supply Vcc + * to the SIM. Pin unused in v1.0(p) and v1.1p */ + AT91F_PIO_SetOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_VCC_SIM); + /* v1.0/1.1: pass-throguh power from the reader/phone (FPC) */ + AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_SIM_LDOEN); + AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_SIM_nPWRFWD); + break; + case SIMTRACE_PWR_LDO: + /* switch VCC_SIM pin into output mode, as in the first + * generation prototype we use it directly to supply Vcc + * to the SIM. Pin unused in v1.0(p) and v1.1p */ + AT91F_PIO_SetOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_VCC_SIM); + /* v1.0/1.1: power from the internal 3.3V LDO */ + AT91F_PIO_SetOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_SIM_nPWRFWD); + AT91F_PIO_SetOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_SIM_LDOEN); + break; + default: + case SIMTRACE_PWR_OFF: + /* switch VCC_SIM pin into output mode, as in the first + * generation prototype we use it directly to supply Vcc + * to the SIM. Pin unused in v1.0(p) and v1.1p */ + AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_VCC_SIM); + /* switch all power paths off */ + AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_SIM_LDOEN); + AT91F_PIO_SetOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_SIM_nPWRFWD); + break; + } +} + static void simtrace_set_mode(enum simtrace_md mode) { switch (mode) { @@ -62,22 +102,6 @@ static void simtrace_set_mode(enum simtrace_md mode) AT91F_PIO_CfgInput(AT91C_BASE_PIOA, UART1_PINS); AT91F_PIO_CfgPullupDis(AT91C_BASE_PIOA, UART1_PINS); - /* switch VCC_SIM pin into output mode, as in the first - * generation prototype we use it directly to supply Vcc - * to the SIM */ - - /* pin unused in v1.0(p) and v1.1p */ - AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_VCC_SIM); - AT91F_PIO_SetOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_VCC_SIM); - /* for v1.0(p) and v1.1p, VCC_SIM can either be powered by - * VCC_PHONE using SIM_PWRFWD, or by the LDO using - * SIM_PWREN. they should be set exclusive. per default - * use VCC_PHONE */ - AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_SIM_PWRFWD); - AT91F_PIO_SetOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_SIM_PWRFWD); - AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_SIM_PWREN); - AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_SIM_PWREN); - /* switch UART0 pins to 'ISO7816 card mode' */ AT91F_PIO_CfgInput(AT91C_BASE_PIOA, UART0_PINS); AT91F_PIO_CfgPullupDis(AT91C_BASE_PIOA, UART0_PINS); @@ -108,6 +132,12 @@ void _init_func(void) led_switch(1, 0); led_switch(2, 1); + AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_VCC_SIM); + AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_SIM_nPWRFWD); + AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, SIMTRACE_PIO_SIM_LDOEN); + /* default: use local LDO to supply power */ + simtrace_set_power(SIMTRACE_PWR_LDO); + iso_uart_rx_mode(); simtrace_set_mode(SIMTRACE_MD_SNIFFER); } -- cgit v1.2.3