CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Siemens ChipCards SLE4432 / SLE4442

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Wilhelm



Joined: 04 Jun 2005
Posts: 4
Location: Namibia

View user's profile Send private message Visit poster's website ICQ Number

Siemens ChipCards SLE4432 / SLE4442
PostPosted: Sat Jun 04, 2005 1:37 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 04, 2005 2:32 pm     Reply with quote

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








PostPosted: Sat Jun 04, 2005 4:18 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 04, 2005 5:29 pm     Reply with quote

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

View user's profile Send private message Visit poster's website ICQ Number

PostPosted: Sun Jun 05, 2005 3:50 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jun 06, 2005 2:26 pm     Reply with 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
- 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

View user's profile Send private message Visit poster's website ICQ Number

PostPosted: Mon Jun 06, 2005 5:04 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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