aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2012-03-22 22:55:14 +0100
committerHarald Welte <laforge@gnumonks.org>2012-03-22 22:55:14 +0100
commit4086f4cf46a8f508766eeaad03450a4d7845f194 (patch)
tree413120574a2caa577b3433d6f02814ba7906ba0d
parent559fc6858377def4705fdcb15bf8cb8a72a54f92 (diff)
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.
-rw-r--r--firmware/src/simtrace.h4
-rw-r--r--firmware/src/simtrace/main_simtrace.c62
2 files changed, 48 insertions, 18 deletions
diff --git a/firmware/src/simtrace.h b/firmware/src/simtrace.h
index b6d44c4..f3ddf23 100644
--- a/firmware/src/simtrace.h
+++ b/firmware/src/simtrace.h
@@ -36,8 +36,8 @@
#define SIMTRACE_PIO_VCC_SIM AT91C_PIO_PA5
/* to set power source for VCC_SIM for v1.0(p) */
-#define SIMTRACE_PIO_SIM_PWREN AT91C_PIO_PA5
-#define SIMTRACE_PIO_SIM_PWRFWD AT91C_PIO_PA26
+#define SIMTRACE_PIO_SIM_LDOEN AT91C_PIO_PA5
+#define SIMTRACE_PIO_SIM_nPWRFWD AT91C_PIO_PA26
/* VCC_PHONE detection */
#define SIMTRACE_PIO_VCC_PHONE AT91C_PIO_PA25
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);
}