source: trunk/csctapi/ifd_mp35.c@ 3181

Last change on this file since 3181 was 3181, checked in by dingo35, 10 years ago

Adding threadsafety FIXMEs, feel free to join checking..

File size: 5.8 KB
Line 
1//FIXME Not checked on threadsafety yet; after checking please remove this line
2#include "../globals.h"
3#include "icc_async.h"
4#include "io_serial.h"
5#include <termios.h>
6
7#define ACK 0x06
8
9// Common command for AD-Teknik readers
10static const BYTE fw_version[] = {0x2a, 0x41};
11
12// Commands for AD-Teknik MP3.5 and MP3.6
13static const BYTE power_always_on[] = {0x2a, 0x8a};
14static const BYTE set_vpp[] = {0x2a, 0x42};
15static const BYTE set_data[] = {0x2a, 0x43};
16static const BYTE set_oscillator[] = {0x2a, 0x5e};
17static const BYTE terminate_com[] = {0x2a, 0x7b};
18static const BYTE transthrough_mode[] = {0x2a, 0x7c};
19static const BYTE phoenix_mode[] = {0x2a, 0x7d};
20static const BYTE smartmouse_mode[] = {0x2a, 0x7e};
21static const BYTE phoenix_6mhz_mode[] = {0x2a, 0x9a};
22static const BYTE smartmouse_6mhz_mode[] = {0x2a, 0x9b};
23static const BYTE fw_info[] = {0x2a, 0xa2};
24
25// Commands for AD-Teknik USB Phoenix
26static const BYTE set_mode_osc[] = {0x2a, 0x42};
27static const BYTE exit_program_mode[] = {0x2a, 0x43};
28
29static const struct product { BYTE code; const char* product_name; } product_codes[] = {
30 {0x10, "USB Phoenix"},
31 {0x40, "MP3.4"},
32 {0x41, "MP3.5"},
33 {0x42, "MP3.6 USB"}};
34
35static BYTE current_product;
36static ushort product_fw_version;
37static int MP35_product_info(BYTE high, BYTE low, BYTE code)
38{
39 int i;
40
41 for(i = 0; i < (int)(sizeof(product_codes) / sizeof(struct product)); i++)
42 {
43 if(product_codes[i].code == code)
44 {
45 cs_log("MP35_Init: %s - FW:%02d.%02d", product_codes[i].product_name, high, low);
46 current_product = code;
47 product_fw_version = (high << 8) | low;
48 return OK;
49 }
50 }
51
52 return ERROR;
53}
54
55int MP35_Init(struct s_reader * reader)
56{
57 BYTE rec_buf[32];
58 BYTE parameter;
59 int original_mhz;
60
61 cs_debug_mask (D_IFD, "IFD: Initializing MP35 reader %s", reader->label);
62
63 current_product = 0;
64 original_mhz = reader->mhz; // MP3.5 commands should be always be written using 9600 baud at 3.58MHz
65 reader->mhz = 357;
66
67 call(IO_Serial_SetParams(reader, 9600, 8, PARITY_NONE, 1, IO_SERIAL_HIGH, IO_SERIAL_HIGH));
68
69 IO_Serial_Sendbreak(reader, 1500);
70 IO_Serial_DTR_Clr(reader);
71 IO_Serial_DTR_Set(reader);
72 cs_sleepms(500);
73 IO_Serial_Flush(reader);
74
75 memset(rec_buf, 0x00, sizeof(rec_buf));
76 call(IO_Serial_Write(reader, 0, 2, fw_version));
77 call(IO_Serial_Read(reader, 200, 4, rec_buf));
78 if(rec_buf[3] != ACK)
79 {
80 cs_debug_mask (D_IFD, "IFD: Failed MP35 command: fw_version");
81 return ERROR;
82 }
83
84 if(MP35_product_info(rec_buf[1], rec_buf[0], rec_buf[2]) != OK)
85 {
86 cs_log("MP35_Init: unknown product code");
87 return ERROR;
88 }
89
90 if(current_product == 0x10) // USB Phoenix
91 {
92 if(original_mhz == 357)
93 {
94 cs_log("MP35_Init: Using oscillator 1 (3.57MHz)");
95 parameter = 0x01;
96 }
97 else if(original_mhz == 368)
98 {
99 cs_log("MP35_Init: Using oscillator 2 (3.68MHz)");
100 parameter = 0x02;
101 }
102 else if(original_mhz == 600)
103 {
104 cs_log("MP35_Init: Using oscillator 3 (6.00MHz)");
105 parameter = 0x03;
106 }
107 else
108 {
109 cs_log("MP35_Init: MP35 support only mhz=357, mhz=368 or mhz=600");
110 cs_log("MP35_Init: Forced oscillator 1 (3.57MHz)");
111 parameter = 0x01;
112 original_mhz = 357;
113 }
114 memset(rec_buf, 0x00, sizeof(rec_buf));
115 call(IO_Serial_Write(reader, 0, 2, set_mode_osc));
116 call(IO_Serial_Write(reader, 0, 1, &parameter));
117 call(IO_Serial_Read(reader, 200, 1, rec_buf)); // Read ACK from previous command
118 if(rec_buf[0] != ACK)
119 {
120 cs_debug_mask (D_IFD, "IFD: Failed MP35 command: set_mode_osc");
121 return ERROR;
122 }
123 cs_log("MP35_Init: Leaving programming mode");
124 memset(rec_buf, 0x00, sizeof(rec_buf));
125 call(IO_Serial_Write(reader, 0, 2, exit_program_mode));
126 call(IO_Serial_Read(reader, 200, 1, rec_buf));
127 if(rec_buf[0] != ACK)
128 {
129 cs_debug_mask (D_IFD, "IFD: Failed MP35 command: exit_program_mode");
130 return ERROR;
131 }
132 }
133 else //MP3.5 or MP3.6
134 {
135 if(product_fw_version >= 0x0500)
136 {
137 int info_len;
138 char info[sizeof(rec_buf) - 2];
139
140 memset(rec_buf, 0x00, sizeof(rec_buf));
141 call(IO_Serial_Write(reader, 0, 2, fw_info));
142 call(IO_Serial_Read(reader, 200, 1, rec_buf));
143 info_len = rec_buf[0];
144 call(IO_Serial_Read(reader, 200, info_len + 1, rec_buf));
145 if(rec_buf[info_len] != ACK)
146 {
147 cs_debug_mask (D_IFD, "IFD: Failed MP35 command: fw_info");
148 return ERROR;
149 }
150 memcpy(info, rec_buf, info_len);
151 info[info_len] = '\0';
152 cs_log("MP35_Init: FW Info - %s", info);
153 }
154
155// memset(rec_buf, 0x00, sizeof(rec_buf));
156// call(IO_Serial_Write(reader, 0, 2, power_always_on));
157// call(IO_Serial_Read(reader, 200, 1, rec_buf));
158// if(rec_buf[0] != ACK)
159// {
160// cs_debug_mask (D_IFD, "IFD: Failed MP35 command: power_always_on");
161// return ERROR;
162// }
163
164 memset(rec_buf, 0x00, sizeof(rec_buf));
165 if(original_mhz == 357)
166 {
167 cs_log("MP35_Init: Using oscillator 1 (3.57MHz)");
168 call(IO_Serial_Write(reader, 0, 2, phoenix_mode));
169 }
170 else if(original_mhz == 600)
171 {
172 cs_log("MP35_Init: Using oscillator 2 (6.00MHz)");
173 call(IO_Serial_Write(reader, 0, 2, phoenix_6mhz_mode));
174 }
175 else
176 {
177 cs_log("MP35_Init: MP35 support only mhz=357 or mhz=600");
178 cs_log("MP35_Init: Forced oscillator 1 (3.57MHz)");
179 call(IO_Serial_Write(reader, 0, 2, phoenix_mode));
180 original_mhz = 357;
181 }
182 }
183
184 reader->mhz = original_mhz; // We might have switched oscillator here
185
186 IO_Serial_Flush(reader);
187
188 return OK;
189}
190
191int MP35_Close(struct s_reader * reader)
192{
193 cs_debug_mask (D_IFD, "IFD: Closing MP35 device %s", reader->device);
194
195 if(current_product != 0x10) // USB Phoenix
196 {
197 IO_Serial_Sendbreak(reader, 1500);
198 IO_Serial_DTR_Clr(reader);
199 }
200
201 IO_Serial_Close(reader);
202
203 return OK;
204}
Note: See TracBrowser for help on using the repository browser.