3 This module provides IFD handling functions for Smartmouse/Phoenix reader.
6 #include "../globals.h"
8 #ifdef CARDREADER_PHOENIX
9 #include "../oscam-time.h"
10 #include "icc_async.h"
11 #include "ifd_db2com.h"
12 #include "ifd_phoenix.h"
13 #include "io_serial.h"
18 #define GPIO_PIN (1 << (reader->detect - 4))
20 static inline int reader_use_gpio(struct s_reader
*reader
)
22 return reader
->use_gpio
&& reader
->detect
> 4;
25 static void set_gpio(struct s_reader
*reader
, int32_t level
)
29 ret
|= read(reader
->gpio_outen
, &reader
->gpio
, sizeof(reader
->gpio
));
30 reader
->gpio
|= GPIO_PIN
;
31 ret
|= write(reader
->gpio_outen
, &reader
->gpio
, sizeof(reader
->gpio
));
33 ret
|= read(reader
->gpio_out
, &reader
->gpio
, sizeof(reader
->gpio
));
35 { reader
->gpio
|= GPIO_PIN
; }
37 { reader
->gpio
&= ~GPIO_PIN
; }
38 ret
|= write(reader
->gpio_out
, &reader
->gpio
, sizeof(reader
->gpio
));
40 rdr_log_dbg(reader
, D_IFD
, "%s level: %d ret: %d", __func__
, level
, ret
);
43 static void set_gpio_input(struct s_reader
*reader
)
46 ret
|= read(reader
->gpio_outen
, &reader
->gpio
, sizeof(reader
->gpio
));
47 reader
->gpio
&= ~GPIO_PIN
;
48 ret
|= write(reader
->gpio_outen
, &reader
->gpio
, sizeof(reader
->gpio
));
49 rdr_log_dbg(reader
, D_IFD
, "%s ret:%d", __func__
, ret
);
52 static int32_t get_gpio(struct s_reader
*reader
)
55 set_gpio_input(reader
);
56 ret
= read(reader
->gpio_in
, &reader
->gpio
, sizeof(reader
->gpio
));
57 rdr_log_dbg(reader
, D_IFD
, "%s ok:%d ret:%d", __func__
, reader
->gpio
& GPIO_PIN
, ret
);
58 if(reader
->gpio
& GPIO_PIN
)
64 int32_t Phoenix_Init(struct s_reader
*reader
)
66 // First set card in reset state, to not change any parameters while communication ongoing
67 IO_Serial_RTS_Set(reader
);
69 const struct s_cardreader
*crdr_ops
= reader
->crdr
;
70 if (!crdr_ops
) return ERROR
;
72 if(crdr_ops
->flush
) { IO_Serial_Flush(reader
); }
74 // define reader->gpio number used for card detect and reset. ref to globals.h
75 if(reader_use_gpio(reader
))
77 reader
->gpio_outen
= open("/dev/gpio/outen", O_RDWR
);
78 reader
->gpio_out
= open("/dev/gpio/out", O_RDWR
);
79 reader
->gpio_in
= open("/dev/gpio/in", O_RDWR
);
80 rdr_log_dbg(reader
, D_IFD
, "init gpio_outen:%d gpio_out:%d gpio_in:%d",
81 reader
->gpio_outen
, reader
->gpio_out
, reader
->gpio_in
);
82 set_gpio_input(reader
);
85 rdr_log_dbg(reader
, D_IFD
, "Initializing reader type=%d", reader
->typ
);
87 /* Default serial port settings */
88 if(reader
->atr
[0] == 0)
90 if(IO_Serial_SetParams(reader
, DEFAULT_BAUDRATE
, 8, PARITY_EVEN
, 2, NULL
, NULL
)) { return ERROR
; }
91 if(crdr_ops
->flush
) { IO_Serial_Flush(reader
); }
96 int32_t Phoenix_GetStatus(struct s_reader
*reader
, int32_t *status
)
98 // detect card via defined reader->gpio
99 if(reader_use_gpio(reader
))
101 *status
= !get_gpio(reader
);
106 return IO_Serial_GetStatus(reader
, status
);
110 int32_t Phoenix_Reset(struct s_reader
*reader
, ATR
*atr
)
112 rdr_log_dbg(reader
, D_IFD
, "Resetting card");
115 unsigned char buf
[ATR_MAX_SIZE
];
116 int32_t parity
[3] = {PARITY_EVEN
, PARITY_ODD
, PARITY_NONE
};
118 call(IO_Serial_SetBaudrate(reader
, DEFAULT_BAUDRATE
));
120 const struct s_cardreader
*crdr_ops
= reader
->crdr
;
121 if (!crdr_ops
) return ERROR
;
123 for(i
= 0; i
< 3; i
++)
125 if(crdr_ops
->flush
) { IO_Serial_Flush(reader
); }
126 if(crdr_ops
->set_parity
) { IO_Serial_SetParity(reader
, parity
[i
]); }
130 IO_Serial_Ioctl_Lock(reader
, 1);
131 if(reader_use_gpio(reader
))
132 { set_gpio(reader
, 0); }
134 { IO_Serial_RTS_Set(reader
); }
138 // felix: set card reset hi (inactive)
139 if(reader_use_gpio(reader
))
140 { set_gpio_input(reader
); }
142 { IO_Serial_RTS_Clr(reader
); }
144 IO_Serial_Ioctl_Lock(reader
, 0);
147 while(n
< ATR_MAX_SIZE
&& !IO_Serial_Read(reader
, 0, ATR_TIMEOUT
, 1, buf
+ n
))
151 if(ATR_InitFromArray(atr
, buf
, n
) != ERROR
)
153 // Successfully retrieve ATR
161 int32_t Phoenix_Close(struct s_reader
*reader
)
163 rdr_log_dbg(reader
, D_IFD
, "Closing phoenix device %s", reader
->device
);
164 if(reader_use_gpio(reader
))
166 if(reader
->gpio_outen
> -1)
167 { close(reader
->gpio_outen
); }
168 if(reader
->gpio_out
> -1)
169 { close(reader
->gpio_out
); }
170 if(reader
->gpio_in
> -1)
171 { close(reader
->gpio_in
); }
173 IO_Serial_Close(reader
);
178 int32_t Phoenix_FastReset (struct s_reader * reader, int32_t delay)
180 IO_Serial_Ioctl_Lock(reader, 1);
181 if (reader_use_gpio(reader))
184 IO_Serial_RTS_Set(reader);
188 // set card reset hi (inactive)
189 if (reader_use_gpio(reader))
190 set_gpio_input(reader);
192 IO_Serial_RTS_Clr(reader);
194 IO_Serial_Ioctl_Lock(reader, 0);
198 IO_Serial_Flush(reader);
203 static int32_t mouse_init(struct s_reader
*reader
)
205 const struct s_cardreader
*crdr_ops
= reader
->crdr
;
206 if (!crdr_ops
) return ERROR
;
208 if(detect_db2com_reader(reader
))
210 reader
->crdr
= crdr_ops
= &cardreader_db2com
;
211 return crdr_ops
->reader_init(reader
);
214 reader
->handle
= open(reader
->device
, O_RDWR
| O_NOCTTY
| O_NONBLOCK
);
215 if(reader
->handle
< 0)
217 rdr_log(reader
, "ERROR: Opening device %s (errno=%d %s)",
218 reader
->device
, errno
, strerror(errno
));
221 if(Phoenix_Init(reader
))
223 rdr_log(reader
, "ERROR: Phoenix_Init returns error");
224 Phoenix_Close(reader
);
230 const struct s_cardreader cardreader_mouse
=
237 .reader_init
= mouse_init
,
238 .get_status
= Phoenix_GetStatus
,
239 .activate
= Phoenix_Reset
,
240 .transmit
= IO_Serial_Transmit
,
241 .receive
= IO_Serial_Receive
,
242 .close
= Phoenix_Close
,
243 .set_parity
= IO_Serial_SetParity
,
244 .set_baudrate
= IO_Serial_SetBaudrate
,