Here’s some code to access this device: (at least the RTCC features)
MCP79410.h
#ifdef __cplusplus
extern "C" {
#endif
extern void RTC_init();
extern char* RTC_GetTimeString(); //read time "hh:mm,dd-mm-yyyy"
extern char IsTimeStrFormat(char * ts); //validate TimeString format
extern void RTC_SetFromTimeString(char* ts); //set time "hh:mm,dd-mm-yyyy"
extern void RTC_PutForward1Hour(); //put time forward an hour (i.e -> Daylight Savings)
extern void RTC_PutBack1Hour(); //put time back an hour (i.e-> NON Daylight Savings)
extern char RTC_IsSet(); //has the RTCC been set?
#ifdef __cplusplus
}
#endif
MCP79410.c
#include <mios32.h>
#include <string.h>
#include <time.h>
#include "MCP79410.h"
#define I2CADDR 0x6F
#define VbatEnableReg 3
#define VBATEN 3
#define ST 7
#define reg_seconds 0
#define msk_seconds 0x7F
#define reg_minutes 1
#define reg_hours 2
#define msk_hours 0x3F
#define reg_day 3
#define msk_day 0x07
#define reg_date 4
#define reg_month 5
#define msk_month 0x1F
#define reg_year 6
#define reg_control 0x07
#define SQWE 6
#define OUT 7
#define SRAM_START 0x20
void RTC_WrReg(u8 r,u8 d){
u8 sub[2];
sub[0]=r;
sub[1]=d;
s32 x=MIOS32_IIC_Transfer(0,IIC_Write,I2CADDR<<1,sub,2);
x=MIOS32_IIC_TransferWait(0);
}
u8 RTC_RdReg(u8 r){
u8 d;
d=r;
s32 x=MIOS32_IIC_Transfer(0,IIC_Write,I2CADDR<<1,&d,1);
x=MIOS32_IIC_TransferWait(0);
x=MIOS32_IIC_Transfer(0,IIC_Read,I2CADDR<<1,&d,1);
x= MIOS32_IIC_TransferWait(0);
return d;
}
u8 Int2BCD(int x){ //return integer as two decimal digits
char low=x%10;
char hi=(x/10)<<4;
return hi|low;
}
int BCD2Int(u8 bcd){ //Convert two BCD digits to Integer
int h=10*(bcd>>4);
return h+(bcd&0x0f);
}
void RTC_init(){
char regval;
regval=RTC_RdReg(VbatEnableReg); //read dont change other bitfields
regval|=(1<<VBATEN); //enable backup supply
RTC_WrReg(VbatEnableReg,regval);
regval=RTC_RdReg(reg_seconds); //read dont change other bitfields
regval|=(1<<ST); //start the osc
RTC_WrReg(reg_seconds,regval);
RTC_WrReg(reg_control,((1<<SQWE)|(1<<OUT))); //enable squarewave 1Hz on MF Pin. Requires pullup on MFP
}
char* RTC_GetTimeString(){ //return timestr
static char s[24];
char secs,mins,hrs,date,mth,yr;
secs=RTC_RdReg(reg_seconds);
secs&=msk_seconds;
mins=RTC_RdReg(reg_minutes);
hrs=RTC_RdReg(reg_hours);
hrs&=msk_hours;
date=RTC_RdReg(reg_date);
mth=RTC_RdReg(reg_month);
mth&=msk_month;
yr=RTC_RdReg(reg_year);
sprintf(s,"%02X:%02X,%02X-%02X-20%02X",hrs,mins,date,mth,yr); //TimeStr
return s;
}
char IsTimeStrFormat(char * ts){ //"hh:mm,dd-mm-yyyy"
char result=0;
if (strlen(ts)==16)
result=1;
else{
MIOS32_MIDI_SendDebugMessage("TimeStr format:\"hh:mm,dd-mm-yyyy\" bad length-%d-",strlen(ts));
return 0;
}
if ((ts[2]==':')&&(ts[5]==',')&&(ts[8]=='-')&&(ts[11]=='-'))
result=1;
else{
MIOS32_MIDI_SendDebugMessage("TimeStr format:\"hh:mm,dd-mm-yyyy\" bad format");
return 0;
}
return result;
}
void TimeStr2tm(struct tm* T, char* t){ //fill in struct tm with an input timestr
T->tm_hour=(t[0]-0x30)*10+(t[1]-0x30);
T->tm_min= (t[3]-0x30)*10+(t[4]-0x30);
T->tm_sec=0;
T->tm_mday= (t[6]-0x30)*10+(t[7]-0x30);
T->tm_mon= (t[9]-0x30)*10+(t[10]-0x30)-1; //from 0
T->tm_year= 100+(t[14]-0x30)*10+(t[15]-0x30);
T->tm_wday=0;
T->tm_isdst=0;
}
char RTC_IsSet(){
char yr;
yr=RTC_RdReg(reg_year);
return (yr>0x10); //unset RTC has year==01
}
void RTC_PutForward1Hour(){ //put time forward an hour (i.e -> Daylight Savings)
char hrs=RTC_RdReg(reg_hours);
char x=hrs;
x&=~msk_hours; //clear hours field
hrs&=msk_hours; //clear non hours field(s)
hrs=BCD2Int(hrs);
++hrs; //inc hours as integer
if (hrs==24) hrs=0;
hrs=Int2BCD(hrs);//store as BCD
hrs|=x; //set control bits
RTC_WrReg(reg_hours,hrs);
};
void RTC_PutBack1Hour(){ //put time back an hour (i.e-> NON Daylight Savings)
u8 hrs=RTC_RdReg(reg_hours);
u8 x=hrs;
x&=~msk_hours; //clear hours field
hrs&=msk_hours; //clear non hours field(s)
hrs=BCD2Int(hrs);
if (hrs==0)
hrs=23;
else
--hrs; //dec hours
hrs=Int2BCD(hrs);//store as BCD
hrs|=x; //set control bits
RTC_WrReg(reg_hours,hrs);
};
void RTC_SetTime(struct tm* T){
char x,mins,hrs,date,mth,yr;
mins=Int2BCD(T->tm_min); //load and convert to BCD
hrs=Int2BCD(T->tm_hour);
date=Int2BCD(T->tm_mday);
mth=Int2BCD(T->tm_mon+1); //months start from 0
yr=Int2BCD(T->tm_year-100); //year counted from 1900
//dont worry about seconds
RTC_WrReg(reg_minutes,mins);
x=RTC_RdReg(reg_hours); //read all
x&=~msk_hours; //clear data bitfields
hrs|=x; //set control bits
RTC_WrReg(reg_hours,hrs);
RTC_WrReg(reg_date,date);
x=RTC_RdReg(reg_month);
x&=~msk_month;
mth|=x;
RTC_WrReg(reg_month,mth);
RTC_WrReg(reg_year,yr);
}
void RTC_SetFromTimeString(char* ts){ //"hh:mm,dd-mm-yyyy"
struct tm T;
TimeStr2tm(&T,ts);
RTC_SetTime(&T);
}