- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / csctapi / ifd_sci.c
blobd414e3476a4f1890a6c0f93e1f9e4f625c652b1e
1 /*
2 ifd_sci.c
3 This module provides IFD handling functions for SCI internal reader.
4 */
6 #include "../globals.h"
8 #ifdef CARDREADER_INTERNAL_SCI
10 #include "../oscam-time.h"
12 #include "atr.h"
13 #include "ifd_sci_global.h"
14 #include "ifd_sci_ioctl.h"
15 #include "io_serial.h"
16 #include "../oscam-string.h"
18 #define OK 0
19 #define ERROR 1
21 struct sr_data
23 uint8_t old_reset;
24 unsigned char T;
25 uint32_t fs;
26 uint32_t ETU;
27 uint32_t WWT;
28 uint32_t CWT;
29 uint32_t BWT;
30 uint32_t EGT;
31 unsigned char P;
32 unsigned char I;
35 static int32_t Sci_GetStatus(struct s_reader *reader, int32_t *status)
37 call (ioctl(reader->handle, IOCTL_GET_IS_CARD_PRESENT, status)<0);
38 return OK;
41 static int32_t Sci_Deactivate(struct s_reader *reader)
43 int32_t in = 0 ;
44 rdr_log(reader, "Deactivating card");
45 if (ioctl(reader->handle, IOCTL_GET_IS_CARD_PRESENT, &in)<0)
47 rdr_log(reader, "Error:%s ioctl(IOCTL_GET_IS_CARD_PRESENT) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) );
48 return ERROR;
50 if (in != 1) {ioctl(reader->handle, IOCTL_GET_IS_CARD_ACTIVATED, &in);}
52 if(in && boxtype_is("dm8000"))
54 if((ioctl(reader->handle, IOCTL_SET_DEACTIVATE)<0))
56 rdr_log(reader,"ioctl(IOCTL_SET_DEACTIVATE) not supported on %s", boxtype_get());
57 return ERROR;
60 else {return ERROR;}
62 return OK;
66 static int32_t Sci_Activate(struct s_reader *reader)
68 rdr_log_dbg(reader, D_IFD, "Is card present?");
69 int32_t in = 0;
70 if (ioctl(reader->handle, IOCTL_GET_IS_CARD_PRESENT, &in)<0)
72 rdr_log(reader, "Error:%s ioctl(IOCTL_GET_IS_CARD_PRESENT) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) );
73 Sci_Deactivate(reader);
74 return ERROR;
76 if (in != 1) {ioctl(reader->handle, IOCTL_GET_IS_CARD_ACTIVATED, &in);}
78 if (in)
80 cs_sleepms(50);
81 return OK;
83 else
85 rdr_log(reader, "Error: no card is present in readerslot!");
86 Sci_Deactivate(reader);
87 return ERROR;
91 static int32_t Sci_Read_ATR(struct s_reader *reader, ATR *atr) // reads ATR on the fly: reading and some low levelchecking at the same time
93 uint32_t timeout = ATR_TIMEOUT;
94 unsigned char buf[SCI_MAX_ATR_SIZE];
95 int32_t n = 0, statusreturn = 0;
97 if(IO_Serial_Read(reader, 0, timeout, 1, buf + n)) //read first char of atr
99 rdr_log(reader, "ERROR: no characters found in ATR!");
100 return ERROR;
102 if(buf[0] == 0x3F) // 3F: card is using inverse convention, 3B = card is using direct convention
104 rdr_log_dbg(reader, D_IFD, "This card uses inverse convention");
106 else { rdr_log_dbg(reader, D_IFD, "This card uses direct convention"); }
107 n++;
108 if(IO_Serial_Read(reader, 0, timeout, 1, buf + n))
110 rdr_log_dbg(reader, D_IFD, "ERROR: only 1 character found in ATR");
111 return ERROR;
113 int32_t T0 = buf[n];
114 int32_t historicalbytes = T0 & 0x0F; // num of historical bytes in lower nibble of T0 byte
115 rdr_log_dbg(reader, D_ATR, "ATR historicalbytes should be: %d", historicalbytes);
116 rdr_log_dbg(reader, D_ATR, "Fetching global interface characters for protocol T0"); // protocol T0 always aboard!
117 n++;
119 int32_t protocols = 1, tck = 0, protocol, protocolnumber; // protocols = total protocols on card, tck = checksum byte present, protocol = mandatory protocol
120 int32_t D = 0; // protocolnumber = TDi uses protocolnumber
121 int32_t TDi = T0; // place T0 char into TDi for looped parsing.
122 while(n < SCI_MAX_ATR_SIZE)
124 if(TDi & 0x10) //TA Present: //The value of TA(i) is always interpreted as XI || UI if i > 2 and T = 15 ='F'in TD(i�1)
126 if(IO_Serial_Read(reader, 0, timeout, 1, buf + n)) { break; } //In this case, TA(i) contains the clock stop indicator XI, which indicates the logical
127 //state the clockline must assume when the clock is stopped, and the class indicator UI,
128 rdr_log_dbg(reader, D_ATR, "TA%d: %02X", protocols, buf[n]); //which specifies the supply voltage class.
129 if((protocols > 2) && ((TDi & 0x0F) == 0x0F)) // Protocol T15 does not exists, it means mandatory on all ATRs
131 if((buf[n] & 0xC0) == 0xC0) { rdr_log_dbg(reader, D_ATR, "Clockline low or high on clockstop"); }
132 if((buf[n] & 0xC0) == 0x00) { rdr_log_dbg(reader, D_ATR, "Clockline not supported on clockstop"); }
133 if((buf[n] & 0xC0) == 0x40) { rdr_log_dbg(reader, D_ATR, "Clockline should be low on clockstop"); }
134 if((buf[n] & 0xC0) == 0x80) { rdr_log_dbg(reader, D_ATR, "Clockline should be high on clockstop"); }
135 if((buf[n] & 0x3F) == 0x01) { rdr_log_dbg(reader, D_ATR, "Voltage class A 4.5~5.5V"); }
136 if((buf[n] & 0x3F) == 0x02) { rdr_log_dbg(reader, D_ATR, "Voltage class B 2.7~3.3V"); }
137 if((buf[n] & 0x3F) == 0x03) { rdr_log_dbg(reader, D_ATR, "Voltage class A 4.5~5.5V and class B 2.7~3.3V"); }
138 if((buf[n] & 0x3F) == 0x04) { rdr_log_dbg(reader, D_ATR, "Voltage RFU"); }
140 if((protocols > 2) && ((TDi & 0x0F) == 0x01)) // Protocol T1 specfic (There is always an obsolete T0 protocol!)
142 int32_t ifsc = buf[n];
143 if(ifsc == 0x00) { ifsc = 32; } //default is 32
144 rdr_log_dbg(reader, D_ATR, "Maximum information field length this card can receive is %d bytes (IFSC)", ifsc);
147 if(protocols < 2)
149 int32_t FI = (buf[n] >> 4); // FI is high nibble ***** work ETU = (1/D)*(Frequencydivider/cardfrequency) (in seconds!)
150 int32_t Fi = atr_f_table[FI]; // lookup the frequency divider
151 float fmax = atr_fs_table[FI]; // lookup the max frequency ***** initial ETU = 372 / initial frequency during atr (in seconds!)
153 int32_t DI = (buf[n] & 0x0F); // DI is low nibble
154 D = atr_d_table[DI]; // lookup the bitrate adjustment (yeah there are floats in it, but in iso only integers!?)
155 rdr_log_dbg(reader, D_ATR, "Advertised max cardfrequency is %.2f (Fmax), frequency divider is %d (Fi)", fmax / 1000000L, Fi); // High nibble TA1 contains cardspeed
156 rdr_log_dbg(reader, D_ATR, "Bitrate adjustment is %d (D)", D); // Low nibble TA1 contains Bitrateadjustment
157 rdr_log_dbg(reader, D_ATR, "Work ETU = %.2f us assuming card runs at %.2f Mhz",
158 (double)((1 / (double)D) * ((double)Fi / (double)fmax) * 1000000), fmax / 1000000L); // And display it...
159 rdr_log_dbg(reader, D_ATR, "Initial ETU = %.2f us", (double)372 / (double)fmax * 1000000); // And display it... since D=1 and frequency during ATR fetch might be different!
161 if(protocols > 1 && protocols < 3)
163 if((buf[n] & 0x80) == 0x80) { rdr_log_dbg(reader, D_ATR, "Switching between negotiable mode and specific mode is not possible"); }
164 else
166 rdr_log_dbg(reader, D_ATR, "Switching between negotiable mode and specific mode is possible");
167 // int32_t PPS = 1; Stupid compiler, will need it later on eventually
169 if((buf[n] & 0x01) == 0x01) { rdr_log_dbg(reader, D_ATR, "Transmission parameters implicitly defined in the interface characters."); }
170 else { rdr_log_dbg(reader, D_ATR, "Transmission parameters explicitly defined in the interface characters."); }
172 protocol = buf[n] & 0x0F;
173 if(protocol) { rdr_log_dbg(reader, D_ATR, "Protocol T = %d is to be used!", protocol); }
175 n++; // next interface character
177 if(TDi & 0x20) //TB Present
179 if(IO_Serial_Read(reader, 0, timeout, 1, buf + n)) { break; }
180 rdr_log_dbg(reader, D_ATR, "TB%d: %02X", protocols, buf[n]);
181 if((protocols > 2) && ((TDi & 0x0F) == 0x01)) // Protocol T1 specfic (There is always an obsolete T0 protocol!)
183 int32_t CWI = (buf[n] & 0x0F); // low nibble contains CWI code for the character waiting time CWT
184 int32_t BWI = (buf[n] >> 4); // high nibble contains BWI code for the block waiting time BWT
185 rdr_log_dbg(reader, D_ATR, "Protocol T1: Character waiting time is %d(CWI)", CWI);
186 rdr_log_dbg(reader, D_ATR, "Protocol T1: Block waiting time is %d (BWI)", BWI);
189 n++; // next interface character
191 if(TDi & 0x40) //TC Present
193 if(IO_Serial_Read(reader, 0, timeout, 1, buf + n)) { break; }
194 rdr_log_dbg(reader, D_ATR, "TC%d: %02X", protocols, buf[n]);
195 if((protocols > 1) && ((TDi & 0x0F) == 0x00))
197 int32_t WI = buf[n];
198 rdr_log_dbg(reader, D_ATR, "Protocol T0: work wait time is %d work etu (WWT)", (int)(960 * D * WI));
200 if((protocols > 1) && ((TDi & 0x0F) == 0x01))
202 if(buf[n] & 0x01) { rdr_log_dbg(reader, D_ATR, "Protocol T1: CRC is used to compute the error detection code"); }
203 else { rdr_log_dbg(reader, D_ATR, "Protocol T1: LRC is used to compute the error detection code"); }
205 if((protocols < 2) && (buf[n] < 0xFF)) { rdr_log_dbg(reader, D_ATR, "Extra guardtime of %d ETU (N)", (int) buf[n]); }
206 if((protocols < 2) && (buf[n] == 0xFF)) { rdr_log_dbg(reader, D_ATR, "Protocol T1: Standard 2 ETU guardtime is lowered to 1 ETU"); }
208 n++; // next interface character
210 if(TDi & 0x80) //TD Present? Get next TDi there will be a next protocol
212 if(IO_Serial_Read(reader, 0, timeout, 1, buf + n)) { break; }
213 rdr_log_dbg(reader, D_ATR, "TD%d %02X", protocols, buf[n]);
214 TDi = buf[n];
215 protocolnumber = TDi & 0x0F;
216 if(protocolnumber == 0x00) { tck = 0; } // T0 protocol do not use tck byte (TCK = checksum byte!)
217 if(protocolnumber == 0x0E) { tck = 1; } // T14 protocol tck byte should be present
218 if(protocolnumber == 0x01) { tck = 1; } // T1 protocol tck byte is mandatory, BTW: this code doesnt calculate if the TCK is valid jet...
219 rdr_log_dbg(reader, D_ATR, "Fetching global interface characters for protocol T%d:", (TDi & 0x0F)); // lower nibble contains protocol number
220 protocols++; // there is always 1 protocol T0 in every ATR as per iso defined, max is 16 (numbered 0..15)
222 n++; // next interface character
224 else { break; }
226 int32_t atrlength = 0;
227 atrlength += n;
228 atrlength += historicalbytes;
229 rdr_log_dbg(reader, D_ATR, "Total ATR Length including %d historical bytes should be %d", historicalbytes, atrlength);
230 if(T0 & 0x80) { protocols--; } // if bit 8 set there was a TD1 and also more protocols, otherwise this is a T0 card: substract 1 from total protocols
231 rdr_log_dbg(reader, D_ATR, "Total protocols in this ATR is %d", protocols);
233 while(n < atrlength + tck) // read all the rest and mandatory tck byte if other protocol than T0 is used.
235 if(IO_Serial_Read(reader, 0, timeout, 1, buf + n)) { break; }
236 n++;
239 if(n != atrlength + tck) { rdr_log(reader, "WARNING: Total ATR characters received is: %d instead of expected %d", n, atrlength + tck); }
241 if((buf[0] != 0x3B) && (buf[0] != 0x3F) && (n > 9 && !memcmp(buf + 4, "IRDETO", 6))) // irdeto S02 reports FD as first byte on dreambox SCI, not sure about SH4 or phoenix
242 { buf[0] = 0x3B; }
244 statusreturn = ATR_InitFromArray(atr, buf, n); // n should be same as atr length but in case of atr read error it's less, so do not use atr length here!
246 if(buf[7] == 0x70 && buf[8] == 0x70 && (buf[9]&0x0F) >= 10)
248 const struct s_cardreader *crdr_ops = reader->crdr;
249 if (!crdr_ops) return ERROR;
250 int8_t nxtr = 0;
251 reader->crdr_flush = 0;
252 while(nxtr < 2)
254 if(IO_Serial_Read(reader, 0, 75000, 1, buf + n + nxtr)) { break; }
255 nxtr++;
259 if(statusreturn == ATR_MALFORMED) { rdr_log(reader, "WARNING: ATR is malformed, you better inspect it with a -d2 log!"); }
261 if(statusreturn == ERROR)
263 rdr_log(reader, "WARNING: ATR is invalid!");
264 return ERROR;
267 return OK; // return OK but atr might be softfailing!
270 static int32_t Sci_Reset(struct s_reader *reader, ATR *atr)
272 int32_t ret = ERROR;
274 SCI_PARAMETERS params;
276 memset(&params, 0, sizeof(SCI_PARAMETERS));
278 params.ETU = 372; //initial ETU (in iso this parameter F)
279 params.EGT = 0; //initial guardtime should be 0 (in iso this is parameter N)
280 params.fs = 3; //initial cardmhz 3 Mhz for non pll readers (in iso this is parameter D)
281 params.T = 0;
282 if(reader->cardmhz > 2000) // PLL based reader
284 params.ETU = 372;
285 params.EGT = 0;
286 params.fs = (int32_t)(reader->cardmhz / 100.0 + 0.5); /* calculate divider for 1 MHz */
287 params.T = 0;
289 if(reader->cardmhz == 8300) /* PLL based reader DM7025 */
291 params.ETU = 372;
292 params.EGT = 0;
293 params.fs = 16; /* read from table setting for 1 MHz:
294 params.fs = 6 for cardmhz = 5.188 MHz
295 params.fs = 7 for cardmhz = 4.611 MHz
296 params.fs = 8 for cardmhz = 3.953 MHz
297 params.fs = 9 for cardmhz = 3.609 MHz
298 params.fs = 10 for cardmhz = 3.192 MHz
299 params.fs = 11 for cardmhz = 2.965 MHz
300 params.fs = 12 for cardmhz = 2.677 MHz
301 params.fs = 13 for cardmhz = 2.441 MHz
302 params.fs = 14 for cardmhz = 2.306 MHz
303 params.fs = 15 for cardmhz = 2.128 MHz
304 params.fs = 16 for cardmhz = 1.977 MHz */
305 params.T = 0;
308 int32_t tries = 0;
309 int32_t max_tries = 0;
310 int32_t pll_start_fs = 0;
311 if (reader->cardmhz > 2000 && reader->cardmhz != 8300)
313 max_tries = (((double)(reader->cardmhz/900)) * 2 ) + 1 ; // the higher the maxpll the higher tries needed, to have 9 Mhz or first avb below.
314 pll_start_fs = ((double)(reader->cardmhz/300)) + 1.5 ; // first avbl reader Mhz equal or above 3.0 Mhz
316 else
318 max_tries = 5;
320 while(ret == ERROR && tries < max_tries)
322 cs_sleepms(50);
323 // rdr_log(reader, "Set reader parameters!");
324 rdr_log_dbg(reader, D_IFD, "Sent reader setting at cardinit T=%d fs=%d ETU=%d WWT=%d CWT=%d BWT=%d EGT=%d clock=%d check=%d P=%d I=%d U=%d",
325 (int)params.T, params.fs, (int)params.ETU, (int)params.WWT,
326 (int)params.CWT, (int)params.BWT, (int)params.EGT,
327 (int)params.clock_stop_polarity, (int)params.check,
328 (int)params.P, (int)params.I, (int)params.U);
329 ioctl(reader->handle, IOCTL_SET_PARAMETERS, &params);
330 cs_sleepms(150); // give the reader some time to process the params
332 // rdr_log(reader, "Reset internal cardreader!");
333 if(ioctl(reader->handle, IOCTL_SET_RESET, 1) < 0)
335 ret = ERROR;
336 rdr_log(reader, "Error:%s ioctl(IOCTL_SET_RESET) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) );
337 Sci_Deactivate(reader);
338 Sci_Activate(reader);
339 cs_sleepms(50);
341 else
343 ret = Sci_Read_ATR(reader, atr);
344 if(ret == ERROR)
346 Sci_Deactivate(reader);
347 Sci_Activate(reader);
348 if (reader->cardmhz > 2000 && reader->cardmhz != 8300)
350 tries++; // increase fs
351 params.fs = (pll_start_fs - tries); // if 1 Mhz init failed retry with min 300 Mhz up to max 9.0 Mhz
352 rdr_log(reader, "Read ATR fail, attempt %d/%d fs = %d", tries, max_tries, params.fs);
354 else if (reader->cardmhz > 2000 && reader->cardmhz == 8300)
356 tries++; // increase fs
357 params.fs = (11 - tries); // if 1 Mhz init failed retry with 3.19 Mhz up to 5.188 Mhz
358 rdr_log(reader, "Read ATR fail, attempt %d/5 fs = %d", tries, params.fs);
360 else
362 tries++; // increase fs
363 params.fs = (2 + tries); // if 1 Mhz init failed retry with 3.0 Mhz up to 7.0 Mhz
364 rdr_log(reader, "Read ATR fail, attempt %d/5 fs = %d", tries, params.fs);
367 else // ATR fetched successfully!
369 if(ioctl(reader->handle, IOCTL_SET_ATR_READY, 1) < 0)
371 ret = ERROR;
372 rdr_log(reader, "Error:%s ioctl(IOCTL_SET_ATR_READY) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) );
377 return ret;
380 static int32_t Sci_WriteSettings(struct s_reader *reader, unsigned char T, uint32_t fs, uint32_t ETU, uint32_t WWT, uint32_t CWT, uint32_t BWT, uint32_t EGT, unsigned char P, unsigned char I)
382 cs_sleepms(150);
383 struct sr_data *crdr_data = reader->crdr_data;
384 //int32_t n;
385 SCI_PARAMETERS params;
386 //memset(&params,0,sizeof(SCI_PARAMETERS));
387 ioctl(reader->handle, IOCTL_GET_PARAMETERS, &params);
388 params.T = T;
389 params.fs = fs;
391 //for Irdeto T14 cards, do not set ETU
392 if(ETU)
393 { params.ETU = ETU; }
394 params.EGT = EGT;
395 params.WWT = WWT;
396 params.BWT = BWT;
397 params.CWT = CWT;
398 if(P)
399 { params.P = P; }
400 if(I)
401 { params.I = I; }
403 crdr_data->T = params.T;
404 crdr_data->fs = params.fs;
405 crdr_data->ETU = params.ETU;
406 crdr_data->WWT = params.WWT;
407 crdr_data->CWT = params.CWT;
408 crdr_data->BWT = params.BWT;
409 crdr_data->EGT = params.EGT;
410 crdr_data->P = params.P;
411 crdr_data->I = params.I;
413 rdr_log_dbg(reader, D_IFD, "Sent reader settings T=%d fs=%d ETU=%d WWT=%d CWT=%d BWT=%d EGT=%d clock=%d check=%d P=%d I=%d U=%d",
414 (int)params.T, params.fs, (int)params.ETU, (int)params.WWT,
415 (int)params.CWT, (int)params.BWT, (int)params.EGT,
416 (int)params.clock_stop_polarity, (int)params.check,
417 (int)params.P, (int)params.I, (int)params.U);
419 ioctl(reader->handle, IOCTL_SET_PARAMETERS, &params);
420 cs_sleepms(150); // give the reader some time to process the params
421 return OK;
424 static int32_t Sci_FastReset(struct s_reader *reader, ATR *atr)
426 struct sr_data *crdr_data = reader->crdr_data;
427 int8_t atr_ok = 1; // initiate atr in ERROR
428 uint32_t timeout = ATR_TIMEOUT;
429 unsigned char buf[SCI_MAX_ATR_SIZE];
430 int8_t atr_len = 0;
432 if(reader->seca_nagra_card == 1)
434 atr_len = reader->card_atr_length; // this is a special case the data buffer has only the atr length.
436 else
438 atr_len = reader->card_atr_length + 2; // data buffer has atr length + 2 bytes
441 Sci_Activate(reader);
442 cs_sleepms(50);
443 if(ioctl(reader->handle, IOCTL_SET_RESET, 1) < 0)
445 rdr_log(reader, "Error:%s ioctl(IOCTL_SET_RESET) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) );
446 Sci_Deactivate(reader);
447 atr_ok = ERROR;
449 else
451 IO_Serial_Read(reader, 0, timeout*10, atr_len, buf); //read atr: give some extra timeout time since on some platforms all chars are read at once
452 // rdr_log_dump(reader,buf, SCI_MAX_ATR_SIZE * 2, "SCI ATR :"); // just to crosscheck the buffer I left it commented.
453 if(ioctl(reader->handle, IOCTL_SET_ATR_READY, 1) < 0)
455 rdr_log(reader, "Error:%s ioctl(IOCTL_SET_ATR_READY) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) );
456 Sci_Deactivate(reader);
457 atr_ok = ERROR;
459 else
461 if(ATR_InitFromArray(atr, buf, atr_len) != ERROR)
463 atr_ok = OK;
465 else
467 rdr_log(reader,"Error reading ATR");
468 atr_ok= ERROR;
471 cs_sleepms(150);
472 Sci_WriteSettings(reader, crdr_data->T,crdr_data->fs,crdr_data->ETU, crdr_data->WWT,crdr_data->CWT,crdr_data->BWT,crdr_data->EGT,crdr_data->P,crdr_data->I);
473 cs_sleepms(150);
476 return atr_ok;
479 static int32_t Sci_Init(struct s_reader *reader)
481 uint8_t i = 0;
482 while(reader->handle_nr > 0 && i < 5)
484 i++;
485 rdr_log(reader," Wait On closing before restart %u", i);
486 cs_sleepms(1000);
489 int flags = O_RDWR | O_NOCTTY;
490 #if defined(__SH4__) || defined(STB04SCI)
491 flags |= O_NONBLOCK;
492 reader->sh4_stb = 1;
493 #endif
494 reader->handle = open(reader->device, flags);
495 if(reader->handle < 0)
497 rdr_log(reader, "ERROR: Opening device %s (errno=%d %s)", reader->device, errno, strerror(errno));
498 return ERROR;
501 if(!reader->crdr_data && !cs_malloc(&reader->crdr_data, sizeof(struct sr_data)))
502 { return ERROR; }
503 struct sr_data *crdr_data = reader->crdr_data;
504 crdr_data->old_reset = 1;
505 reader->handle_nr = reader->handle + 1;
506 return OK;
509 static int32_t sci_activate(struct s_reader *reader, ATR *atr)
511 if(!reader->ins7e11_fast_reset)
513 call(Sci_Activate(reader));
514 call(Sci_Reset(reader, atr));
516 else
518 rdr_log_dbg(reader, D_IFD, "Fast card reset with atr");
519 call(Sci_FastReset(reader, atr));
521 return OK;
524 static int32_t Sci_Close(struct s_reader *reader)
526 Sci_Deactivate(reader);
527 IO_Serial_Close(reader);
528 NULLFREE(reader->crdr_data); //clearing allocated module mem
529 NULLFREE(reader->csystem_data); //clearing allocated card system mem
530 cs_sleepms(150); // some stb's needs small extra time even after close procedure seems to be ok.
531 reader->handle_nr = 0;
532 return OK;
535 static int32_t sci_write_settings(struct s_reader *reader, struct s_cardreader_settings *s)
537 if(reader->cardmhz > 2000) // only for dreambox internal pll readers clockspeed can be set precise others like vu ignore it and work always at 4.5 Mhz
539 // P fixed at 5V since this is default class A card, and TB is deprecated
540 if(reader->protocol_type != ATR_PROTOCOL_TYPE_T14) // fix VU+ internal reader slow responses on T0/T1
542 cs_sleepms(150);
543 call(Sci_WriteSettings(reader, 0, reader->divider, s->ETU, s->WWT, reader->CWT, reader->BWT, s->EGT, 5, (unsigned char)s->I));
544 cs_sleepms(150);
546 else // no fixup for T14 protocol otherwise error
548 cs_sleepms(150);
549 call(Sci_WriteSettings(reader, reader->protocol_type, reader->divider, s->ETU, s->WWT, reader->CWT, reader->BWT, s->EGT, 5, (unsigned char)s->I));
550 cs_sleepms(150);
553 else // all other brand boxes than dreamboxes or VU+!
555 // P fixed at 5V since this is default class A card, and TB is deprecated
556 cs_sleepms(150);
557 // non pll internal reader needs base frequency like 1,2,3,4,5,6 MHz not clock rate conversion factor (Fi)
558 call(Sci_WriteSettings(reader, reader->protocol_type, s->F/100, s->ETU, s->WWT, reader->CWT, reader->BWT, s->EGT, 5, (unsigned char)s->I));
559 cs_sleepms(150);
561 return OK;
564 const struct s_cardreader cardreader_internal_sci =
566 .desc = "internal",
567 .typ = R_INTERNAL,
568 .flush = 1,
569 .max_clock_speed = 1,
570 .reader_init = Sci_Init,
571 .get_status = Sci_GetStatus,
572 .activate = sci_activate,
573 .transmit = IO_Serial_Transmit,
574 .receive = IO_Serial_Receive,
575 .close = Sci_Close,
576 .write_settings = sci_write_settings,
579 #endif