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 CCS Technical Support

RTC-4543SA
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Tagge



Joined: 23 Aug 2005
Posts: 93

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

RTC-4543SA
PostPosted: Wed May 13, 2009 10:56 am     Reply with quote

Hi, has anyone made a driver for this RTC?
Im working on one but do have some trouble, as usually..
Made this far, but aint getting out the right stuff.

Code:
#ifndef RTC_SCLK
#define RTC_SCLK PIN_E6
#define RTC_IO   PIN_E7
#define RTC_WR   PIN_C1
#define RTC_CE   PIN_C0
#endif
void write_rtc(BYTE data, BYTE length)
{
   int8 i=0;
   printf("test write_rtc: %u; length: %u\r\n",data, length); //ok!!
   for(i=0;i<=length;++i) {
      output_bit(RTC_IO, shift_right(&data,1,0) );
      output_high(RTC_SCLK);
      delay_us(2);
      output_low(RTC_SCLK);
      delay_us(2);
   }   
}
//----------------------------
BYTE read_rtc(BYTE length)
{
   BYTE i,data;   

   for(i=0;i<=length;++i) {
      shift_right(&data,1,input(RTC_IO));
      output_high(RTC_SCLK);
      delay_us(2);
      output_low(RTC_SCLK);
      delay_us(2);
   }
   printf("test read rtc data: %u; \r\n",data); //Nok!!   
   return(data);
}
//-----------------------------
int get_bcd(BYTE data)
{
   int nibh;
   int nibl;

   nibh=data/10;
   nibl=data-(nibh*10);

   return((nibh<<4)|nibl);
}

int rm_bcd(BYTE data)
{
   int i;

   i=data;
   data=(i>>4)*10;
   data=data+(i<<4>>4);

   return data;
}
//---------------------------------------------------------------------
void rtc_set_datetime(BYTE min, BYTE hr, BYTE dow, BYTE day, BYTE mth, BYTE year)
{   
   output_high(RTC_CE); //enable rtc
   output_high(RTC_WR); //write enable
   delay_us(10);   
   
   write_rtc(get_bcd(0),7);   //sekunder 0
   write_rtc(get_bcd(min),7); //min 0-59
   write_rtc(get_bcd(hr),7);  //Timmar 0-59
   write_rtc(get_bcd(dow),3); //day of week 1-7
   write_rtc(get_bcd(day),7);   //day 1-31
   write_rtc(get_bcd(mth),7);   //mounth 1-12
   write_rtc(get_bcd(year),7);  //year 0-99 
   
   output_low(RTC_CE); //disable rtc
   output_low(RTC_WR); //disable write
}
//------------------------------------------------------------------------
void rtc_get_date(BYTE& day, BYTE& mth, BYTE& year, BYTE& dow)
{
int8 slask =0;

   output_high(RTC_CE); //enable rtc
   output_low(RTC_WR);  //read enable
   delay_us(10);
   
   slask =(read_rtc(7));slask =(read_rtc(7));slask =(read_rtc(7));
 
   dow = rm_bcd(read_rtc(3));
   day = rm_bcd(read_rtc(7));
   mth = rm_bcd(read_rtc(7));
   year = rm_bcd(read_rtc(7));
   printf("test read_rtc: %u\r\n",year); //nok!!
   
   output_low(RTC_CE); //disable rtc
 
}

void rtc_get_time(BYTE& hr, BYTE& min, BYTE& sec)
{
int8 slask=0;
   output_high(RTC_CE); //enable rtc
   output_low(RTC_WR);  //read enable
   delay_us(10);
   
   sec = rm_bcd(read_rtc(7)); 
   min = rm_bcd(read_rtc(7));   
   hr  = rm_bcd(read_rtc(7));
   output_low(RTC_CE); //disable rtc
   delay_us(10);
   slask=(read_rtc(3));slask=(read_rtc(7));slask=(read_rtc(7));slask=(read_rtc(7));
}
////////////////////////////////////////////7
void set_time(){
BYTE my_in[3]="",answer=0, my_sek=0, my_min=0, my_hour=0, my_dow=0,my_day=0,my_mth=0,my_year=0;

   fprintf(USER,"min:\r\n");
   fgets(my_in,USER);
   my_min=atoi(my_in);
   
   fprintf(USER,"hour:\r\n");
   fgets(my_in,USER);
   my_hour=atoi(my_in);
   
   fprintf(USER,"dow:\r\n");
   fgets(my_in,USER);
   my_dow=atoi(my_in);
   
   fprintf(USER,"day:\r\n");
   fgets(my_in,USER);
   my_day=atoi(my_in);
   
   fprintf(USER,"month:\r\n");
   fgets(my_in,USER);
   my_mth=atoi(my_in);
   
   fprintf(USER,"year:\r\n");
   fgets(my_in,USER);
   my_year=atoi(my_in);
   
   fprintf(USER,"Written:%u:%u:%u:%u:%u:%u\r\n Right Y,N?\r\n",my_min,my_hour,my_dow,my_day,my_mth,my_year);
   do{
   answer=fgetc(USER);
   }while(answer!='Y' && answer!='N');
   if(answer=='Y')
      rtc_set_datetime(my_min, my_hour, my_dow, my_day, my_mth, my_year);
   else fprintf(USER,"Not saved\r\n");
   
   //testa
   rtc_get_time(my_hour,my_min, my_sek);
   fprintf(USER,"Time %u:%u:%u\r\n",my_hour,my_min,my_sek);
   
   rtc_get_date(my_day,my_mth,my_year,my_dow);
   fprintf(USER,"Date %u:%u:%u; %u\r\n",my_day,my_mth,my_year,my_dow);
}
//eof


print from the program in hyperterminal:
test write_rtc: 0; length: 7
test write_rtc: 53; length: 7
test write_rtc: 24; length: 7
test write_rtc: 4; length: 3
test write_rtc: 9; length: 7
test write_rtc: 5; length: 7
test write_rtc: 9; length: 7
test read rtc data: 0;
test read rtc data: 106;
test read rtc data: 48;
test read rtc data: 3;
test read rtc data: 0;
test read rtc data: 0;
test read rtc data: 0;
Time 30:70:0
test read rtc data: 0;
test read rtc data: 106;
test read rtc data: 48;
test read rtc data: 131;
test read rtc data: 18;
test read rtc data: 10;
test read rtc data: 18;
test read_rtc: 12
Date 12:10:12; 83

Any suggestions gladly taken
Thanks/Tagge
Tagge



Joined: 23 Aug 2005
Posts: 93

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

PostPosted: Wed May 13, 2009 2:11 pm     Reply with quote

I think I find one issue when reading the data of the RTC, when writing to and reading from it I have to use 8-bits! altough its only 7 bits of data. It could maybe be done by just let the clock make an extra pulse after the data?
Like
Code:
void write_rtc(BYTE data, BYTE length)
{
   int8 i=0;
   printf("test write_rtc: %u; length: %u\r\n",data, length);
   for(i=0;i<=length;++i) {
      output_bit(RTC_IO, shift_right(&data,1,0) );
      output_high(RTC_SCLK);
      delay_us(2);
      output_low(RTC_SCLK);
      delay_us(2);
   }   
  output_high(RTC_SCLK);
  delay_us(2);
  output_low(RTC_SCLK); 
}

What do you think?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 13, 2009 2:42 pm     Reply with quote

According to the Application manual, it wants 52 clock pulses for a write
cycle. On page 7, it says:
Quote:
Note that during a write operation, 52 bits of data must be input.

http://www.epsontoyocom.co.jp/english/product/RTC/set02/rtc4543sa_sb/index.html
You are only doing 45 bits.


This RTC chip does not have a byte-oriented interface. Modern RTC
chips have standard SPI or i2c interfaces. Why are you using this
strange chip ?
Tagge



Joined: 23 Aug 2005
Posts: 93

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

PostPosted: Wed May 13, 2009 3:18 pm     Reply with quote

I agree, but it wasn't up to me to use this chip Rolling Eyes
I hate it! must be from the time of the roman empire..
And your right, about the 52 bits, but I assume that its enough to just let the clock make a extra cycle? because the eight bit isn't used, only clocked in..
Or maybe it should consist of something, a zero maybe.
its the same thing when reading, I'm trying to throw away the bits that are not of interest.
But do you think the driver would work? I haven't tested with the 52 bits yet.
Is the bcd function right though?
thanks/Tagge
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 13, 2009 3:48 pm     Reply with quote

The application note (which you can download and read) says:
Quote:

Correct write access isn't completed when CE terminal [is] turned into
low [level] on a state of less than 52 bits.

You can't make up your own spec. You have to follow the manufacturer's
documentation.

Quote:
Is the bcd function right though?

The get_bcd() and rm_bcd() functions were copied from the CCS driver
file, ds1302.c, so presumably they should work.
Tagge



Joined: 23 Aug 2005
Posts: 93

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

PostPosted: Thu May 14, 2009 3:17 am     Reply with quote

Hi again, I got it almost working Smile
Its writing allright until the "month", there something goes wrong..
The 8-bit of the month must be a '0' acording to data sheet, it should be 0 anyway as months only are between 1-12..
Strange thing is that months also work, but not if entered between 4-7!!
year doesnt work at all, almost allways 0,1 or +100..
I suspect it could have something to do with the dow byte that is only 4 bits long?? Im sending just a 0 to it, but Im nor sure how its accepted by the write_rtc() function?
Time works fine both write and read.
Code:
void rtc_set_datetime(BYTE min, BYTE hr, BYTE dow, BYTE day, BYTE mth, BYTE year)
{   
   output_high(RTC_CE); //enable rtc
   output_high(RTC_WR); //write enable
   delay_us(10);   
   
   write_rtc(get_bcd(0),8);   //sekunder 0
   write_rtc(get_bcd(min),8); //min 0-59
   write_rtc(get_bcd(hr),8);  //Timmar 0-59
   write_rtc(0,4);//get_bcd(dow),4); //day of week 1-7, dont needed
   write_rtc(get_bcd(day),8);   //day 1-31 OK
   write_rtc(get_bcd(mth),8);   //mounth 1-12 NOK!
   write_rtc(get_bcd(year),8);  //year 0-99 
   //=52 bits
   
   output_low(RTC_CE); //disable rtc
   output_low(RTC_WR); //disable write
}

testing:
Code:
void rtc_get_date(BYTE& day, BYTE& mth, BYTE& year) {
int8 slask =0;
   output_high(RTC_CE); //enable rtc
   output_low(RTC_WR);  //read enable
   delay_us(10);
   
   //THROW AWAY FIRST 28 BITS
   slask =read_rtc(8);slask =read_rtc(8);slask =read_rtc(8);slask = read_rtc(4);
   
   day = rm_bcd(read_rtc(8));//OK
   mth = rm_bcd(read_rtc(8));//NOK
   year = rm_bcd(read_rtc(8));   
   
   output_low(RTC_CE); //disable rtc
 
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 14, 2009 12:13 pm     Reply with quote

Try masking it down, so the bcd function only operates on the valid bits.
Example:
Quote:
mth = rm_bcd(read_rtc(8) & 0x1F);


If that doesn't work, then post a list of the values that you are writing to
each register, and also post what you read back.
Tagge



Joined: 23 Aug 2005
Posts: 93

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

PostPosted: Thu May 14, 2009 12:28 pm     Reply with quote

Hi, thanks,
Tested your suggestion, but no change.
Im trying to write for example:
Written:10:20:4:14:5:9
Right Y,N?
Time 20:10:0 //this is ok
Date 2000:0:14 //only day ok
I found a sort of driver but its not in CCS, that seems to take care of the 4 bit "byte", that is maybe the trouble, it looks like this, some changes made by me, but still a non working code.. Im quite tired, so I havent figured it out all, yet at least..
Code:
void write_rtc_buffer(BYTE *my_buffer, int8 len){
  int8 rem = 0;
  BYTE accu, shift;
     
   output_high(RTC_CE); //enable rtc
   output_high(RTC_WR); //write enable
   delay_us(10);

       for (rem = len; rem > 0; ) {
               for (shift = 0, accu = *my_buffer++;(rem > 0) && (shift < 8);
                    rem--, shift++) {
                       output_bit(RTC_IO,(accu & 0x01)); /* LSB first */
                       output_high(RTC_SCLK);
                       delay_us(10);
                       output_low(RTC_SCLK);
                       delay_us(10);
                       accu >>= 1;
               }
       }

   output_low(RTC_CE); //enable rtc
   output_low(RTC_WR); //write enable

}
//And the writing function:
void rtc_set_all(BYTE min, BYTE hr,BYTE dow, BYTE day, BYTE mth, BYTE year){
BYTE my_buffer[7];
BYTE tmp = 0, sec=0, i=0;

   my_buffer[0]=get_bcd(sec);
   my_buffer[1]=get_bcd(min);
   my_buffer[2]=get_bcd(hr);
   my_buffer[3]=get_bcd(dow);
   tmp=get_bcd(day);
   my_buffer[3]=(tmp&0x0f)<<4;
   my_buffer[4]=(tmp&0xf0)>>4;
   tmp=get_bcd(mth);
   my_buffer[4]=(tmp&0x0f)<<4;
   my_buffer[5]=(tmp&0xf0)>>4;
   tmp=get_bcd(year%100);
   my_buffer[5]=(tmp&0x0f)<<4;
   my_buffer[6]=(tmp&0xf0)>>4;
   write_rtc_buffer(my_buffer,52);
}

What do you think?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 14, 2009 12:34 pm     Reply with quote

Quote:
Written:10:20:4:14:5:9
Right Y,N?
Time 20:10:0 //this is ok
Date 2000:0:14 //only day ok

You are entering the data in a different order than it's displayed,
so it's difficult for me to correlate the input and output values.

Please post a 1:1 list showing the entry value and the output.
Tagge



Joined: 23 Aug 2005
Posts: 93

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

PostPosted: Thu May 14, 2009 1:03 pm     Reply with quote

Ok, entering as:
Code:
 rtc_set_datetime(my_min, my_hour,  my_day, my_mth, my_year);

And the values are:
40:20:4:14:5:9
Code:

void rtc_set_datetime(BYTE min, BYTE hr, BYTE day, BYTE mth, BYTE year)

   output_high(RTC_CE); //enable rtc
   output_high(RTC_WR); //write enable
   delay_us(10);   
   
   write_rtc(0,8);   //sek 0
   write_rtc(get_bcd(min),8); //min 40
   write_rtc(get_bcd(hr),8);  //hour 20
   
   write_rtc(0,4);//get_bcd(dow),4); //day of week 1-7 Not used! just 0
   write_rtc(get_bcd(day),8);   //day 14
   write_rtc(get_bcd(mth),8);   //month 5
   write_rtc(get_bcd(year),8);  //year 9
   delay_ms(1);   
   output_low(RTC_WR); //disable write
   output_low(RTC_CE); //disable rtc
   delay_ms(1);     
}

And the output when read in this case is:
sec = 0;
min = 40
hour =20
day = 14
month = 0
year = 0
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 14, 2009 1:06 pm     Reply with quote

Quote:
Ok, entering as:
Code:
rtc_set_datetime(my_min, my_hour, my_day, my_mth, my_year);

And the values are:
40:20:4:14:5:9

There are 5 parameters in your function, but 6 items in your values list.
Please identify the values.
Tagge



Joined: 23 Aug 2005
Posts: 93

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

PostPosted: Thu May 14, 2009 1:24 pm     Reply with quote

rtc_set_datetime(my_min, my_hour, my_day, my_mth, my_year);
the dow value is only set to 0 in the function rtc_set_datetime()
write_rtc(0,4); //dow
Its asked for in the user interface, but not used further..
therefore seen as the 4 in the user string.

Thanks for your assistance, Im really confused with this one/tagge
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 14, 2009 3:45 pm     Reply with quote

I would get rid of the bcd conversions, and just look at the low-level data.
Strip down your program as much as possible. Send out a data stream
and see what you get back.


There are bugs in your program. For example, the read_rtc() routine
has the possiblity of using a length less than 8 (a full byte). But, you
don't initialize 'data' to 0 before you start shifting bits into it. Suppose
your length is only 4. Then 'data' could have some random value in it,
and 4-bits of the random value would be returned, along with the valid
4 bits. See the correction below.
Quote:
BYTE read_rtc(BYTE length)
{
BYTE i, data;

data = 0; // *** Add this line
for(i=0;i<=length;++i) {
shift_right(&data,1,input(RTC_IO));
output_high(RTC_SCLK);
delay_us(2);
output_low(RTC_SCLK);
delay_us(2);
}
printf("test read rtc data: %u; \r\n",data); //Nok!!
return(data);
}


You may have other bugs that I haven't seen yet. That's why I say just
strip it down as small as you can and test the raw data transfer.
Guest








PostPosted: Fri May 15, 2009 5:24 am     Reply with quote

Hi, yes, thanks, I will try it.
But under the mean time, is there any way of building an array of bits?
as
Code:
int1 buffer[52];

How could it look like? and how could I pass a byte in to 8-bits in that array? and after that be able to send the bits array to the write_rtc() function.. where it has to be clocked in from the seconds LSB first until the years MSb at last..
I think that could solve the problem? then I could pass all bits one by one to the chip.
/tagge
Tagge



Joined: 23 Aug 2005
Posts: 93

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

PostPosted: Fri May 15, 2009 9:04 am     Reply with quote

Im confused about the BCD function, if I write in dec, for ex
Written:37:16:5:15:5:9
And then read it at the rtc_set_datetime() function as hex it says:
In set_date_time:25:10:05:0f:05:09
And thats ok, but then I send the bytes to the bin2bcd function,
Code:
BYTE get_bcd(BYTE data){
   int nibh;
   int nibl;

   nibh=data/10;
   nibl=data-(nibh*10);

   return((nibh<<4)|nibl);   
}

What returns is, bcd in printf as hex:
fprintf(USER,"BCD write_rtc :%x\r\n",data);
To me it seems like its changed back to dec and not to BCD? or am Im cycling.. BCD have 4 bits for 0-9, the fifth bit for tens, 6 for twenties, 7 for forthies and so on..

In BCD write_rtc :00 //ok, in 0, sec
In BCD write_rtc :37 // min its 37 in dec to? should it be 0x25 in bcd(hex)
In BCD write_rtc :16 //hour its 16 in dec to? should be 0x0f in bcd?
In BCD write_rtc :00 //ok 0, dow
In BCD write_rtc :15 //day its 15 in dec to, ok in bcd?
In BCD write_rtc :05 //month its 5 in dec to, ok in bcd?
In BCD write_rtc :09 //year its 9 in dec to, ok in bcd?
Time 16:37:0
Date 2001:1:15
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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