3 This module provides IFD handling functions for SCI internal reader.
6 #include "../globals.h"
8 #ifdef CARDREADER_INTERNAL_SCI
10 #include "../oscam-time.h"
13 #include "ifd_sci_global.h"
14 #include "ifd_sci_ioctl.h"
15 #include "io_serial.h"
16 #include "../oscam-string.h"
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);
41 static int32_t Sci_Deactivate(struct s_reader
*reader
)
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
) );
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());
66 static int32_t Sci_Activate(struct s_reader
*reader
)
68 rdr_log_dbg(reader
, D_IFD
, "Is card present?");
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
);
76 if (in
!= 1) {ioctl(reader
->handle
, IOCTL_GET_IS_CARD_ACTIVATED
, &in
);}
85 rdr_log(reader
, "Error: no card is present in readerslot!");
86 Sci_Deactivate(reader
);
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!");
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"); }
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");
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!
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
);
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"); }
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))
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
]);
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
226 int32_t atrlength
= 0;
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; }
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
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
;
251 reader
->crdr_flush
= 0;
254 if(IO_Serial_Read(reader
, 0, 75000, 1, buf
+ n
+ nxtr
)) { break; }
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!");
267 return OK
; // return OK but atr might be softfailing!
270 static int32_t Sci_Reset(struct s_reader
*reader
, ATR
*atr
)
274 SCI_PARAMETERS params
;
276 memset(¶ms
, 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)
282 if(reader
->cardmhz
> 2000) // PLL based reader
286 params
.fs
= (int32_t)(reader
->cardmhz
/ 100.0 + 0.5); /* calculate divider for 1 MHz */
289 if(reader
->cardmhz
== 8300) /* PLL based reader DM7025 */
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 */
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
320 while(ret
== ERROR
&& tries
< max_tries
)
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
, ¶ms
);
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)
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
);
343 ret
= Sci_Read_ATR(reader
, atr
);
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
);
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)
372 rdr_log(reader
, "Error:%s ioctl(IOCTL_SET_ATR_READY) failed.(%d:%s)", __FUNCTION__
, errno
, strerror(errno
) );
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
)
383 struct sr_data
*crdr_data
= reader
->crdr_data
;
385 SCI_PARAMETERS params
;
386 //memset(¶ms,0,sizeof(SCI_PARAMETERS));
387 ioctl(reader
->handle
, IOCTL_GET_PARAMETERS
, ¶ms
);
391 //for Irdeto T14 cards, do not set ETU
393 { params
.ETU
= ETU
; }
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
, ¶ms
);
420 cs_sleepms(150); // give the reader some time to process the params
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
];
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.
438 atr_len
= reader
->card_atr_length
+ 2; // data buffer has atr length + 2 bytes
441 Sci_Activate(reader
);
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
);
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
);
461 if(ATR_InitFromArray(atr
, buf
, atr_len
) != ERROR
)
467 rdr_log(reader
,"Error reading ATR");
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
);
479 static int32_t Sci_Init(struct s_reader
*reader
)
482 while(reader
->handle_nr
> 0 && i
< 5)
485 rdr_log(reader
," Wait On closing before restart %u", i
);
489 int flags
= O_RDWR
| O_NOCTTY
;
490 #if defined(__SH4__) || defined(STB04SCI)
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
));
501 if(!reader
->crdr_data
&& !cs_malloc(&reader
->crdr_data
, sizeof(struct sr_data
)))
503 struct sr_data
*crdr_data
= reader
->crdr_data
;
504 crdr_data
->old_reset
= 1;
505 reader
->handle_nr
= reader
->handle
+ 1;
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
));
518 rdr_log_dbg(reader
, D_IFD
, "Fast card reset with atr");
519 call(Sci_FastReset(reader
, atr
));
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;
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
543 call(Sci_WriteSettings(reader
, 0, reader
->divider
, s
->ETU
, s
->WWT
, reader
->CWT
, reader
->BWT
, s
->EGT
, 5, (unsigned char)s
->I
));
546 else // no fixup for T14 protocol otherwise error
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
));
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
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
));
564 const struct s_cardreader cardreader_internal_sci
=
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
,
576 .write_settings
= sci_write_settings
,