diff --git a/TODO-RELEASE b/TODO-RELEASE index 5da461b6..fb357238 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -8,3 +8,4 @@ # If any interfaces have been removed or changed since the last public release: c:r:0. #library what description / commit summary line simtrace2 API/ABI change osmo_st2_transport new member +simtrace2 API/ABI change cardemu_usb_msg_config new member diff --git a/firmware/libcommon/include/simtrace.h b/firmware/libcommon/include/simtrace.h index a37ec4f3..aeb56ed8 100644 --- a/firmware/libcommon/include/simtrace.h +++ b/firmware/libcommon/include/simtrace.h @@ -124,4 +124,8 @@ extern void mode_cardemu_usart1_irq(void); void Timer_Init( void ); void TC0_Counter_Reset( void ); +/* Sim presence pins */ +bool mode_cardemu_get_prensence_pol(uint8_t instance); +void mode_cardemu_set_prensence_pol(uint8_t instance, bool high); + #endif /* SIMTRACE_H */ diff --git a/firmware/libcommon/include/simtrace_prot.h b/firmware/libcommon/include/simtrace_prot.h index d1eb89bb..d95eb008 100644 --- a/firmware/libcommon/include/simtrace_prot.h +++ b/firmware/libcommon/include/simtrace_prot.h @@ -261,12 +261,21 @@ struct cardemu_usb_msg_error { /* enable/disable the generation of DO_STATUS on IRQ endpoint */ #define CEMU_FEAT_F_STATUS_IRQ 0x00000001 +#define CEMU_CONFIG_PRES_POL_PRES_L 0x00 +#define CEMU_CONFIG_PRES_POL_PRES_H 0x01 +#define CEMU_CONFIG_PRES_POL_VALID 0x02 + /* SIMTRACE_MSGT_BD_CEMU_CONFIG */ struct cardemu_usb_msg_config { /* bit-mask of CEMU_FEAT_F flags */ uint32_t features; /* the selected slot number (if an external mux is present) */ uint8_t slot_mux_nr; + /* Sim presence pin polarity. Bit 1 is valid bit. Bit 0 gpio value when sim present. + * When sim is present, set sim_present gpio to high -> 0x03 + * When sim is present, set sim_present gpio to low -> 0x02 + */ + uint8_t pres_pol; } __attribute__ ((packed)); /*********************************************************************** diff --git a/firmware/libcommon/source/card_emu.c b/firmware/libcommon/source/card_emu.c index e6907e66..e040eea7 100644 --- a/firmware/libcommon/source/card_emu.c +++ b/firmware/libcommon/source/card_emu.c @@ -24,6 +24,7 @@ #include "trace.h" #include "iso7816_fidi.h" #include "card_emu.h" +#include "simtrace.h" #include "simtrace_prot.h" #include "usb_buf.h" #include @@ -1096,7 +1097,7 @@ static void card_emu_report_config(struct card_handle *ch) #else cfg->slot_mux_nr = 0; #endif - + cfg->pres_pol = mode_cardemu_get_prensence_pol(ch->num) | CEMU_CONFIG_PRES_POL_VALID; usb_buf_upd_len_and_submit(msg); } @@ -1270,6 +1271,11 @@ int card_emu_set_config(struct card_handle *ch, const struct cardemu_usb_msg_con } #endif + if (scfg_len >= sizeof(uint32_t)+sizeof(uint8_t)+sizeof(uint8_t)) { + if (scfg->pres_pol & CEMU_CONFIG_PRES_POL_VALID) + mode_cardemu_set_prensence_pol(ch->num, scfg->pres_pol & CEMU_CONFIG_PRES_POL_PRES_H); + } + /* send back a report of our current configuration */ card_emu_report_config(ch); diff --git a/firmware/libcommon/source/mode_cardemu.c b/firmware/libcommon/source/mode_cardemu.c index a05840e7..60c14ea4 100644 --- a/firmware/libcommon/source/mode_cardemu.c +++ b/firmware/libcommon/source/mode_cardemu.c @@ -79,7 +79,10 @@ struct cardem_inst { uint8_t ep_out; uint8_t ep_in; uint8_t ep_int; + /*! Pin to set when SIM is present/inserted (SIM presence pin). */ const Pin pin_insert; + /*! Invert the Pin polarity. When not inverted, the SIM pin_insert will be High, when a SIM is present. */ + bool pin_insert_inverted; #ifdef DETECT_VCC_BY_ADC uint32_t vcc_uv; #endif @@ -113,7 +116,10 @@ struct cardem_inst cardem_inst[] = { .ep_int = SIMTRACE_CARDEM_USB_EP_USIM1_INT, #ifdef PIN_SET_USIM1_PRES .pin_insert = PIN_SET_USIM1_PRES, -#endif +#endif /* PIN_SET_USIM1_PRES */ +#ifdef PIN_SET_USIM1_PRES_INVERTED + .pin_insert_inverted = true, +#endif /* PIN_SET_USIM1_PRES_INVERTED */ }, #ifdef CARDEMU_SECOND_UART { @@ -128,7 +134,10 @@ struct cardem_inst cardem_inst[] = { .ep_int = SIMTRACE_CARDEM_USB_EP_USIM2_INT, #ifdef PIN_SET_USIM2_PRES .pin_insert = PIN_SET_USIM2_PRES, -#endif +#endif /* PIN_SET_USIM2_PRES */ +#ifdef PIN_SET_USIM2_PRES_INVERTED + .pin_insert_inverted = true, +#endif /* PIN_SET_USIM2_PRES_INVERTED */ }, #endif }; @@ -700,7 +709,7 @@ static void process_card_insert(struct cardem_inst *ci, bool card_insert) TRACE_INFO("%u: set card_insert to %s\r\n", ci->num, card_insert ? "INSERTED" : "REMOVED"); #ifdef HAVE_BOARD_CARDINSERT - board_set_card_insert(ci, card_insert); + board_set_card_insert(ci, card_insert ^ ci->pin_insert_inverted); #else if (!ci->pin_insert.pio) { TRACE_INFO("%u: skipping unsupported card_insert to %s\r\n", @@ -708,7 +717,7 @@ static void process_card_insert(struct cardem_inst *ci, bool card_insert) return; } - if (card_insert) + if (card_insert ^ ci->pin_insert_inverted) PIO_Set(&ci->pin_insert); else PIO_Clear(&ci->pin_insert); @@ -962,3 +971,25 @@ void mode_cardemu_run(void) process_any_usb_commands(queue, ci); } } + +void mode_cardemu_set_prensence_pol(uint8_t instance, bool high) +{ + struct cardem_inst *ci; + + if (instance >= ARRAY_SIZE(cardem_inst)) + return; + + ci = &cardem_inst[instance]; + ci->pin_insert_inverted = !high; +} + +bool mode_cardemu_get_prensence_pol(uint8_t instance) +{ + struct cardem_inst *ci; + + if (instance >= ARRAY_SIZE(cardem_inst)) + return false; + + ci = &cardem_inst[instance]; + return !ci->pin_insert_inverted; +}