libraries / Mitov / Mitov_RTC_DS1307.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_DS1307_h
  11#define _MITOV_RTC_DS1307_h
  12
  13#include <Mitov.h>
  14#include <Mitov_Basic_RTC.h>
  15
  16namespace Mitov
  17{
  18//---------------------------------------------------------------------------
  19        enum DS1307ClockFrequency { rtc1307fDisabledLow, rtc1307fDisabledHigh, rtc1307f1Hz, rtc1307f4096Hz, rtc1307f8192Hz, rtc1307f32768Hz };
  20//---------------------------------------------------------------------------
  21        class RTC_DS1307 : 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                        kClockReg       = 7,
  35
  36                        // The RAM register space follows the clock register space.
  37                        kRamAddress0     = 8
  38                };
  39
  40                const uint8_t   DS1307_ADDRESS = 0x68;
  41
  42        public:
  43                DS1307ClockFrequency    ClockFrequency : 3;
  44
  45        public:
  46                void SetClockFrequency( DS1307ClockFrequency AValue )
  47                {
  48                        if( ClockFrequency == AValue )
  49                                return;
  50
  51                        ClockFrequency = AValue;
  52                        UpdateClockFrequency();
  53                }
  54
  55        protected:
  56                Mitov::TDateTime FLastDateTime;
  57
  58        protected:
  59                uint8_t readRegister(const uint8_t reg) 
  60                {
  61                        Wire.beginTransmission(DS1307_ADDRESS);
  62                        Wire.write( reg );      
  63                        Wire.endTransmission();
  64
  65                        Wire.requestFrom(DS1307_ADDRESS, (uint8_t)1 );
  66
  67                        return Wire.read();
  68                }
  69
  70                void writeRegister( const uint8_t reg, const uint8_t value ) 
  71                {
  72                        Wire.beginTransmission(DS1307_ADDRESS);
  73                        Wire.write( reg );      
  74                        Wire.write( value );    
  75                        Wire.endTransmission();
  76                }
  77
  78                uint8_t hourFromRegisterValue(const uint8_t value) 
  79                {
  80                        uint8_t adj;
  81                        if (value & 128)  // 12-hour mode
  82                                adj = 12 * ((value & 32) >> 5);
  83
  84                        else           // 24-hour mode
  85                                adj = 10 * ((value & (32 + 16)) >> 4);
  86
  87                        return (value & 15) + adj;
  88                }
  89
  90                void UpdateClockFrequency()
  91                {
  92                        const uint8_t CValues [] = { 0x00, 0x80, 0x40, 0x41, 0x42, 0x43 };
  93                        writeRegister( kClockReg, CValues[ ClockFrequency ] );
  94                }
  95
  96                virtual void ReadTime()
  97                {
  98                        if( ! OutputPin.IsConnected() )
  99                                return;
 100
 101                        Wire.beginTransmission(DS1307_ADDRESS);
 102                        Wire.write((byte)0);    
 103                        Wire.endTransmission();
 104
 105                        Wire.requestFrom(DS1307_ADDRESS, (byte)7);
 106                        uint16_t ASecond = FromBcdToDec(Wire.read() & 0x7F);
 107                        uint16_t AMinute = FromBcdToDec(Wire.read());
 108                        uint16_t AHour = hourFromRegisterValue( Wire.read() );
 109                        uint16_t ADay = Wire.read();
 110                        uint16_t ADate = FromBcdToDec(Wire.read());
 111                        uint16_t AMonth = FromBcdToDec(Wire.read());
 112                        uint16_t AYear = FromBcdToDec(Wire.read()) + 2000;
 113
 114                        Mitov::TDateTime ADateTime;
 115
 116                        if( ADateTime.TryEncodeDateTime( AYear, AMonth, ADate, AHour, AMinute, ASecond, 0 ))
 117                        {
 118                                if( FLastDateTime != ADateTime )
 119                                {
 120                                        FLastDateTime = ADateTime;
 121                                        OutputPin.Notify( &ADateTime );
 122                                }
 123                        }
 124
 125                }
 126
 127                virtual void UpdateHalt()
 128                {
 129                        uint8_t sec = readRegister( kSecondReg );
 130
 131                        sec &= ~(1 << 7);
 132                        sec |= ( ( Halt & 1 ) << 7 );
 133                        writeRegister( kSecondReg, sec );
 134                }
 135
 136        protected:
 137                virtual void DoSetReceive( void *_Data )
 138                {
 139//                      if( WriteProtect )
 140//                              return;
 141
 142                        Mitov::TDateTime &ADateTime = *(Mitov::TDateTime *)_Data;
 143
 144                        uint16_t AYear;
 145                        uint16_t AMonth;
 146                        uint16_t ADay;
 147                        uint16_t AWeekDay;
 148                        uint16_t AHour;
 149                        uint16_t AMinute;
 150                        uint16_t ASecond;
 151                        uint16_t AMilliSecond;
 152                        ADateTime.DecodeDateTime( AYear, AMonth, ADay, AWeekDay, AHour, AMinute, ASecond, AMilliSecond );
 153
 154                        Wire.beginTransmission(DS1307_ADDRESS);
 155                        Wire.write((byte)0); // start at location 0
 156
 157                        Wire.write( ( ( Halt & 1 ) << 7 ) | FromDecToBcd( ASecond ));
 158                        Wire.write(FromDecToBcd( AMinute ));
 159                        Wire.write(FromDecToBcd( AHour ));
 160                        Wire.write(FromDecToBcd( AWeekDay ));
 161                        Wire.write(FromDecToBcd( ADay ));
 162                        Wire.write(FromDecToBcd( AMonth ));
 163                        Wire.write(FromDecToBcd( AYear - 2000));
 164
 165                        Wire.endTransmission();
 166                }
 167
 168        protected:
 169                virtual void SystemInit()
 170                {
 171                        UpdateHalt();
 172                        UpdateClockFrequency();
 173                        inherited::SystemInit();
 174                }
 175
 176        public:
 177                RTC_DS1307() :
 178                        ClockFrequency( rtc1307fDisabledLow )
 179                {
 180                }
 181        };
 182}
 183
 184#endif