//----------------------------------------------------------------------------
///
/// \brief support for I2C-RTC MCP7940N
///
/// https://www.mouser.de/datasheet/2/268/25010A-71550.pdf
///
/// \author Maximilian Seesslen
///
//----------------------------------------------------------------------------


#include <biwak/mcp7940.hpp>


int CMcp7940::getDate(int &year, int &month, int &day) const
{
   int val;

   i2cReadData(REG_RTCYEAR, &val, 1);
   year=bcd2dec( val& 0xFF ) + 2000;

   i2cReadData(REG_RTCMTH, &val, 1);
   month=bcd2dec( val& 0x1F );

   i2cReadData(REG_RTCDATE, &val, 1);
   day=bcd2dec( val& 0x3F );

   return(0);
}

int CMcp7940::getTime(int &hour, int &minute, int &sec) const
{
   int val;

   i2cReadData(REG_RTCSEC, &val, 1);
   sec=bcd2dec( val& 0x7F );

   i2cReadData(REG_RTCMIN, &val, 1);
   minute=bcd2dec( val& 0x7F );

   i2cReadData(REG_RTCHOUR, &val, 1);
   hour=bcd2dec( val& 0x3F );

   return(0);
}

int CMcp7940::setDate(int year, int month, int day) const
{
   int val;
   int sta;

   sta=i2cReadData(REG_RTCYEAR, &val, 1);
   lAssert(sta==0);
   val&=~REG_YEARMSK;
   val|=dec2bcd(year-2000);
   sta=i2cWriteData(REG_RTCYEAR, &val, 1);
   lAssert(sta==0);

   sta=i2cReadData(REG_RTCMTH, &val, 1);
   lAssert(sta==0);
   val&=~REG_MONTHMSK;
   val|=dec2bcd(month);
   sta=i2cWriteData(REG_RTCMTH, &val, 1);
   lAssert(sta==0);

   sta=i2cReadData(REG_RTCDATE, &val, 1);
   lAssert(sta==0);
   val&=~REG_DAYMSK;
   val|=dec2bcd(day);
   sta=i2cWriteData(REG_RTCDATE, &val, 1);
   lAssert(sta==0);
   
   enable();

   return(0);
}

int CMcp7940::setTime(int hour, int minute, int sec) const
{
   int val;

   i2cReadData(REG_RTCSEC, &val, 1);
   val&=~REG_SECMSK;
   val|=dec2bcd(sec);
   i2cWriteData(REG_RTCSEC, &val, 1);

   i2cReadData(REG_RTCMIN, &val, 1);
   val&=~REG_MINMSK;
   val|=dec2bcd(minute);
   i2cWriteData(REG_RTCMIN, &val, 1);

   i2cReadData(REG_RTCHOUR, &val, 1);
   val&=~REG_HOURMSK;
   val|=dec2bcd(hour);
   i2cWriteData(REG_RTCHOUR, &val, 1);
   enable();

   return(0);
}

int CMcp7940::dump() const
{
   char seconds;
   int sta;

   for(int i1=0; i1<0xA; i1++)
   {
      sta=i2cReadData(i1, &seconds, 1);
      printf("data 0x%02X: 0x%02X (%d)\n", i1, seconds, sta);
   }
   return(0);
}

int CMcp7940::getDate() const
{
   int val;

   i2cReadData(REG_RTCSEC, &val, 1);
   int sec=bcd2dec( val& 0x7F );
   i2cReadData(REG_RTCMIN, &val, 1);
   int min=bcd2dec( val& 0x7F );
   i2cReadData(REG_RTCHOUR, &val, 1);
   int hour=bcd2dec( val& 0x3F );

   i2cReadData(REG_RTCYEAR, &val, 1);
   int year=bcd2dec( val& 0xFF ) + 2000;
   i2cReadData(REG_RTCMTH, &val, 1);
   int month=bcd2dec( val& 0x1F );
   i2cReadData(REG_RTCDATE, &val, 1);
   int day=bcd2dec( val& 0x3F );

   printf("Time: %d:%d:%d\n", hour, min, sec);
   printf("Date: %d.%d.%d\n", day, month, year);

   return(0);
}

void CMcp7940::hwToRtc() const
{
   int year, month, day;
   int hour, min, sec;
   getDate(year, month, day);
   getTime(hour, min, sec);
   m_rtc.setDate(year, month, day);
   m_rtc.setTime(hour, min, sec);
}

void CMcp7940::rtcToHw() const
{
   int year, month, day;
   int hour, min, sec;
   m_rtc.getDate(year, month, day);
   m_rtc.getTime(hour, min, sec);
   setDate(year, month, day);
   setTime(hour, min, sec);
}


//---fin----------------------------------------------------------------------
