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

Driver RTC MCP79411

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
dpechman



Joined: 04 Dec 2007
Posts: 43

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

Driver RTC MCP79411
PostPosted: Thu Jul 02, 2015 8:11 am     Reply with quote

Code:

////////////////////////////////////////////////////////////////////////////////
///                             MCP79411.h                                   
///                     Driver for Real Time Clock                           
///                                                                         
/// Daniel Pechmann                                                         
///                                                                         
/// Data: 22/05/2012 First Release                                           
///                                                                         
/// rtc_init() - Enable oscillator without clearing the seconds register -   
///                 used when PIC loses power and rtc run from 3V BAT       
///            - Disable squarewave output                                   
///                                                                         
/// rtc_set_date_time(day,mth,year,dow,hour,min,sec)  Set the date/time     
///                                                                         
/// rtc_get_date(day,mth,year,dow)               Get the date               
///                                                                         
/// rtc_get_time(hr,min,sec)                     Get the time               
///                                                                         
/// rtc_get_mac(BYTE &mc5, ..., BYTE &mc0)       Get MAC Address             
///                                                                         
/// rtc_get_powerdown(BYTE &min, ..., BYTE &mth) Get timestamp of powerdown 
///                                                                         
/// rtc_get_powerup(BYTE &min, ..., BYTE &mth)   Get timestamp of powerup   
///                                                                         
/// rtc_set_alarm0(BYTE sec, ..., BYTE mth)      Adjust Alarm0               
///                                                                         
/// rtc_set_alarm1(BYTE sec, ..., BYTE mth)      Adjust Alarm1               
///                                                                         
/// void rtc_write_byte(...)                     Write byte anywhere in rtc
///                                                                         
/// void rtc_read_byte(...)                      Read byte anywhere in rtc   
///                                                                         
////////////////////////////////////////////////////////////////////////////////

#define RTC_SDA  PIN_C4
#define RTC_SCL  PIN_C3

#define  ADDR_EEPROM_WRITE 0xae       //  DEVICE ADDR for EEPROM (writes)   
#define  ADDR_EEPROM_READ  0xaf       //  DEVICE ADDR for EEPROM (reads) 
#define  ADDR_RTCC_WRITE   0xde       //  DEVICE ADDR for RTCC MCHP  (writes)
#define  ADDR_RTCC_READ    0xdf

#define  ADDR_UNIQUE_ID    0xf2

#define  SRAM_PTR          0x20       //  pointer of the SRAM area (RTCC)
#define  ADDR_EEPROM_SR    0xff       //  STATUS REGISTER in the  EEPROM

#define  ADDR_SEC          0x00       //  address of SECONDS      register
#define  ADDR_MIN          0x01       //  address of MINUTES      register
#define  ADDR_HOUR         0x02       //  address of HOURS        register
#define  ADDR_DAY          0x03       //  address of DAY OF WEEK  register
#define  ADDR_STAT         0x03       //  address of STATUS       register
#define  ADDR_DATE         0x04       //  address of DATE         register 
#define  ADDR_MNTH         0x05       //  address of MONTH        register
#define  ADDR_YEAR         0x06       //  address of YEAR         register
#define  ADDR_CTRL         0x07       //  address of CONTROL      register
#define  ADDR_CAL          0x08       //  address of CALIB        register
#define  ADDR_ULID         0x09       //  address of UNLOCK ID    register

#define  ADDR_ALM0SEC      0x0a       //  address of ALARMO SEC   register
#define  ADDR_ALM0MIN      0x0b       //  address of ALARMO MIN   register
#define  ADDR_ALM0HR       0x0c       //  address of ALARMO HOUR  register
#define  ADDR_ALM0CTL      0x0d       //  address of ALARM0 CONTR register
#define  ADDR_ALM0DAT      0x0e       //  address of ALARMO DATE  register
#define  ADDR_ALM0MTH      0x0f       //  address of ALARMO MONTH register

#define  ADDR_ALM1SEC      0x11       //  address of ALARM1 SEC   register
#define  ADDR_ALM1MIN      0x12       //  address of ALARM1 MIN   register
#define  ADDR_ALM1HR       0x13       //  address of ALARM1 HOUR  register
#define  ADDR_ALM1CTL      0x14       //  address of ALARM1 CONTR register
#define  ADDR_ALM1DAT      0x15       //  address of ALARM1 DATE  register
#define  ADDR_ALM1MTH      0x16       //  address of ALARM1 MONTH register
       
#define  ADDR_SAVtoBAT_MIN 0x18       //  address of T_SAVER MIN(VDD->BAT)
#define  ADDR_SAVtoBAT_HR  0x19       //  address of T_SAVER HR (VDD->BAT)
#define  ADDR_SAVtoBAT_DAT 0x1a       //  address of T_SAVER DAT(VDD->BAT)
#define  ADDR_SAVtoBAT_MTH 0x1b       //  address of T_SAVER MTH(VDD->BAT)

#define  ADDR_SAVtoVDD_MIN 0x1c       //  address of T_SAVER MIN(BAT->VDD)
#define  ADDR_SAVtoVDD_HR  0x1d       //  address of T_SAVER HR (BAT->VDD)
#define  ADDR_SAVtoVDD_DAT 0x1e       //  address of T_SAVER DAT(BAT->VDD)
#define  ADDR_SAVtoVDD_MTH 0x1f       //  address of T_SAVER MTH(BAT->VDD)       

#define  START_32KHZ       0x80       //  start crystal: ST = b7 (ADDR_SEC)
#define  LP                0x20       //  mask for the leap year bit(MONTH REG)   
#define  HOUR_12           0x40       //  12 hours format   (ADDR_HOUR)   
#define  PM                0x20       //  post-meridian bit (ADDR_HOUR)
#define  OUT_PIN           0x80       //  = b7 (ADDR_CTRL)
#define  SQWE              0x40       //  SQWE = b6 (ADDR_CTRL)
#define  ALM_NO            0x00       //  no alarm activated        (ADDR_CTRL)
#define  ALM_0             0x10       //  ALARM0 is       activated (ADDR_CTRL)
#define  ALM_1             0x20       //  ALARM1 is       activated (ADDR_CTRL)
#define  ALM_01            0x30       //  both alarms are activated (ADDR_CTRL)
#define  MFP_01H           0x00       //  MFP = SQVAW(01 HERZ)      (ADDR_CTRL) 
#define  MFP_04K           0x01       //  MFP = SQVAW(04 KHZ)       (ADDR_CTRL) 
#define  MFP_08K           0x02       //  MFP = SQVAW(08 KHZ)       (ADDR_CTRL) 
#define  MFP_32K           0x03       //  MFP = SQVAW(32 KHZ)       (ADDR_CTRL) 
#define  MFP_64H           0x04       //  MFP = SQVAW(64 HERZ)      (ADDR_CTRL)
#define  ALMx_POL          0x80       //  polarity of MFP on alarm  (ADDR_ALMxCTL)   
#define  ALMxC_SEC         0x00       //  ALARM compare on SEC      (ADDR_ALMxCTL)             
#define  ALMxC_MIN         0x10       //  ALARM compare on MIN      (ADDR_ALMxCTL)   
#define  ALMxC_HR          0x20       //  ALARM compare on HOUR     (ADDR_ALMxCTL)   
#define  ALMxC_DAY         0x30       //  ALARM compare on DAY      (ADDR_ALMxCTL)   
#define  ALMxC_DAT         0x40       //  ALARM compare on DATE     (ADDR_ALMxCTL)   
#define  ALMxC_ALL         0x70       //  ALARM compare on all param(ADDR_ALMxCTL)   
#define  ALMx_IF           0x08       //  MASK of the ALARM_IF      (ADDR_ALMxCTL)
#define  OSCON             0x20       //  state of the oscillator(running or not)
#define  VBATEN            0x08       //  enable battery for back-up         

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL, FORCE_SW, FAST)

//Prototypes
BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);

// Init Real Time Clock
void rtc_Init(void)
{
   BYTE seconds = 0;

   i2c_start();
   i2c_write(ADDR_RTCC_WRITE);     // WR to RTC
   i2c_write(ADDR_SEC);                // REG 0
   i2c_start();
   i2c_write(ADDR_RTCC_READ);      // RD from RTC
   seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in rtc
   i2c_stop();
   //seconds &= 0x7F;
   seconds |= 0x80; //set to 1 bit 7 of seconds(ST) enabling oscillator
   
   delay_us(3);

   i2c_start();
   i2c_write(ADDR_RTCC_WRITE);      // WR to RTC
   i2c_write(ADDR_SEC);      // REG 0
   i2c_write(bin2bcd(seconds) | 0x80);     // Start oscillator with current "seconds value
   i2c_start();
   i2c_write(ADDR_RTCC_WRITE);      // WR to RTC
   i2c_write(0x07);      // Control Register
   i2c_write(0x80);      // Disable squarewave output pin
   i2c_stop();
}

//function to set datetime
void rtc_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec)
{
  i2c_start();
  i2c_write(ADDR_RTCC_WRITE);      // I2C write address
  i2c_write(ADDR_SEC);             // Point to start writing at REG 0 - Seconds
  i2c_write(bin2bcd(sec) | 0x80 ); // ST ON
  i2c_write(bin2bcd(min));         
  i2c_write(bin2bcd(hr));         
  i2c_write(bin2bcd(dow) | 0x08 ); // VBATEN ON
  i2c_write(bin2bcd(day));         
  i2c_write(bin2bcd(mth));       
  i2c_write(bin2bcd(year));       
  i2c_write(0x80);                 // REG 7 - Disable squarewave output pin
  //i2c_write(0x10);               // REG 4 - turn on with 1Hz the square pin
  i2c_stop();
}

void rtc_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
{
  i2c_start();
  i2c_write(ADDR_RTCC_WRITE);
  i2c_write(0x03);                     // Start at REG 3 - Day of week
  i2c_start();
  i2c_write(ADDR_RTCC_READ);
  dow  = bcd2bin(i2c_read() & 0x07);   // REG 3
  day  = bcd2bin(i2c_read() & 0x3f);   // REG 4
  mth  = bcd2bin(i2c_read() & 0x1f);   // REG 5
  year = bcd2bin(i2c_read(0));         // REG 6
  i2c_stop();
}

void rtc_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
  i2c_start();
  i2c_write(ADDR_RTCC_WRITE);
  i2c_write(0x00);                     // Start at REG 0 - Seconds
  i2c_start();
  i2c_write(ADDR_RTCC_READ);
  sec = bcd2bin(i2c_read() & 0x7f);    //0x7f b01111111
  min = bcd2bin(i2c_read() & 0x7f);    //0x7f
  hr  = bcd2bin(i2c_read(0) & 0x3f);   //0x3f b00111111
  i2c_stop();
}

void rtc_get_mac(BYTE &mc5, BYTE &mc4, BYTE &mc3, BYTE &mc2, BYTE &mc1, BYTE &mc0)
{
  i2c_start();
  i2c_write(ADDR_EEPROM_WRITE);  //0x57
  i2c_write(ADDR_UNIQUE_ID);     // Start point ADDR_UNIQUE_ID
  i2c_start();
  i2c_write(ADDR_EEPROM_READ);
  mc5 = bcd2bin(i2c_read());   
  mc4 = bcd2bin(i2c_read());   
  mc3 = bcd2bin(i2c_read());
  mc2 = bcd2bin(i2c_read());   
  mc1 = bcd2bin(i2c_read()); 
  mc0 = bcd2bin(i2c_read(0));         
  i2c_stop();
}

void rtc_get_powerdown(BYTE &min, BYTE &hr, BYTE &dow, BYTE &date, BYTE &mth)
{
  BYTE tmp;
  i2c_start();
  i2c_write(ADDR_RTCC_WRITE);
  i2c_write(ADDR_SAVtoBAT_MIN);         // Start point ADDR_SAVtoBAT_MIN
  i2c_start();
  i2c_write(ADDR_RTCC_READ);
  min = bcd2bin(i2c_read());   
  hr  = bcd2bin(i2c_read()); 
  date = bcd2bin(i2c_read()& 0x3F);   
  tmp = i2c_read(0); 
  i2c_stop();
  mth = bcd2bin(tmp & 0x0F);
  dow = bcd2bin(tmp & 0xE0);
}

void rtc_get_powerup(BYTE &min, BYTE &hr, BYTE &dow, BYTE &date, BYTE &mth)
{
  BYTE tmp;
  i2c_start();
  i2c_write(ADDR_RTCC_WRITE);
  i2c_write(ADDR_SAVtoVDD_MIN);         // Start point ADDR_SAVtoVDD_MIN
  i2c_start();
  i2c_write(ADDR_RTCC_READ);
  min = bcd2bin(i2c_read());   
  hr  = bcd2bin(i2c_read());   
  date = bcd2bin(i2c_read()& 0x3F);   
  tmp = i2c_read(0); 
  i2c_stop();
  mth = bcd2bin(tmp & 0x0F);
  dow = bcd2bin(tmp & 0xE0); 
}

void rtc_set_alarm0(BYTE sec, BYTE min, BYTE hr, BYTE dow, BYTE day, BYTE mth) 
{
  i2c_start();
  i2c_write(ADDR_RTCC_WRITE);
  i2c_write(ADDR_ALM0SEC);            // Start point ADDR_ALM0SEC
  i2c_start();
  i2c_write(ADDR_RTCC_WRITE);
  i2c_write(bin2bcd(sec));
  i2c_write(bin2bcd(min));
  i2c_write(bin2bcd(hr));
  i2c_write(bin2bcd(dow));
  i2c_write(bin2bcd(day));
  i2c_write(bin2bcd(mth));
  i2c_stop();
}

void rtc_set_alarm1(BYTE sec, BYTE min, BYTE hr, BYTE dow, BYTE day, BYTE mth) 
{
  i2c_start();
  i2c_write(ADDR_RTCC_WRITE);
  i2c_write(ADDR_ALM1SEC);            // Start point ADDR_ALM1SEC
  i2c_start();
  i2c_write(ADDR_RTCC_WRITE);
  i2c_write(bin2bcd(sec));
  i2c_write(bin2bcd(min));
  i2c_write(bin2bcd(hr));
  i2c_write(bin2bcd(dow));
  i2c_write(bin2bcd(day));
  i2c_write(bin2bcd(mth));
  i2c_stop();
}

void rtc_clear_stamp()
{
   BYTE regtmp = 0;

   i2c_start();
   i2c_write(ADDR_RTCC_WRITE);     // WR to RTC
   i2c_write(ADDR_DAY);            // REG 0
   i2c_start();
   i2c_write(ADDR_RTCC_READ);      // RD from RTC
   regtmp = bcd2bin(i2c_read(0));  // le para regtmp o valor do registrador 0x03 no rtc
   i2c_stop();

   regtmp |= 0x10; //set to 1 4th bit of register 0x03 cleaning timestamps
   
   delay_us(3);

   i2c_start();
   i2c_write(ADDR_RTCC_WRITE);      // WR to RTC
   i2c_write(ADDR_DAY);             // REG 0
   i2c_start();
   i2c_write(ADDR_RTCC_WRITE);      // WR to RTC
   i2c_write(regtmp);               // read value + bit 4 set
   i2c_stop(); 
}

BYTE rtc_read_byte(BYTE address)
{
  BYTE tmp;
  i2c_start();
  i2c_write(ADDR_EEPROM_WRITE);
  i2c_write(address);            // Start point to specific address
  i2c_start();
  i2c_write(ADDR_EEPROM_READ);
  tmp  = bcd2bin(i2c_read(0));
  i2c_stop();
  return tmp; 
}

void rtc_write_byte(BYTE address, BYTE value)
{
  i2c_start();
  i2c_write(ADDR_EEPROM_WRITE);
  i2c_write(address);            // Start point to specific address
  i2c_start();
  i2c_write(ADDR_EEPROM_WRITE);
  i2c_write(value);
  i2c_stop();
}

BYTE bin2bcd(BYTE binary_value)
{
   BYTE temp;
   BYTE retval;

   temp = binary_value;
   retval = 0;
   
   if(temp >= 10)
   {
      temp -= 10;
      retval += 0x10;
   }
   else
   {
      retval += temp;
      break;
   }

   return(retval);
}


BYTE bcd2bin(BYTE bcd_value)
{
  BYTE temp;

  temp = bcd_value;
  temp >>= 1;
  temp &= 0x78;
  return(temp + (temp >> 2) + (bcd_value & 0x0f));
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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