You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
5.7 KiB
240 lines
5.7 KiB
/* |
|
* ds1302.c: |
|
* Real Time clock |
|
* |
|
* Copyright (c) 2013 Gordon Henderson. |
|
*********************************************************************** |
|
* This file is part of wiringPi: |
|
* https://projects.drogon.net/raspberry-pi/wiringpi/ |
|
* |
|
* wiringPi is free software: you can redistribute it and/or modify |
|
* it under the terms of the GNU Lesser General Public License as published by |
|
* the Free Software Foundation, either version 3 of the License, or |
|
* (at your option) any later version. |
|
* |
|
* wiringPi is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU Lesser General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU Lesser General Public License |
|
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>. |
|
*********************************************************************** |
|
*/ |
|
|
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <stdint.h> |
|
#include <stdarg.h> |
|
|
|
#include <wiringPi.h> |
|
|
|
#include "ds1302.h" |
|
|
|
// Register defines |
|
|
|
#define RTC_SECS 0 |
|
#define RTC_MINS 1 |
|
#define RTC_HOURS 2 |
|
#define RTC_DATE 3 |
|
#define RTC_MONTH 4 |
|
#define RTC_DAY 5 |
|
#define RTC_YEAR 6 |
|
#define RTC_WP 7 |
|
#define RTC_TC 8 |
|
#define RTC_BM 31 |
|
|
|
|
|
// Locals |
|
|
|
static int dPin, cPin, sPin ; |
|
|
|
/* |
|
* dsShiftIn: |
|
* Shift a number in from the chip, LSB first. Note that the data is |
|
* sampled on the trailing edge of the last clock, so it's valid immediately. |
|
********************************************************************************* |
|
*/ |
|
|
|
static unsigned int dsShiftIn (void) |
|
{ |
|
uint8_t value = 0 ; |
|
int i ; |
|
|
|
pinMode (dPin, INPUT) ; delayMicroseconds (1) ; |
|
|
|
for (i = 0 ; i < 8 ; ++i) |
|
{ |
|
value |= (digitalRead (dPin) << i) ; |
|
digitalWrite (cPin, HIGH) ; delayMicroseconds (1) ; |
|
digitalWrite (cPin, LOW) ; delayMicroseconds (1) ; |
|
} |
|
|
|
return value; |
|
} |
|
|
|
|
|
/* |
|
* dsShiftOut: |
|
* A normal LSB-first shift-out, just slowed down a bit - the Pi is |
|
* a bit faster than the chip can handle. |
|
********************************************************************************* |
|
*/ |
|
|
|
static void dsShiftOut (unsigned int data) |
|
{ |
|
int i ; |
|
|
|
pinMode (dPin, OUTPUT) ; |
|
|
|
for (i = 0 ; i < 8 ; ++i) |
|
{ |
|
digitalWrite (dPin, data & (1 << i)) ; delayMicroseconds (1) ; |
|
digitalWrite (cPin, HIGH) ; delayMicroseconds (1) ; |
|
digitalWrite (cPin, LOW) ; delayMicroseconds (1) ; |
|
} |
|
} |
|
|
|
|
|
/* |
|
* ds1302regRead: ds1302regWrite: |
|
* Read/Write a value to an RTC Register or RAM location on the chip |
|
********************************************************************************* |
|
*/ |
|
|
|
static unsigned int ds1302regRead (const int reg) |
|
{ |
|
unsigned int data ; |
|
|
|
digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ; |
|
dsShiftOut (reg) ; |
|
data = dsShiftIn () ; |
|
digitalWrite (sPin, LOW) ; delayMicroseconds (1) ; |
|
|
|
return data ; |
|
} |
|
|
|
static void ds1302regWrite (const int reg, const unsigned int data) |
|
{ |
|
digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ; |
|
dsShiftOut (reg) ; |
|
dsShiftOut (data) ; |
|
digitalWrite (sPin, LOW) ; delayMicroseconds (1) ; |
|
} |
|
|
|
|
|
/* |
|
* ds1302rtcWrite: ds1302rtcRead: |
|
* Writes/Reads the data to/from the RTC register |
|
********************************************************************************* |
|
*/ |
|
|
|
unsigned int ds1302rtcRead (const int reg) |
|
{ |
|
return ds1302regRead (0x81 | ((reg & 0x1F) << 1)) ; |
|
} |
|
|
|
void ds1302rtcWrite (int reg, unsigned int data) |
|
{ |
|
ds1302regWrite (0x80 | ((reg & 0x1F) << 1), data) ; |
|
} |
|
|
|
|
|
/* |
|
* ds1302ramWrite: ds1302ramRead: |
|
* Writes/Reads the data to/from the RTC register |
|
********************************************************************************* |
|
*/ |
|
|
|
unsigned int ds1302ramRead (const int addr) |
|
{ |
|
return ds1302regRead (0xC1 | ((addr & 0x1F) << 1)) ; |
|
} |
|
|
|
void ds1302ramWrite (const int addr, const unsigned int data) |
|
{ |
|
ds1302regWrite ( 0xC0 | ((addr & 0x1F) << 1), data) ; |
|
} |
|
|
|
/* |
|
* ds1302clockRead: |
|
* Read all 8 bytes of the clock in a single operation |
|
********************************************************************************* |
|
*/ |
|
|
|
void ds1302clockRead (int clockData [8]) |
|
{ |
|
int i ; |
|
unsigned int regVal = 0x81 | ((RTC_BM & 0x1F) << 1) ; |
|
|
|
digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ; |
|
|
|
dsShiftOut (regVal) ; |
|
for (i = 0 ; i < 8 ; ++i) |
|
clockData [i] = dsShiftIn () ; |
|
|
|
digitalWrite (sPin, LOW) ; delayMicroseconds (1) ; |
|
} |
|
|
|
|
|
/* |
|
* ds1302clockWrite: |
|
* Write all 8 bytes of the clock in a single operation |
|
********************************************************************************* |
|
*/ |
|
|
|
void ds1302clockWrite (const int clockData [8]) |
|
{ |
|
int i ; |
|
unsigned int regVal = 0x80 | ((RTC_BM & 0x1F) << 1) ; |
|
|
|
digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ; |
|
|
|
dsShiftOut (regVal) ; |
|
for (i = 0 ; i < 8 ; ++i) |
|
dsShiftOut (clockData [i]) ; |
|
|
|
digitalWrite (sPin, LOW) ; delayMicroseconds (1) ; |
|
} |
|
|
|
|
|
/* |
|
* ds1302trickleCharge: |
|
* Set the bits on the trickle charger. |
|
* Probably best left alone... |
|
********************************************************************************* |
|
*/ |
|
|
|
void ds1302trickleCharge (const int diodes, const int resistors) |
|
{ |
|
if (diodes + resistors == 0) |
|
ds1302rtcWrite (RTC_TC, 0x5C) ; // Disabled |
|
else |
|
ds1302rtcWrite (RTC_TC, 0xA0 | ((diodes & 3) << 2) | (resistors & 3)) ; |
|
} |
|
|
|
|
|
|
|
|
|
/* |
|
* ds1302setup: |
|
* Initialise the chip & remember the pins we're using |
|
********************************************************************************* |
|
*/ |
|
|
|
void ds1302setup (const int clockPin, const int dataPin, const int csPin) |
|
{ |
|
dPin = dataPin ; |
|
cPin = clockPin ; |
|
sPin = csPin ; |
|
|
|
digitalWrite (dPin, LOW) ; |
|
digitalWrite (cPin, LOW) ; |
|
digitalWrite (sPin, LOW) ; |
|
|
|
pinMode (dPin, OUTPUT) ; |
|
pinMode (cPin, OUTPUT) ; |
|
pinMode (sPin, OUTPUT) ; |
|
|
|
ds1302rtcWrite (RTC_WP, 0) ; // Remove write-protect |
|
}
|
|
|