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

i2c problem with M41T81S and oscillator fail bit

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



Joined: 05 Apr 2011
Posts: 12

View user's profile Send private message

i2c problem with M41T81S and oscillator fail bit
PostPosted: Tue May 10, 2011 2:49 pm     Reply with quote

Hi, I am using the i2C functions for the first time and am having a problem clearing the OF bit of the M41T81S rtc when the module is first booted up and it is set. Does anyone have experience of this, who might be able to spot an error? I am using the PIC 18LF46J11. Here is my test code:

Code:

#include <18LF46J11.h>         
#include <string.h>
#include <stdlib.h>

#fuses HS,NOWDT

#use DELAY(crystal=4000000)

#PIN_SELECT U2TX=PIN_B4
#PIN_SELECT U2RX=PIN_B5
#use rs232(UART2, baud=9600, ERRORS, STREAM=PC)

#define TRISA_VAL   0x02     
#define TRISB_VAL   0x2F     
#define TRISD_VAL   0x20 
#define TRISE_VAL   0x00   

#define I2C_SCL   PIN_C3
#define I2C_SDA   PIN_C4

#define RTC_DEVICE_READ  0xD0
#define RTC_DEVICE_WRITE 0xD1

#define RTC_STOP_BIT_REG 0x01
#define RTC_SEC_REG      0x01
#define RTC_MIN_REG      0x02
#define RTC_HOUR_REG     0x03
#define RTC_DOW_REG      0x04
#define RTC_DAY_REG      0x05
#define RTC_MONTH_REG    0x06
#define RTC_YEAR_REG     0x07
#define RTC_HALT_BIT_REG 0x0c
#define RTC_FLAGS_REG    0x0F
#define BOOL short          // 'short' is very short (1 bit) in this compiler

#use I2C(MASTER, SDA=PIN_C4, SCL=PIN_C3, restart_wdt)

void rtc_init();
bool rtc_check_osc_failure();
void rtc_start_osc_restart();
void rtc_finish_osc_restart();
byte read_ext_rtc(byte address);
void write_ext_rtc(byte address, byte data);
 
void main(void)
{
  fprintf(PC,"Hello World: Booting Up\r\n");   
  delay_ms(1000);

  rtc_init();

  while (1)
  {
    if (rtc_check_osc_failure() == true)
    {
      fprintf(PC,"RTCLOCK: Oscillator fail flag set - clearing\r\n");
      rtc_start_osc_restart();
      delay_ms(4000);
      rtc_finish_osc_restart();
      // now check again
      if (rtc_check_osc_failure() == true)
      {
       fprintf(PC,"RTCLOCK: Oscillator FAILED to restart\r\n");
      }
      else
      {
        fprintf(PC,"RTCLOCK: Oscillator fail flag ok\r\n");
      }
    }
    else
    {
      fprintf(PC,"RTCLOCK: Oscillator fail flag ok\r\n");
    }
  }
}


void rtc_init() {
   output_float(I2C_SCL);
   output_float(I2C_SDA);
}

bool rtc_check_osc_failure()
{
  byte flags;
  byte oscill_fail_flag;

  flags = read_ext_rtc(RTC_FLAGS_REG);  // flags including Oscillator Fail bit
  oscill_fail_flag = (flags&0x04);
  if (oscill_fail_flag > 0)
  {
    return true;
  }
  else
  {
    return false;
  }
}

void rtc_start_osc_restart()
{   
  byte temp_data;

  // the oscillator has failed, so go to restart sequence which is
  // Write '1' to Stop bit, then write '0' to stop bit, then wait 4 secs, then set OF (oscillator fail) bit to 0
  temp_data = read_ext_rtc(RTC_STOP_BIT_REG);  // Read the byte at the address for the stop bit
  temp_data = temp_data|0x80;  // Set bit 7 (the stop bit) to 0
  write_ext_rtc(RTC_STOP_BIT_REG,temp_data);
  // now set the stop bit to 1
  temp_data = temp_data&0x7F;  // Set bit 7 (the stop bit) to 1
  write_ext_rtc(RTC_STOP_BIT_REG,temp_data);



void rtc_finish_osc_restart()
{
  byte flags;

  // Set the OF flag to 0
  // first read flags
  flags = read_ext_rtc(RTC_FLAGS_REG);
  // now set OF bit to 0
  flags = flags&0xFB;
  // now write flags to rtc
  write_ext_rtc(RTC_FLAGS_REG,flags);
}



bool ext_rtc_ready()
{
   int1 ack;
   i2c_start();            // If the write command is acknowledged,
   ack = i2c_write(RTC_DEVICE_READ);  // then the device is ready.
   i2c_stop();
   return !ack;
}


byte read_ext_rtc(byte address)
{
   byte data;

   while(!ext_rtc_ready());
   i2c_start();
   i2c_write(RTC_DEVICE_READ);  // D is device address
   i2c_write(address); 
   i2c_start();
   i2c_write(RTC_DEVICE_WRITE);  // set device to read
   data=i2c_read(0);
   i2c_stop();
   return (data);
}


void write_ext_rtc(byte address, byte data)
{
   while(!ext_rtc_ready());
   i2c_start();
   i2c_write(RTC_DEVICE_READ);
   i2c_write(address);
   i2c_write(data);
   i2c_stop();
}


I get the following output:

Hello World: Booting Up
RTCLOCK: Oscillator fail flag set - clearing
RTCLOCK: Oscillator FAILED to restart
RTCLOCK: Oscillator fail flag set - clearing
RTCLOCK: Oscillator FAILED to restart
RTCLOCK: Oscillator fail flag set - clearing
RTCLOCK: Oscillator FAILED to restart
RTCLOCK: Oscillator fail flag set - clearing
RTCLOCK: Oscillator FAILED to restart etc.

Thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue May 10, 2011 7:54 pm     Reply with quote

The M41T81S data sheet says this:
Quote:

Oscillator fail detection

If the oscillator fail bit (OF) is internally set to '1,' this indicates that the
oscillator has either stopped, or was stopped for some period of time and
can be used to judge the validity of the clock and date data.

In the event the OF bit is found to be set to '1' at any time other than the
initial power-up, the STOP bit (ST) should be written to a '1,' then
immediately reset to '0.' This will restart the oscillator.

The following conditions can cause the OF bit to be set:

● The first time power is applied (defaults to a '1' on power-up).
● The voltage present on V CC is insufficient to support oscillation.
● The ST bit is set to '1.'
● External interference of the crystal.

The OF bit will remain set to '1' until written to logic '0'. The oscillator
must start and have run for at least 4 seconds before attempting
to reset the OF bit to '0.'
magic_mauve



Joined: 05 Apr 2011
Posts: 12

View user's profile Send private message

PostPosted: Wed May 11, 2011 1:50 am     Reply with quote

Thank you for your reply. I see you have highlighted the note that you need to wait 4 secs and then set the OF to '0'. I believe I have done this with:

delay_ms(4000);
rtc_finish_osc_restart();

The rtc_finish_osc_restart() function sets the OF to 0.

Are you saying that this is not correct?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 11, 2011 12:55 pm     Reply with quote

You're right. I skimmed your program too quickly and I missed that part.
I'll look more closely at it.

Describe the external hardware connections to the RTC chip. Do you
have the external 32.768 KHz watch crystal, and the backup battery ?
What is the Vdd voltage of the PIC and the RTC chip ? What is the size
of the pullup resistors on the i2c bus ?
magic_mauve



Joined: 05 Apr 2011
Posts: 12

View user's profile Send private message

PostPosted: Fri May 13, 2011 3:07 am     Reply with quote

Just to let you know, I discovered the crystal had been been positioned the wrong way around which explains a lot! All is working now. Many thanks
Sinalux



Joined: 17 May 2011
Posts: 2

View user's profile Send private message

PostPosted: Tue May 17, 2011 5:12 pm     Reply with quote

Hello,

I'm having the same problem. Can you tell me if you're using a 32.767 kHz crystal? What do you mean with "crystal had been positioned the wrong way around"?
_________________
Tks

Sinalux
magic_mauve



Joined: 05 Apr 2011
Posts: 12

View user's profile Send private message

Crystal
PostPosted: Wed May 18, 2011 1:40 am     Reply with quote

There is a 32.768Khz crystal connected, it is an ABS13. I'm not the hardware engineer, but the crystal has a slight slope at one end and it had been positioned on the board around the wrong way, i.e. with the slope at the wrong end.
Ttelmah



Joined: 11 Mar 2010
Posts: 19339

View user's profile Send private message

PostPosted: Wed May 18, 2011 5:01 am     Reply with quote

In your case the way round matters.
A crystal is a 2pin component.
The ABS13 version comes in a SMD package, with four pins. The actual crystal being across pins 1 and 4. Put it in the wrong way round, and you will be connecting your circuit to pins 2 and 3, and no actual connection will be made to the internal crystal!.....
So in this package 'direction matters'. For 99.9% of crystals, it doesn't.

Best Wishes
Sinalux



Joined: 17 May 2011
Posts: 2

View user's profile Send private message

PostPosted: Wed May 18, 2011 3:45 pm     Reply with quote

Hi!
I just found that my problem is on i2c bus, not the crystal!! My uC always detect i2c bus collision. Anyone experienced something like this?
_________________
Tks

Sinalux
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