1 #include "../globals.h"
4 #include "../oscam-time.h"
6 #include "ifd_phoenix.h"
13 #define MP35_WRITE_DELAY 100000
14 #define MP35_READ_DELAY 200000
15 #define MP35_BREAK_LENGTH 1200000
19 unsigned char current_product
;
20 uint16_t product_fw_version
;
23 // Common command for AD-Teknik readers
24 static const unsigned char fw_version
[] = {0x2a, 0x41};
26 // Commands for AD-Teknik MP3.5 and MP3.6
27 //static const unsigned char power_always_on[] = {0x2a, 0x8a};
28 //static const unsigned char set_vpp[] = {0x2a, 0x42};
29 //static const unsigned char set_data[] = {0x2a, 0x43};
30 //static const unsigned char set_oscillator[] = {0x2a, 0x5e};
31 //static const unsigned char terminate_com[] = {0x2a, 0x7b};
32 //static const unsigned char transthrough_mode[] = {0x2a, 0x7c};
33 static const unsigned char phoenix_mode
[] = {0x2a, 0x7d};
34 //static const unsigned char smartmouse_mode[] = {0x2a, 0x7e};
35 static const unsigned char phoenix_6mhz_mode
[] = {0x2a, 0x9a};
36 //static const unsigned char smartmouse_6mhz_mode[] = {0x2a, 0x9b};
37 static const unsigned char fw_info
[] = {0x2a, 0xa2};
39 // Commands for AD-Teknik USB Phoenix
40 static const unsigned char set_mode_osc
[] = {0x2a, 0x42};
41 static const unsigned char exit_program_mode
[] = {0x2a, 0x43};
43 static const struct product
46 const char *product_name
;
49 {0x10, "USB Phoenix"},
55 static int32_t mp35_product_info(struct s_reader
*reader
, unsigned char high
, unsigned char low
, unsigned char code
, MP35_info
*info
)
59 for(i
= 0; i
< (int)(sizeof(product_codes
) / sizeof(struct product
)); i
++)
61 if(product_codes
[i
].code
== code
)
63 rdr_log(reader
, "%s: %s - FW:%02d.%02d", __func__
, product_codes
[i
].product_name
, high
, low
);
64 info
->current_product
= code
;
65 info
->product_fw_version
= (high
<< 8) | low
;
73 static int32_t mp35_reader_init(struct s_reader
*reader
)
75 MP35_info reader_info
;
76 unsigned char rec_buf
[32];
77 unsigned char parameter
;
79 int32_t original_cardmhz
;
81 rdr_log(reader
, "%s: started", __func__
);
83 original_mhz
= reader
->mhz
;
84 original_cardmhz
= reader
->cardmhz
;
86 // MP3.5 commands should be always be written using 9600 baud at 3.57MHz
88 reader
->cardmhz
= 357;
90 int32_t dtr
= IO_SERIAL_HIGH
;
91 int32_t cts
= IO_SERIAL_HIGH
;
93 call(IO_Serial_SetParams(reader
, 9600, 8, PARITY_NONE
, 1, &dtr
, &cts
));
95 IO_Serial_Sendbreak(reader
, MP35_BREAK_LENGTH
);
96 IO_Serial_DTR_Clr(reader
);
97 IO_Serial_DTR_Set(reader
);
99 IO_Serial_RTS_Set(reader
);
100 IO_Serial_Flush(reader
);
102 memset(rec_buf
, 0x00, sizeof(rec_buf
));
103 call(IO_Serial_Write(reader
, MP35_WRITE_DELAY
, 1000000, 2, fw_version
));
104 call(IO_Serial_Read(reader
, MP35_READ_DELAY
, 1000000, 4, rec_buf
));
105 if(rec_buf
[3] != ACK
)
107 rdr_log_dbg(reader
, D_IFD
, "Failed MP35 command: fw_version");
111 if(mp35_product_info(reader
, rec_buf
[1], rec_buf
[0], rec_buf
[2], &reader_info
) != OK
)
113 rdr_log(reader
, "%s: unknown product code", __func__
);
117 if(reader_info
.current_product
== 0x10) // USB Phoenix
119 if(original_mhz
== 357)
121 rdr_log(reader
, "%s: Using oscillator 1 (3.57MHz)", __func__
);
124 else if(original_mhz
== 368)
126 rdr_log(reader
, "%s: Using oscillator 2 (3.68MHz)", __func__
);
129 else if(original_mhz
== 600)
131 rdr_log(reader
, "%s: Using oscillator 3 (6.00MHz)", __func__
);
136 rdr_log(reader
, "%s: MP35 support only mhz=357, mhz=368 or mhz=600", __func__
);
137 rdr_log(reader
, "%s: Forced oscillator 1 (3.57MHz)", __func__
);
141 memset(rec_buf
, 0x00, sizeof(rec_buf
));
142 call(IO_Serial_Write(reader
, MP35_WRITE_DELAY
, 1000000, 2, set_mode_osc
));
143 call(IO_Serial_Write(reader
, MP35_WRITE_DELAY
, 1000000, 1, ¶meter
));
144 call(IO_Serial_Read(reader
, MP35_READ_DELAY
, 1000000, 1, rec_buf
)); // Read ACK from previous command
145 if(rec_buf
[0] != ACK
)
147 rdr_log_dbg(reader
, D_IFD
, "Failed MP35 command: set_mode_osc");
150 rdr_log_dbg(reader
, D_IFD
, "%s: Leaving programming mode", __func__
);
151 memset(rec_buf
, 0x00, sizeof(rec_buf
));
152 call(IO_Serial_Write(reader
, MP35_WRITE_DELAY
, 1000000, 2, exit_program_mode
));
153 call(IO_Serial_Read(reader
, MP35_READ_DELAY
, 1000000, 1, rec_buf
));
154 if(rec_buf
[0] != ACK
)
156 rdr_log_dbg(reader
, D_IFD
, "Failed MP35 command: exit_program_mode");
160 else //MP3.5 or MP3.6
162 if(reader_info
.product_fw_version
>= 0x0500)
165 char info
[sizeof(rec_buf
) - 2];
167 memset(rec_buf
, 0x00, sizeof(rec_buf
));
168 call(IO_Serial_Write(reader
, MP35_WRITE_DELAY
, 1000000, 2, fw_info
));
169 call(IO_Serial_Read(reader
, MP35_READ_DELAY
, 1000000, 1, rec_buf
));
170 info_len
= rec_buf
[0];
171 call(IO_Serial_Read(reader
, MP35_READ_DELAY
, 1000000, info_len
+ 1, rec_buf
));
172 if(rec_buf
[info_len
] != ACK
)
174 rdr_log_dbg(reader
, D_IFD
, "Failed MP35 command: fw_info");
177 memcpy(info
, rec_buf
, info_len
);
178 info
[info_len
] = '\0';
179 rdr_log(reader
, "%s: FW Info - %s", __func__
, info
);
182 memset(rec_buf
, 0x00, sizeof(rec_buf
));
183 if(original_mhz
== 357)
185 rdr_log(reader
, "%s: Using oscillator 1 (3.57MHz)", __func__
);
186 call(IO_Serial_Write(reader
, MP35_WRITE_DELAY
, 1000000, 2, phoenix_mode
));
188 else if(original_mhz
== 600)
190 rdr_log(reader
, "%s: Using oscillator 2 (6.00MHz)", __func__
);
191 call(IO_Serial_Write(reader
, MP35_WRITE_DELAY
, 1000000, 2, phoenix_6mhz_mode
));
195 rdr_log(reader
, "%s: MP35 support only mhz=357 or mhz=600", __func__
);
196 rdr_log(reader
, "%s: Forced oscillator 1 (3.57MHz)", __func__
);
197 call(IO_Serial_Write(reader
, MP35_WRITE_DELAY
, 1000000, 2, phoenix_mode
));
200 tcdrain(reader
->handle
);
203 // We might have switched oscillator here
204 reader
->mhz
= original_mhz
;
205 reader
->cardmhz
= original_cardmhz
;
207 /* Default serial port settings */
208 if(reader
->atr
[0] == 0)
210 IO_Serial_Flush(reader
);
211 call(IO_Serial_SetParams(reader
, DEFAULT_BAUDRATE
, 8, PARITY_EVEN
, 2, NULL
, NULL
));
217 static int32_t mp35_close(struct s_reader
*reader
)
219 rdr_log_dbg(reader
, D_IFD
, "Closing MP35 device %s", reader
->device
);
221 IO_Serial_DTR_Clr(reader
);
222 IO_Serial_Close(reader
);
227 static int32_t mp35_init(struct s_reader
*reader
)
229 reader
->handle
= open(reader
->device
, O_RDWR
| O_NOCTTY
| O_NONBLOCK
);
230 if(reader
->handle
< 0)
232 rdr_log(reader
, "ERROR: Opening device %s (errno=%d %s)",
233 reader
->device
, errno
, strerror(errno
));
236 if(IO_Serial_SetParams(reader
, DEFAULT_BAUDRATE
, 8, PARITY_EVEN
, 2, NULL
, NULL
))
239 if(mp35_reader_init(reader
))
241 rdr_log(reader
, "ERROR: mp35_reader_init returned error");
248 const struct s_cardreader cardreader_mp35
=
255 .reader_init
= mp35_init
,
256 .get_status
= IO_Serial_GetStatus
,
257 .activate
= Phoenix_Reset
,
258 .transmit
= IO_Serial_Transmit
,
259 .receive
= IO_Serial_Receive
,
261 .set_parity
= IO_Serial_SetParity
,
262 .set_baudrate
= IO_Serial_SetBaudrate
,