|
|
View previous topic :: View next topic |
Author |
Message |
Tagge
Joined: 23 Aug 2005 Posts: 93
|
RTC-4543SA |
Posted: Wed May 13, 2009 10:56 am |
|
|
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
|
|
Posted: Wed May 13, 2009 2:11 pm |
|
|
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
|
|
Posted: Wed May 13, 2009 2:42 pm |
|
|
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
|
|
Posted: Wed May 13, 2009 3:18 pm |
|
|
I agree, but it wasn't up to me to use this chip
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
|
|
Posted: Wed May 13, 2009 3:48 pm |
|
|
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
|
|
Posted: Thu May 14, 2009 3:17 am |
|
|
Hi again, I got it almost working
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
|
|
Posted: Thu May 14, 2009 12:13 pm |
|
|
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
|
|
Posted: Thu May 14, 2009 12:28 pm |
|
|
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
|
|
Posted: Thu May 14, 2009 12:34 pm |
|
|
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
|
|
Posted: Thu May 14, 2009 1:03 pm |
|
|
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
|
|
Posted: Thu May 14, 2009 1:06 pm |
|
|
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
|
|
Posted: Thu May 14, 2009 1:24 pm |
|
|
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
|
|
Posted: Thu May 14, 2009 3:45 pm |
|
|
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
|
|
Posted: Fri May 15, 2009 5:24 am |
|
|
Hi, yes, thanks, I will try it.
But under the mean time, is there any way of building an array of bits?
as
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
|
|
Posted: Fri May 15, 2009 9:04 am |
|
|
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 |
|
|
|
|
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
|