blob: 2bcecc66dea70a1add276bee76b194f86d46e0b3 [file] [log] [blame]
Harald Welte2a6d3af2016-02-28 19:29:14 +01001#include "board.h"
2#include "card_emu.h"
Harald Weltebd717682016-02-28 19:30:05 +01003#include "iso7816_fidi.h"
4
5#define TRACE_ENTRY() TRACE_DEBUG("%s entering\n", __func__)
Harald Welte2a6d3af2016-02-28 19:29:14 +01006
7static const Pin pins_cardsim[] = PINS_CARDSIM;
8
9/* UART pins */
10static const Pin pins_usim1[] = {PINS_USIM1};
11static const Pin pin_usim1_rst = PIN_USIM1_nRST;
12static const Pin pin_usim1_vcc = PIN_USIM1_VCC;
13
14#ifdef CARDEMU_SECOND_UART
15static const Pin pins_usim2[] = {PINS_USIM1};
16static const Pin pin_usim2_rst = PIN_USIM2_nRST;
17static const Pin pin_usim2_vcc = PIN_USIM2_VCC;
18#endif
19
20static struct card_handle *ch1, *ch2;
21
22static struct Usart_info usart_info[] = {
23 {
24 .base = USART1,
25 .id = ID_USART1,
26 .state = USART_RCV
27 },
28#ifdef CARDEMU_SECOND_UART
29 {
30 .base = USART0,
31 .id = ID_USART0,
32 .state = USART_RCV
33 },
34#endif
35};
36
37static Usart *get_usart_by_chan(uint8_t uart_chan)
38{
39 switch (uart_chan) {
40 case 0:
41 return USART1;
42#ifdef CARDEMU_SECOND_UART
43 case 1:
44 return USART0;
45#endif
46 }
47 return NULL;
48}
49
50/***********************************************************************
51 * Call-Backs from card_emu.c
52 ***********************************************************************/
53
54/* call-back from card_emu.c to enable/disable transmit and/or receive */
55void card_emu_uart_enable(uint8_t uart_chan, uint8_t rxtx)
56{
57 Usart *usart = get_usart_by_chan(uart_chan);
58 switch (rxtx) {
59 case ENABLE_TX:
Harald Welte9dbc46e2016-02-29 10:05:10 +010060 USART_EnableIt(usart, US_IER_TXRDY);
61 USART_DisableIt(usart, ~US_IER_TXRDY);
Harald Welte2a6d3af2016-02-28 19:29:14 +010062 USART_SetReceiverEnabled(usart, 0);
63 USART_SetTransmitterEnabled(usart, 1);
64 break;
65 case ENABLE_RX:
66 USART_SetTransmitterEnabled(usart, 0);
67 USART_SetReceiverEnabled(usart, 1);
Harald Welte9dbc46e2016-02-29 10:05:10 +010068 USART_EnableIt(usart, US_IER_RXRDY);
69 USART_DisableIt(usart, ~US_IER_RXRDY);
Harald Welte2a6d3af2016-02-28 19:29:14 +010070 break;
71 case 0:
72 default:
73 USART_SetTransmitterEnabled(usart, 0);
74 USART_SetReceiverEnabled(usart, 0);
Harald Welte9dbc46e2016-02-29 10:05:10 +010075 USART_DisableIt(usart, 0xFFFFFFFF);
Harald Welte2a6d3af2016-02-28 19:29:14 +010076 break;
77 }
78}
79
80/* call-back from card_emu.c to transmit a byte */
81int card_emu_uart_tx(uint8_t uart_chan, uint8_t byte)
82{
83 Usart_info *ui = &usart_info[uart_chan];
84 ISO7816_SendChar(byte, ui);
85 return 1;
86}
87
88
89/* FIXME: integrate this with actual irq handler */
90void usart_irq_rx(uint8_t uart, uint32_t csr, uint8_t byte)
91{
92 struct card_handle *ch = ch1;
93#ifdef CARDEMU_SECOND_UART
94 if (uart == 0)
95 ch = ch2;
96#endif
97
98 if (csr & US_CSR_TXRDY)
99 card_emu_tx_byte(ch);
100
101 if (csr & US_CSR_RXRDY)
102 card_emu_process_rx_byte(ch, byte);
103
104 if (csr & (US_CSR_OVRE|US_CSR_FRAME|US_CSR_PARE|
105 US_CSR_TIMEOUT|US_CSR_NACK|(1<<10))) {
106 TRACE_DEBUG("e 0x%x st: 0x%x\n", byte, csr);
107 }
108}
109
Harald Weltebd717682016-02-28 19:30:05 +0100110/* call-back from card_emu.c to change UART baud rate */
111int card_emu_uart_update_fidi(uint8_t uart_chan, unsigned int fidi)
112{
113 int rc;
Harald Weltebd717682016-02-28 19:30:05 +0100114 Usart *usart = get_usart_by_chan(uart_chan);
115
Harald Welte99f62a62016-02-29 10:08:49 +0100116 usart->US_CR |= US_CR_RXDIS | US_CR_RSTRX;
117 usart->US_FIDI = fidi & 0x3ff;
118 usart->US_CR |= US_CR_RXEN | US_CR_STTTO;
119 return 0;
Harald Weltebd717682016-02-28 19:30:05 +0100120}
Harald Welte2a6d3af2016-02-28 19:29:14 +0100121
122/***********************************************************************
123 * Core USB / mainloop integration
124 ***********************************************************************/
125
126/* executed once at system boot for each config */
127void mode_cardemu_configure(void)
128{
Harald Weltebd717682016-02-28 19:30:05 +0100129 TRACE_ENTRY();
Harald Welte2a6d3af2016-02-28 19:29:14 +0100130}
131
132/* called if config is activated */
133void mode_cardemu_init(void)
134{
Harald Weltebd717682016-02-28 19:30:05 +0100135 TRACE_ENTRY();
136
Harald Welte2a6d3af2016-02-28 19:29:14 +0100137 PIO_Configure(pins_cardsim, PIO_LISTSIZE(pins_cardsim));
138
139 PIO_Configure(pins_usim1, PIO_LISTSIZE(pins_usim1));
140 ISO7816_Init(&usart_info[0], CLK_SLAVE);
Harald Welte9dbc46e2016-02-29 10:05:10 +0100141 //USART_EnableIt(USART1, US_IER_RXRDY);
Harald Welte2a6d3af2016-02-28 19:29:14 +0100142 NVIC_EnableIRQ(USART1_IRQn);
143 ch1 = card_emu_init(0, 2, 0);
144
145#ifdef CARDEMU_SECOND_UART
146 PIO_Configure(pins_usim2, PIO_LISTSIZE(pins_usim2));
147 ISO7816_Init(&usart_info[1], CLK_SLAVE);
Harald Welte9dbc46e2016-02-29 10:05:10 +0100148 //USART_EnableIt(USART0, US_IER_RXRDY);
Harald Welte2a6d3af2016-02-28 19:29:14 +0100149 NVIC_EnableIRQ(USART0_IRQn);
150 ch2 = card_emu_init(1, 0, 1);
151#endif
152}
153
154/* called if config is deactivated */
155void mode_cardemu_exit(void)
156{
Harald Weltebd717682016-02-28 19:30:05 +0100157 TRACE_ENTRY();
158
Harald Welte2a6d3af2016-02-28 19:29:14 +0100159 NVIC_DisableIRQ(USART1_IRQn);
160 USART_SetTransmitterEnabled(USART1, 0);
161 USART_SetReceiverEnabled(USART1, 0);
162
163#ifdef CARDEMU_SECOND_UART
164 NVIC_DisableIRQ(USART0_IRQn);
165 USART_SetTransmitterEnabled(USART0, 0);
166 USART_SetReceiverEnabled(USART0, 0);
167#endif
168}
169
170/* main loop function, called repeatedly */
171void mode_cardemu_run(void)
172{
173 int rst_active, vcc_active;
174
175 /* usb_to_host() is handled by main() */
176
177 if (ch1) {
178 rst_active = PIO_Get(&pin_usim1_rst) ? 0 : 1;
179 vcc_active = PIO_Get(&pin_usim1_vcc) ? 1 : 0;
180 card_emu_io_statechg(ch1, CARD_IO_RST, rst_active);
181 card_emu_io_statechg(ch1, CARD_IO_VCC, vcc_active);
182 /* FIXME: clock ? */
183 }
184 usb_from_host(PHONE_DATAOUT);
185
186#ifdef CARDEMU_SECOND_UART
187 if (ch2) {
188 rst_active = PIO_Get(&pin_usim2_rst) ? 0 : 1;
189 vcc_active = PIO_Get(&pin_usim2_vcc) ? 1 : 0;
190 card_emu_io_statechg(ch2, CARD_IO_RST, rst_active);
191 card_emu_io_statechg(ch2, CARD_IO_VCC, vcc_active);
192 /* FIXME: clock ? */
193 }
194 usb_from_host(FIXME);
195#endif
196}