|
|
View previous topic :: View next topic |
Author |
Message |
Wilhelm
Joined: 04 Jun 2005 Posts: 4 Location: Namibia
|
Siemens ChipCards SLE4432 / SLE4442 |
Posted: Sat Jun 04, 2005 1:37 pm |
|
|
Hi,
I am a software developer (Linux GCC mainly) but have been tasked by a company in our group for a PCW Driver for the SLE 4442 Chipcard.
When done I will post the code in the Code Library for everyone to benefit from (Open source is part of my coding practices)
For those who are not familiar with the SLE4442 Chip, it is a 256-Byte EEPROM.
Datasheet : http://www.scdeveloper.com/datasheet/sle4442.pdf
Assume the following :
1) PIC16F84
2) RA0 -> RST on SLE
RA1 -> CLK on SLE
RA2 -> I/O on SLE
3) include lcd.c (so this will be on RB0-7) for output.
Page 10 of the SLE datasheet shows the ATR proceedure.
The SLE requires 31 clock pulses after a reset.
so I would set RA0 - High (Reset), then Low again to complete the reset command.
then to generate the 31 clock pulses must I do the following ?
Code: |
for (i=1;i<=31;++i)
{
output_high(RA1);
output_low(RA1);
printf("Bit :%c",input(RA2)+0x30);
};
|
am I correct in assuming that This will produce the 31 clock pulses and read the I/O (high or low) during each clock pulse as per the datasheet ?
Not being an electronic engineer I don't fully understand the concept of "rising edge" and "falling edge" as per 2.2.2 in the datasheet.
I will address the reading, and writing after this part is working. (In the same thread)
Thank you in advance
Wilhelm Lehmann |
|
|
libor
Joined: 14 Dec 2004 Posts: 288 Location: Hungary
|
|
Posted: Sat Jun 04, 2005 2:32 pm |
|
|
Just a few comments:
- If I get it right there must be a clock pulse during the reset also according to the datasheet.
- The datasheet specifies both min. and max. timing intervals and frequencies for all signals, you should also consider the timing issues depending on the frequency your PIC is running, the output_high() followed by the output_low() might result a pulse too short, the printf() may take too much time before the next loop iteration...
- Dont forget, that I/O line is an open drain, must be pulled up by an external resistor.
so much came to my mind so far, is it reading something at all? |
|
|
Guest
|
|
Posted: Sat Jun 04, 2005 4:18 pm |
|
|
Thanks for the reply.
Note Taken of the fist clock pulse on the reset signal.
You mention the Min and Max clock pulses. I see the clock freq is min 7 and max 50kHz.
(in my First post I said will be using 16F84 just to add this is at 4Mhz)
Then what are the implications of using a different PIC with say a 20Mhz Xtal ?
How can I ensure that this is maintained ? irrespective of the PIC being used ? Say keeping a value of 25kHz ?
If the Printf() may take to long, would you suggest that I do all the read/write operations to the SLE first then send output to the LCD ?
I/O Line is an open drain ? So RA2 can't connect directly to the I/O. Must there then be a resistor between VCC and I/O, With I/O to RA2 ?
I understand a pullup resistor to be between VCC and Pin X and a Pulldown as between GND and Pin X. Is this right ?
Thanks for all the help ... |
|
|
libor
Joined: 14 Dec 2004 Posts: 288 Location: Hungary
|
|
Posted: Sat Jun 04, 2005 5:29 pm |
|
|
The simplest way of making pulses of certain length is to use the delay_us() or delay_ms() instructions between port manipulation.
The #use_delay(clock=4000000) in the beginning will inform the compiler how fast is your PIC running (4Mhz in this case), so it will generate the delay routines accordingly. If you move to another PIC running at different speed, you only have to change this directive.
Eg. to make a clock pulse of ca. 25 kHz: (length of high pulse is ca. 20us = half period at 25khz)
Code: | output_high(RA1);
delay_us(20); //you can subtract the output...()'s execution time from the delay time when a more precise timing needed
output_low(RA1);
|
Yes. you should not do long time consuming tasks during 'bit banging' on ports. collect the incoming bits into a variable (eg. by rotating it in bit-by-bit), and printf() the variable(s) when the timing sensitive port reading operation is over.
Yes, you are correct with the resistor thing. Use any value in the range 10k - 100k for pull-ups/downs.
For extra safety when learning/testing you can also add a 1k-10k resistor in series (it should be max. ca. 1/10 value of the pull-up/down on the same port) between the PIC and the device under test. So you can avoid damaging your ICs by limiting the short current if accidentaly programming the two facing ports both as outputs and switching them to opposite levels. This added resistor will not influence communication at these low speeds. |
|
|
Wilhelm
Joined: 04 Jun 2005 Posts: 4 Location: Namibia
|
|
Posted: Sun Jun 05, 2005 3:50 pm |
|
|
Hi again,
After a bit of experimenting ...
The Datasheet states while sending the ATR you get the first four addresses on the eeprom read back during the ATR pulses.
This works 100% (with the code below) and the fist 2 addresses are dispalyed on line 1 of the LCD and the next 2 on line 2.
Code: | #define RST PIN_A0
#define CLK PIN_A1
#define IO PIN_A2
#define SOUND PIN_B3
unsigned int i;
char a[33];
int z;
int c;
int1 n;
void Beep( int1 n ) {
for (c=1;c<=n;++c) {
output_high(sound);
delay_ms(100);
output_low(sound);
delay_ms(100);
}
}
void main() {
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
Beep(2);
lcd_init();
delay_ms(500);
printf(lcd_putc,"\f");
delay_ms(100);
lcd_gotoxy(1, 1) ;
for (i=0;i<=32;++i)
{
output_high(CLK);
if (i==0) { output_high(RST); };
delay_us(14);
if( input(PIN_A2) ) a[i] = '1';
if( !input(PIN_A2) ) a[i] = '0';
output_low(CLK);
if (i==0) { output_low(RST); };
delay_us(14);
};
output_high(sound);
delay_ms(1000);
output_low(sound);
For(i=1;i<=32;++i)
{
printf(lcd_putc,"%c",a[i]);
if (i==8) { printf(lcd_putc," "); };
if (i==16) { printf(lcd_putc," "); lcd_gotoxy(1, 2) ; };
if (i==24) { printf(lcd_putc," "); };
if (i==32) { printf(lcd_putc," "); };
};
}
|
Now The problem ...
Instead of dispalying the 4 Addresses from the ATR sequence, I want to read the first 4 addresses by sending the read command, followed by the address, followed by 8 bits (with no effect). (ie READ + ADDRESS + NO EFFECT) (Page 13 of the SLE datasheet)
the read command is 00110000 and for the fisrt four addresses again the start address must be 00000000. then for the no effect data I send 00000000
Then I should be able to send 32 clock pulses and read the data again like the first bit of code (so I use the same code) but add the Read,address,no effect portion between ATR and Read 32 bits.
Not ideal code, but I thought it should work.
Code: |
unsigned int i;
char a[33];
int z;
int c;
int1 n;
void ClockSignal( int1 n ) {
output_high(CLK);
delay_us(14);
output_low(CLK);
if (n==1) output_high(PIN_A2);
if (n==0) output_low(PIN_A2);
delay_us(14);
}
void Beep( int1 n ) {
for (c=1;c<=n;++c) {
output_high(sound);
delay_ms(100);
output_low(sound);
delay_ms(100);
}
}
void main() {
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
Beep(2);
lcd_init();
delay_ms(500);
printf(lcd_putc,"\f");
delay_ms(100);
lcd_gotoxy(1, 1) ;
//Send ATR
for (i=0;i<=32;++i)
{
output_high(CLK);
if (i==0) { output_high(RST); };
delay_us(14);
if( input(PIN_A2) ) a[i] = '1';
if( !input(PIN_A2) ) a[i] = '0';
output_low(CLK);
if (i==0) { output_low(RST); };
delay_us(14);
};
// Send Read Command
ClockSignal(0);
ClockSignal(0);
ClockSignal(1);
ClockSignal(1);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
// Send Address
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
//Send 3rd Word
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
//ensure Pin A2 is Low
output_low(PIN_A2);
// Read Data
output_high(CLK);
delay_us(14);
output_high(PIN_A2);
delay_us(14);
output_low(CLK);
delay_us(14);
for (i=1;i<=32;++i)
{
output_high(CLK);
delay_us(14);
if( input(PIN_A2) ) a[i] = '1';
if( !input(PIN_A2) ) a[i] = '0';
output_low(CLK);
delay_us(14);
};
output_high(sound);
delay_ms(1000);
output_low(sound);
For(i=1;i<=32;++i)
{
printf(lcd_putc,"%c",a[i]);
if (i==8) { printf(lcd_putc," "); };
if (i==16) { printf(lcd_putc," "); lcd_gotoxy(1, 2) ; };
if (i==24) { printf(lcd_putc," "); };
if (i==32) { printf(lcd_putc," "); };
};
}
|
Yet wen executing this code I should get the same results as the first set of code, but I get all '1'
I quess I missed something stupid ? Any ideas ?
Wilhelm |
|
|
libor
Joined: 14 Dec 2004 Posts: 288 Location: Hungary
|
|
Posted: Mon Jun 06, 2005 2:26 pm |
|
|
- the bits on the data line are LSB first according to the data sheet diagrams: to send the command 00110000, you have to send the bits in reverse order: 00001100
- i would suggest to use #use fast_io(port) directive to allow setting each port's direction manually with set_tris_X() command, so you have to set each port's direction explicitly before using it either for output or for input, it is less confusing when you use a port that function in both directions (DATA line) you can be always aware of what direction a port is set to.
- I have not checked thoroughly if you deal with the start-condition and stop-condition mentioned on page 10. have a look at it. |
|
|
Wilhelm
Joined: 04 Jun 2005 Posts: 4 Location: Namibia
|
|
Posted: Mon Jun 06, 2005 5:04 pm |
|
|
Hi,
Quote: | - the bits on the data line are LSB first according to the data sheet diagrams: to send the command 00110000, you have to send the bits in reverse order: 00001100 |
So I changed : Code: | // Send Read Command
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(1);
ClockSignal(1);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
|
To
Code: | // Send Read Command
ClockSignal(0); // Clock Pulse 0
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(0);
ClockSignal(1);
ClockSignal(1);
ClockSignal(0);
ClockSignal(0);
|
Same results .... Just getting '1's
Then How does the set_tris_X() work ? (Using PIN_A2 for IO, RST and CLK works fine)
W |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|