libraries / Mitov / Mitov_RTC_DS3231.hon commit Added link to project report (97a3ba0)
   1////////////////////////////////////////////////////////////////////////////////
   2//                                                                            //
   3//     This software is supplied under the terms of a license agreement or    //
   4//     nondisclosure agreement with Mitov Software and may not be copied      //
   5//     or disclosed except in accordance with the terms of that agreement.    //
   6//         Copyright(c) 2002-2016 Mitov Software. All Rights Reserved.        //
   7//                                                                            //
   8////////////////////////////////////////////////////////////////////////////////
   9
  10#ifndef _MITOV_RTC_DS3231_h
  11#define _MITOV_RTC_DS3231_h
  12
  13#include <Mitov.h>
  14#include <Mitov_Basic_RTC.h>
  15
  16namespace Mitov
  17{
  18//---------------------------------------------------------------------------
  19//      enum DS3231ClockFrequency { rtc3231fDisabled, rtc3231f1Hz, rtc3231f1024Hz, rtc3231f4096Hz, rtc3231f8192Hz };
  20//---------------------------------------------------------------------------
  21        class RTC_DS3231 : public BasicHaltRTC
  22        {
  23                typedef BasicHaltRTC inherited;
  24
  25                enum Register 
  26                {
  27                        kSecondReg  = 0,
  28                        kMinuteReg  = 1,
  29                        kHourReg    = 2,
  30                        kDayReg     = 3,
  31                        kDateReg    = 4,
  32                        kMonthReg   = 5,
  33                        kYearReg    = 6,
  34                        kControlReg = 0xE
  35//                      kClockReg       = 7,
  36
  37                        // The RAM register space follows the clock register space.
  38//                      kRamAddress0     = 8
  39                };
  40
  41                const uint8_t   DS3231_ADDRESS  = 0x68;
  42
  43        protected:
  44                Mitov::TDateTime FLastDateTime;
  45
  46        protected:
  47                uint8_t readRegister(const uint8_t reg) 
  48                {
  49                        Wire.beginTransmission(DS3231_ADDRESS);
  50                        Wire.write( reg );      
  51                        Wire.endTransmission();
  52
  53                        Wire.requestFrom(DS3231_ADDRESS, (uint8_t)1 );
  54
  55                        return Wire.read();
  56                }
  57
  58                void writeRegister( const uint8_t reg, const uint8_t value ) 
  59                {
  60                        Wire.beginTransmission(DS3231_ADDRESS);
  61                        Wire.write( reg );      
  62                        Wire.write( value );    
  63                        Wire.endTransmission();
  64                }
  65
  66                uint8_t hourFromRegisterValue(const uint8_t value) 
  67                {
  68                        uint8_t adj;
  69                        if (value & 128)  // 12-hour mode
  70                                adj = 12 * ((value & 32) >> 5);
  71
  72                        else           // 24-hour mode
  73                                adj = 10 * ((value & (32 + 16)) >> 4);
  74
  75                        return (value & 15) + adj;
  76                }
  77
  78                virtual void ReadTime()
  79                {
  80                        if( ! OutputPin.IsConnected() )
  81                                return;
  82
  83                        Wire.beginTransmission(DS3231_ADDRESS);
  84                        Wire.write((byte)0);    
  85                        Wire.endTransmission();
  86
  87                        Wire.requestFrom(DS3231_ADDRESS, (byte)7);
  88                        uint16_t ASecond = FromBcdToDec(Wire.read() & 0x7F);
  89                        uint16_t AMinute = FromBcdToDec(Wire.read());
  90                        uint16_t AHour = hourFromRegisterValue( Wire.read() );
  91                        uint16_t ADay = Wire.read();
  92                        uint16_t ADate = FromBcdToDec(Wire.read());
  93                        uint16_t AMonth = FromBcdToDec(Wire.read());
  94                        uint16_t AYear = FromBcdToDec(Wire.read()) + 2000;
  95
  96                        Mitov::TDateTime ADateTime;
  97
  98                        if( ADateTime.TryEncodeDateTime( AYear, AMonth, ADate, AHour, AMinute, ASecond, 0 ))
  99                        {
 100                                if( FLastDateTime != ADateTime )
 101                                {
 102                                        FLastDateTime = ADateTime;
 103                                        OutputPin.Notify( &ADateTime );
 104                                }
 105                        }
 106
 107                }
 108
 109                virtual void UpdateHalt()
 110                {
 111                        uint8_t sec = readRegister( kSecondReg );
 112
 113                        sec &= ~(1 << 7);
 114                        sec |= ( ( Halt & 1 ) << 7 );
 115                        writeRegister( kSecondReg, sec );
 116                }
 117
 118/*
 119                void UpdateClockFrequency()
 120                {
 121                        const uint8_t CValues [] = { 0x00, 0x80, 0x40, 0x41, 0x42, 0x43 };
 122
 123                        uint8_t AValue = readRegister( kControlReg );
 124
 125                        sec &= ~(1 << 7);
 126                        sec |= ( ( Halt & 1 ) << 7 );
 127                        writeRegister( kSecondReg, sec );
 128
 129                        writeRegister( kControlReg, CValues[ ClockFrequency ] );
 130                }
 131*/
 132        protected:
 133                virtual void DoSetReceive( void *_Data )
 134                {
 135                        Mitov::TDateTime &ADateTime = *(Mitov::TDateTime *)_Data;
 136
 137                        uint16_t AYear;
 138                        uint16_t AMonth;
 139                        uint16_t ADay;
 140                        uint16_t AWeekDay;
 141                        uint16_t AHour;
 142                        uint16_t AMinute;
 143                        uint16_t ASecond;
 144                        uint16_t AMilliSecond;
 145                        ADateTime.DecodeDateTime( AYear, AMonth, ADay, AWeekDay, AHour, AMinute, ASecond, AMilliSecond );
 146
 147                        Wire.beginTransmission(DS3231_ADDRESS);
 148                        Wire.write((byte)0); // start at location 0
 149
 150                        Wire.write( ( ( Halt & 1 ) << 7 ) | FromDecToBcd( ASecond ));
 151                        Wire.write(FromDecToBcd( AMinute ));
 152                        Wire.write(FromDecToBcd( AHour ));
 153                        Wire.write(FromDecToBcd( AWeekDay ));
 154                        Wire.write(FromDecToBcd( ADay ));
 155                        Wire.write(FromDecToBcd( AMonth ));
 156                        Wire.write(FromDecToBcd( AYear - 2000));
 157
 158                        Wire.endTransmission();
 159                }
 160
 161        protected:
 162                virtual void SystemInit()
 163                {
 164                        UpdateHalt();
 165//                      UpdateClockFrequency();
 166                        inherited::SystemInit();
 167                }
 168
 169        public:
 170                RTC_DS3231()// :
 171//                      ClockFrequency( rtc3231fDisabled )
 172                {
 173                }
 174        };
 175}
 176
 177#endif