git-svn-id: svn+ssh://oldsvn/home/mlalondesvn/svn/cral@1 3ee9b42a-b53c-0410-a25e-f0b6218d5d5bmaster
commit
20f384ee55
@ -0,0 +1,37 @@
|
|||||||
|
#include "../global.h"
|
||||||
|
|
||||||
|
// call with printString(PSTR("My string"))
|
||||||
|
void SPrint_P(const char *data)
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
ch = pgm_read_byte( data++ );
|
||||||
|
if ( !ch ) return;
|
||||||
|
Serial.print(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPrintln_P(const char *data)
|
||||||
|
{
|
||||||
|
SPrint_P(data);
|
||||||
|
SPrint_P(PSTR("\r\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPrintHex_P(const char *data)
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
ch = pgm_read_byte( data++ );
|
||||||
|
if ( !ch ) return;
|
||||||
|
Serial.print(ch, HEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPrintlnHex_P(const char *data)
|
||||||
|
{
|
||||||
|
printString(data);
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef staticPrint_H
|
||||||
|
#define staticPrint_H
|
||||||
|
|
||||||
|
#ifndef nop
|
||||||
|
#define nop() asm volatile ("nop")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SPrint
|
||||||
|
#define SPrint(str) SPrint_P(PSTR(str))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SPrintln
|
||||||
|
#define SPrintln(str) SPrintln_P(PSTR(str))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SPrintHex
|
||||||
|
#define SPrintHex(str) SPrintHex_P(PSTR(str))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SPrint
|
||||||
|
#define SPrintlnHez(str) SPrintlnHex_P(PSTR(str))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void SPrint_P(const char *data);
|
||||||
|
void SPrintln_P(const char *data);
|
||||||
|
void SPrintHex_P(const char *data);
|
||||||
|
void SPrintlnHex_P(const char *data);
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,58 @@
|
|||||||
|
#ifndef LCD_H
|
||||||
|
#define LCD_H
|
||||||
|
|
||||||
|
#define LCD_ROWS 2
|
||||||
|
#define LCD_COLUMNS 16
|
||||||
|
|
||||||
|
#define LCD_CURSOR_OFF 0x0C
|
||||||
|
#define LCD_CURSOR_OFF_BLINK 0x0D
|
||||||
|
#define LCD_CURSOR_NO_BLINK 0x0E
|
||||||
|
#define LCD_CURSOR_BLINK 0x0F
|
||||||
|
#define LCD_CLEAR 0x01
|
||||||
|
#define LCD_CLOSE_INIT 0x80
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry modes
|
||||||
|
**/
|
||||||
|
#define LCD_ENTRY_AUTOINC 0x04
|
||||||
|
#define LCD_ENTRY_SHIFT 0x02
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shifting commands
|
||||||
|
**/
|
||||||
|
#define LCD_GO_HOME 0x02
|
||||||
|
#define LCD_SHIFT_RIGHT 0x1C
|
||||||
|
#define LCD_SHIFT_LEFT 0x18
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display off command
|
||||||
|
**/
|
||||||
|
#define LCD_TURN_OFF 0x0A
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Character font
|
||||||
|
**/
|
||||||
|
#define LCD_CHARSET_0 0x00
|
||||||
|
#define LCD_CHARSET_1 0x04
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of lines
|
||||||
|
**/
|
||||||
|
#define LCD_LINES_1 0x00
|
||||||
|
#define LCD_LINES_2 0x08
|
||||||
|
|
||||||
|
#define LCD_FUNCTION_MASK B00100000
|
||||||
|
|
||||||
|
// Choose the fonction modes here
|
||||||
|
#define LCD_FUNCTION_SET LCD_LINES_2 | LCD_CHARSET_0
|
||||||
|
|
||||||
|
// Choose the cursor mode here
|
||||||
|
#define LCD_CURSOR LCD_CURSOR_OFF
|
||||||
|
|
||||||
|
// Choose the entry mode here
|
||||||
|
#define LCD_ENTRY_MODE LCD_ENTRY_AUTOINC
|
||||||
|
|
||||||
|
// Uncomment this if you want clearScreen to call back a function named onClearScreen
|
||||||
|
//#define LCD_USE_CLRSCREEN_CALLBACK
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef RTC_CONFIG_H
|
||||||
|
#define RTC_CONFIG_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this to your local GMT offset
|
||||||
|
* Comment to skip GMT offset calculations
|
||||||
|
**/
|
||||||
|
#define RTC_GMT_OFFSET -5
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select your DST type
|
||||||
|
* Comment all to skip DST calculation
|
||||||
|
**/
|
||||||
|
#define RTC_DST_TYPE 0 /* US */
|
||||||
|
//#define RTC_DST_TYPE 1 /* EU */
|
||||||
|
|
||||||
|
// Uncomment this only if you need to check DST prior to 2006
|
||||||
|
//#define RTC_CHECK_OLD_DST
|
||||||
|
#define RTC_DST_OLD_YEAR 2006
|
||||||
|
|
||||||
|
#define RTC_DOW_1 PSTR("Sun") /* First day of the week */
|
||||||
|
#define RTC_DOW_2 PSTR("Mon")
|
||||||
|
#define RTC_DOW_3 PSTR("Tue")
|
||||||
|
#define RTC_DOW_4 PSTR("Wed")
|
||||||
|
#define RTC_DOW_5 PSTR("Thu")
|
||||||
|
#define RTC_DOW_6 PSTR("Fri")
|
||||||
|
#define RTC_DOW_7 PSTR("Sat")
|
||||||
|
|
||||||
|
/* Wednesday is the first day of Epoch: This probably shouldn't change! */
|
||||||
|
#define RTC_DOW_0 RTC_DOW_4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macros
|
||||||
|
**/
|
||||||
|
// Start (US/EU), Stop (EU)
|
||||||
|
#define DSTCALCULATION1(y) (31-((y * 5 / 4) + 1) % 7)
|
||||||
|
|
||||||
|
// Stop (US)
|
||||||
|
#define DSTCALCULATION2(y) (7 - ((1 + y * 5 / 4) % 7))
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,623 @@
|
|||||||
|
extern "C" {
|
||||||
|
#include <Wire/Wire.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "../global.h"
|
||||||
|
#include "../configs/RTC/rtcConfig.h"
|
||||||
|
#include "ds1337.h"
|
||||||
|
|
||||||
|
// Internal macro for storing month days!
|
||||||
|
#ifndef GETMONTHDAYS
|
||||||
|
PROGMEM prog_uint16_t monthcount[] = {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
|
||||||
|
#define GETMONTHDAYS(index) (pgm_read_word_near(monthcount + index))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CI
|
||||||
|
#define CI(reg,bit) (reg & ~(bit))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SI
|
||||||
|
#define SI(reg,bit) (reg | bit)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DS1337::DS1337()
|
||||||
|
{
|
||||||
|
clockExists = false;
|
||||||
|
alarmId = false;
|
||||||
|
|
||||||
|
#ifdef WIRE_LIB_SCAN_MOD
|
||||||
|
/*if (!Wire.isStarted()) */Wire.begin();
|
||||||
|
#else
|
||||||
|
Wire.begin();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
DS1337 RTC = DS1337();
|
||||||
|
|
||||||
|
#ifdef WIRE_LIB_SCAN_MOD
|
||||||
|
int8_t DS1337::Init(void)
|
||||||
|
{
|
||||||
|
// Account for the crystal power up!
|
||||||
|
delay(250);
|
||||||
|
|
||||||
|
// Check address and returns false is there is an error
|
||||||
|
if (Wire.checkAddress(DS1337_WADDR)) {
|
||||||
|
// Possibly set the default registers here
|
||||||
|
|
||||||
|
clockExists = true;
|
||||||
|
|
||||||
|
// Start the oscillator if need
|
||||||
|
if (getRegisterBit(DS1337_SP, DS1337_SP_EOSC))
|
||||||
|
{
|
||||||
|
if (getRegisterBit(DS1337_STATUS, DS1337_STATUS_OSF))
|
||||||
|
{
|
||||||
|
unsetRegister(DS1337_STATUS, DS1337_STATUS_OSF);
|
||||||
|
}
|
||||||
|
|
||||||
|
clockStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
return DS1337_WADDR;
|
||||||
|
} else clockExists = false;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int8_t DS1337::Init(void)
|
||||||
|
{
|
||||||
|
// Account for the crystal power up!
|
||||||
|
delay(250);
|
||||||
|
|
||||||
|
clockExists = true;
|
||||||
|
|
||||||
|
// Start the oscillator if need
|
||||||
|
if (getRegisterBit(DS1337_SP, DS1337_SP_EOSC))
|
||||||
|
{
|
||||||
|
if (getRegisterBit(DS1337_STATUS, DS1337_STATUS_OSF))
|
||||||
|
{
|
||||||
|
unsetRegister(DS1337_STATUS, DS1337_STATUS_OSF);
|
||||||
|
}
|
||||||
|
|
||||||
|
clockStart();
|
||||||
|
|
||||||
|
return DS1337_WADDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
boolean DS1337::checkClock()
|
||||||
|
{
|
||||||
|
if (getRegisterBit(DS1337_STATUS, DS1337_STATUS_OSF))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DS1337::setRegister(uint8_t registerNumber, uint8_t registerMask)
|
||||||
|
{
|
||||||
|
writeRegister(registerNumber, SI(getRegister(registerNumber), registerMask));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DS1337::unsetRegister(uint8_t registerNumber, uint8_t registerMask)
|
||||||
|
{
|
||||||
|
writeRegister(registerNumber, CI(getRegister(registerNumber), registerMask));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DS1337::writeRegister(uint8_t registerNumber, uint8_t registerValue)
|
||||||
|
{
|
||||||
|
if (!clockExists) return;
|
||||||
|
|
||||||
|
Wire.beginTransmission(DS1337_WADDR);
|
||||||
|
Wire.send(registerNumber);
|
||||||
|
|
||||||
|
Wire.send(registerValue);
|
||||||
|
|
||||||
|
Wire.endTransmission();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t DS1337::getRegister(uint8_t registerNumber)
|
||||||
|
{
|
||||||
|
if (!clockExists) return 0;
|
||||||
|
|
||||||
|
Wire.beginTransmission(DS1337_WADDR);
|
||||||
|
Wire.send(registerNumber);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
Wire.requestFrom(DS1337_WADDR, 1);
|
||||||
|
|
||||||
|
while (!Wire.available());
|
||||||
|
|
||||||
|
return Wire.receive();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DS1337::clockRead(void)
|
||||||
|
{
|
||||||
|
if (!clockExists) return;
|
||||||
|
|
||||||
|
Wire.beginTransmission(DS1337_WADDR);
|
||||||
|
Wire.send(0x00);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
Wire.requestFrom(DS1337_WADDR, 7);
|
||||||
|
while (!Wire.available());
|
||||||
|
|
||||||
|
for(int i=0; i<7; i++)
|
||||||
|
{
|
||||||
|
if (Wire.available())
|
||||||
|
rtc_bcd[i] = Wire.receive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DS1337::clockSave(void)
|
||||||
|
{
|
||||||
|
if (!clockExists) return;
|
||||||
|
|
||||||
|
Wire.beginTransmission(DS1337_WADDR);
|
||||||
|
Wire.send(0x00);
|
||||||
|
|
||||||
|
for(int i=0; i<7; i++)
|
||||||
|
{
|
||||||
|
Wire.send(rtc_bcd[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DS1337::clockGet(uint16_t *rtc)
|
||||||
|
{
|
||||||
|
clockRead();
|
||||||
|
|
||||||
|
for(int i=0;i<8;i++) // cycle through each component, create array of data
|
||||||
|
{
|
||||||
|
rtc[i]=clockGet(i, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t DS1337::clockGet(uint8_t c, boolean refresh)
|
||||||
|
{
|
||||||
|
if(refresh) clockRead();
|
||||||
|
|
||||||
|
int timeValue=-1;
|
||||||
|
switch(c)
|
||||||
|
{
|
||||||
|
case DS1337_SEC:
|
||||||
|
timeValue = bcdToBin(DS1337_SEC, DS1337_HI_SEC);
|
||||||
|
break;
|
||||||
|
case DS1337_MIN:
|
||||||
|
timeValue = bcdToBin(DS1337_MIN, DS1337_HI_MIN);
|
||||||
|
break;
|
||||||
|
case DS1337_HR:
|
||||||
|
timeValue = bcdToBin(DS1337_HR, DS1337_HI_HR);
|
||||||
|
break;
|
||||||
|
case DS1337_DOW:
|
||||||
|
timeValue = rtc_bcd[DS1337_DOW] & DS1337_LO_DOW;
|
||||||
|
break;
|
||||||
|
case DS1337_DATE:
|
||||||
|
timeValue = bcdToBin(DS1337_DATE, DS1337_HI_DATE);
|
||||||
|
break;
|
||||||
|
case DS1337_MTH:
|
||||||
|
timeValue = CI(bcdToBin(DS1337_MTH, DS1337_HI_MTH), DS1337_LO_CNTY);
|
||||||
|
break;
|
||||||
|
case DS1337_YR:
|
||||||
|
timeValue = bcdToBin(DS1337_YR, DS1337_HI_YR)+(1900 + (rtc_bcd[DS1337_MTH] & DS1337_LO_CNTY ? 100 : 0));
|
||||||
|
break;
|
||||||
|
case DS1337_CNTY:
|
||||||
|
timeValue = rtc_bcd[DS1337_MTH] & DS1337_LO_CNTY>>7;
|
||||||
|
break;
|
||||||
|
} // end switch
|
||||||
|
|
||||||
|
return timeValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DS1337_USE_BCD_CLOCKSET
|
||||||
|
void DS1337::clockSet(uint8_t timeSection, uint16_t timeValue)
|
||||||
|
{
|
||||||
|
switch(timeSection)
|
||||||
|
{
|
||||||
|
case DS1337_SEC:
|
||||||
|
if(timeValue<60)
|
||||||
|
{
|
||||||
|
rtc_bcd[DS1337_SEC] = binToBcd(timeValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DS1337_MIN:
|
||||||
|
if(timeValue<60)
|
||||||
|
{
|
||||||
|
rtc_bcd[DS1337_MIN] = binToBcd(timeValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DS1337_HR:
|
||||||
|
// TODO : AM/PM 12HR/24HR
|
||||||
|
if(timeValue<24)
|
||||||
|
{
|
||||||
|
rtc_bcd[DS1337_HR] = binToBcd(timeValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DS1337_DOW:
|
||||||
|
if(timeValue<8)
|
||||||
|
{
|
||||||
|
rtc_bcd[DS1337_DOW] = timeValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DS1337_DATE:
|
||||||
|
if(timeValue<31)
|
||||||
|
{
|
||||||
|
rtc_bcd[DS1337_DATE] = binToBcd(timeValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DS1337_MTH:
|
||||||
|
if(timeValue<13)
|
||||||
|
{
|
||||||
|
rtc_bcd[DS1337_MTH] = SI(CI(binToBcd(timeValue),DS1337_LO_CNTY), (rtc_bcd[DS1337_MTH] & DS1337_LO_CNTY));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DS1337_YR:
|
||||||
|
if(timeValue<1000)
|
||||||
|
{
|
||||||
|
rtc_bcd[DS1337_YR] = binToBcd(timeValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DS1337_CNTY:
|
||||||
|
if (timeValue > 0)
|
||||||
|
{
|
||||||
|
rtc_bcd[DS1337_MTH] = SI(rtc_bcd[DS1337_MTH], DS1337_LO_CNTY);
|
||||||
|
} else {
|
||||||
|
rtc_bcd[DS1337_MTH] = CI(rtc_bcd[DS1337_MTH], DS1337_LO_CNTY);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} // end switch
|
||||||
|
|
||||||
|
clockSave();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DS1337_USE_GET_UTS
|
||||||
|
uint32_t DS1337::calculateUTS(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec)
|
||||||
|
{
|
||||||
|
// Number of days per month
|
||||||
|
// Compute days
|
||||||
|
tt = (year - 1970) * 365 + GETMONTHDAYS(month) + day - 1;
|
||||||
|
|
||||||
|
// Compute for leap year
|
||||||
|
for (month <= 2 ? year-- : 0; year >= 1970; year--)
|
||||||
|
if (ISLEAP(year))
|
||||||
|
tt++;
|
||||||
|
|
||||||
|
// Plus the time
|
||||||
|
tt = sec + 60 * (min + 60 * (tt * 24 + hour - RTC_GMT_OFFSET));
|
||||||
|
|
||||||
|
return tt;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DS1337_USE_SET_UTS
|
||||||
|
void DS1337::clockSetWithUTS(uint32_t unixTimeStamp, boolean correctedTime)
|
||||||
|
{
|
||||||
|
int8_t ii;
|
||||||
|
uint16_t year;
|
||||||
|
uint16_t *yrPtr = &year;
|
||||||
|
uint16_t thisYear;
|
||||||
|
uint16_t *tyPtr = &thisYear;
|
||||||
|
#if defined(RTC_DST_TYPE)
|
||||||
|
uint8_t thisDate;
|
||||||
|
uint8_t *tdPtr = &thisDate;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Serial.print((uint32_t)unixTimeStamp, DEC); delay(5); SPrint(" ");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate GMT and DST
|
||||||
|
**/
|
||||||
|
#if defined(RTC_GMT_OFFSET)
|
||||||
|
if (!correctedTime) unixTimeStamp = (uint32_t)unixTimeStamp + (RTC_GMT_OFFSET * 3600);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Years
|
||||||
|
tt = (uint32_t)unixTimeStamp / 3600 / 24 / 365;
|
||||||
|
year = tt + 1970;
|
||||||
|
|
||||||
|
thisYear = year;
|
||||||
|
|
||||||
|
// Set the century bit
|
||||||
|
if (tt > 30) {
|
||||||
|
rtc_bcd[DS1337_MTH] = SI(rtc_bcd[DS1337_MTH], DS1337_LO_CNTY);
|
||||||
|
tt-= 30;
|
||||||
|
} else {
|
||||||
|
rtc_bcd[DS1337_MTH] = CI(rtc_bcd[DS1337_MTH], DS1337_LO_CNTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the year
|
||||||
|
rtc_bcd[DS1337_YR] = binToBcd(tt);
|
||||||
|
|
||||||
|
// Number of days left in the year
|
||||||
|
// Serial.print((uint32_t)unixTimeStamp, DEC); delay(5); SPrint(" "); delay(5);
|
||||||
|
// Serial.print((uint32_t)unixTimeStamp%31536000, DEC); delay(5); SPrint(" "); delay(5);
|
||||||
|
tt = ((uint32_t)(uint32_t)unixTimeStamp%31536000 / 3600 / 24) + 1;
|
||||||
|
|
||||||
|
// Serial.print(tt, DEC); delay(5); SPrint(" "); delay(5);
|
||||||
|
|
||||||
|
// leap year correction
|
||||||
|
for (year--; year > 1970; year--) {
|
||||||
|
if (ISLEAP(year))
|
||||||
|
{
|
||||||
|
tt--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(yrPtr);
|
||||||
|
|
||||||
|
// Serial.print(tt, DEC); SPrint(" ");
|
||||||
|
|
||||||
|
// Grab the number of previous days, account for leap years, and save the month
|
||||||
|
for (ii = 1; ii < 12; ii++)
|
||||||
|
{
|
||||||
|
if (( GETMONTHDAYS(ii+1) + ((ISLEAP(thisYear) && ii >= 2) ? 1 : 0) ) > tt)
|
||||||
|
{
|
||||||
|
rtc_bcd[DS1337_MTH] = SI(CI(binToBcd(ii), DS1337_LO_CNTY), (rtc_bcd[DS1337_MTH] & DS1337_LO_CNTY));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Serial.print(ii, DEC);
|
||||||
|
// SPrint(" ");
|
||||||
|
|
||||||
|
// Date
|
||||||
|
#if defined(RTC_DST_TYPE)
|
||||||
|
if (!correctedTime) {
|
||||||
|
thisDate = tt - (GETMONTHDAYS(ii) + ((ISLEAP(thisYear) && ii >= 2) ? 1 : 0));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Date
|
||||||
|
rtc_bcd[DS1337_DATE] = binToBcd( tt - (GETMONTHDAYS(ii) + ((ISLEAP(thisYear) && ii >= 2) * 1)) );
|
||||||
|
// Serial.print( tt - (GETMONTHDAYS(ii) + ((ISLEAP(thisYear) && ii >= 2) * 1)) , DEC);
|
||||||
|
// SPrint(" ");
|
||||||
|
|
||||||
|
// Day of the week
|
||||||
|
rtc_bcd[DS1337_DOW] = ((tt)%7 + 1) & DS1337_LO_DOW;
|
||||||
|
// Serial.print(((tt)%7 + 1) & DS1337_LO_DOW, DEC);
|
||||||
|
// SPrint(" ");
|
||||||
|
|
||||||
|
// Hour
|
||||||
|
tt = (uint32_t)unixTimeStamp%86400 / 3600;
|
||||||
|
rtc_bcd[DS1337_HR] = binToBcd(tt);
|
||||||
|
// Serial.print(tt, DEC);
|
||||||
|
// SPrint(" ");
|
||||||
|
|
||||||
|
#if defined(RTC_DST_TYPE)
|
||||||
|
if (!correctedTime) {
|
||||||
|
uint8_t dstStartMo, dstStopMo, dstStart, dstStop;
|
||||||
|
uint8_t *dstStartMoPtr = &dstStartMo;
|
||||||
|
uint8_t *dstStopMoPtr = &dstStopMo;
|
||||||
|
uint8_t *dstStartPtr = &dstStart;
|
||||||
|
uint8_t *dstStopPtr = &dstStop;
|
||||||
|
|
||||||
|
#ifndef RTC_CHECK_OLD_DST
|
||||||
|
dstStart = DSTCALCULATION1(thisYear);
|
||||||
|
#if RTC_DST_TYPE == 1
|
||||||
|
dstStop = DSTCALCULATION1(thisYear); // EU DST
|
||||||
|
#else
|
||||||
|
dstStop = DSTCALCULATION2(thisYear); // US DST
|
||||||
|
#endif
|
||||||
|
dstStartMo = 3;
|
||||||
|
dstStopMo = 11;
|
||||||
|
#else
|
||||||
|
if (thisYear < RTC_DST_OLD_YEAR) {
|
||||||
|
dstStart = ((2+6 * thisYear - (thisYear / 4) ) % 7 + 1);
|
||||||
|
dstStop = (14 - ((1 + thisYear * 5 / 4) % 7));
|
||||||
|
dstStartMo = 4;
|
||||||
|
dstStopMo = 10;
|
||||||
|
} else {
|
||||||
|
dstStart = DSTCALCULATION1(thisYear)
|
||||||
|
#if RTC_DST_TYPE == 1
|
||||||
|
dstStop = DSTCALCULATION1(thisYear) // EU DST
|
||||||
|
#else
|
||||||
|
dstStop = DSTCALCULATION2(thisYear); // US DST
|
||||||
|
#endif
|
||||||
|
dstStartMo = 3;
|
||||||
|
dstStopMo = 11;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (ii >= dstStartMo && ii <= dstStopMo)
|
||||||
|
{
|
||||||
|
if ( (ii < dstStopMo && (ii > dstStartMo || thisDate > dstStart || thisDate == dstStart && tt >= 2)) ||
|
||||||
|
(thisDate < dstStop || thisDate == dstStop && tt < 2) )
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Free as much memory as possible before entering recursion
|
||||||
|
**/
|
||||||
|
free(tyPtr);
|
||||||
|
free(tdPtr);
|
||||||
|
free(dstStopPtr);
|
||||||
|
free(dstStartPtr);
|
||||||
|
free(dstStopMoPtr);
|
||||||
|
free(dstStartMoPtr);
|
||||||
|
|
||||||
|
clockSetWithUTS((uint32_t)unixTimeStamp + 3600, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Minutes
|
||||||
|
tt = (uint32_t)unixTimeStamp%3600 / 60;
|
||||||
|
rtc_bcd[DS1337_MIN] = binToBcd(tt);
|
||||||
|
// Serial.print(tt, DEC);
|
||||||
|
// SPrint(" ");
|
||||||
|
|
||||||
|
// Seconds
|
||||||
|
tt = ((uint32_t)unixTimeStamp%3600)%60;
|
||||||
|
rtc_bcd[DS1337_SEC] = binToBcd(tt);
|
||||||
|
// Serial.print(tt, DEC);
|
||||||
|
// SPrint(" ");
|
||||||
|
|
||||||
|
// Stop the clock
|
||||||
|
//clockStop(); // Uneeded with the ds1337
|
||||||
|
|
||||||
|
// Save buffer to the RTC
|
||||||
|
clockSave();
|
||||||
|
|
||||||
|
// Restart the oscillator
|
||||||
|
//clockStart(); // Uneeded with the ds1337
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t DS1337::bcdToBin(uint8_t index, uint8_t hi)
|
||||||
|
{
|
||||||
|
return (10*((rtc_bcd[index] & hi)>>4))+(rtc_bcd[index] & DS1337_LO_BCD);
|
||||||
|
}
|
||||||
|
uint8_t DS1337::binToBcd(uint8_t val)
|
||||||
|
{
|
||||||
|
return ((((val)/10)<<4) + (val)%10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alarm support functions
|
||||||
|
**/
|
||||||
|
#ifdef DS1337_USE_ALARMS
|
||||||
|
|
||||||
|
void DS1337::alarmSelect(boolean alarm)
|
||||||
|
{
|
||||||
|
alarmId = alarm;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DS1337::alarmSet(uint8_t timeSection, uint8_t timeValue)
|
||||||
|
{
|
||||||
|
if (timeSection > DS1337_ALARM_DT) return;
|
||||||
|
|
||||||
|
if (alarmId == true) rtc_alarm[DS1337_SEC] = 0;
|
||||||
|
|
||||||
|
switch(timeSection)
|
||||||
|
{
|
||||||
|
case DS1337_SEC:
|
||||||
|
if(alarmId == false && timeValue<60)
|
||||||
|
{
|
||||||
|
rtc_alarm[DS1337_SEC] = binToBcd(timeValue) & ~DS1337_ALARM_MASK | (rtc_alarm[DS1337_SEC] & DS1337_ALARM_MASK);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DS1337_MIN:
|
||||||
|
if(timeValue < 60)
|
||||||
|
{
|
||||||
|
rtc_alarm[DS1337_MIN] = binToBcd(timeValue) & ~DS1337_ALARM_MASK | (rtc_alarm[DS1337_MIN] & DS1337_ALARM_MASK);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DS1337_HR:
|
||||||
|
if(timeValue < 24)
|
||||||
|
{
|
||||||
|
rtc_alarm[DS1337_HR] = binToBcd(timeValue) & ~DS1337_ALARM_MASK | (rtc_alarm[DS1337_HR] & DS1337_ALARM_MASK);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DS1337_DOW:
|
||||||
|
if(timeValue < 31)
|
||||||
|
{
|
||||||
|
rtc_alarm[DS1337_DOW] = binToBcd(timeValue) & ~DS1337_ALARM_MASK & ~DS1337_ALARM_DT_MASK | (rtc_alarm[DS1337_DOW] & DS1337_ALARM_MASK) | (rtc_alarm[DS1337_DOW] & DS1337_ALARM_DT_MASK);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DS1337_ALARM_MODE:
|
||||||
|
{
|
||||||
|
if (alarmId) {
|
||||||
|
timeValue = (timeValue>>1)<<1;
|
||||||
|
} else
|
||||||
|
rtc_alarm[DS1337_SEC] = (rtc_alarm[DS1337_SEC] & ~DS1337_ALARM_MASK) | DS1337_ALARM_MASK & timeValue<<7;
|
||||||
|
|
||||||
|
rtc_alarm[DS1337_MIN] = (rtc_alarm[DS1337_MIN] & ~DS1337_ALARM_MASK) | DS1337_ALARM_MASK & timeValue<<6;
|
||||||
|
rtc_alarm[DS1337_HR] = (rtc_alarm[DS1337_HR] & ~DS1337_ALARM_MASK) | DS1337_ALARM_MASK & timeValue<<5;
|
||||||
|
rtc_alarm[DS1337_DOW] = (rtc_alarm[DS1337_DOW] & ~DS1337_ALARM_MASK) | DS1337_ALARM_MASK & timeValue<<4;
|
||||||
|
|
||||||
|
if (timeValue == DS1337_ALARM_MCH_DOWHRMINSEC)
|
||||||
|
{
|
||||||
|
rtc_alarm[DS1337_DOW] = rtc_alarm[DS1337_DOW] & ~DS1337_ALARM_DT_MASK | DS1337_ALARM_DT_MASK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DS1337_ALARM_DT:
|
||||||
|
{
|
||||||
|
rtc_alarm[DS1337_DOW] = rtc_alarm[DS1337_DOW] & ~DS1337_ALARM_DT_MASK | (timeValue == 1 ? DS1337_ALARM_DT_MASK : 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} // end switch
|
||||||
|
|
||||||
|
alarmSave();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean DS1337::alarmCheck(boolean both)
|
||||||
|
{
|
||||||
|
if (!both) return alarmCheck();
|
||||||
|
bool res;
|
||||||
|
|
||||||
|
if (getRegisterBit(DS1337_STATUS, DS1337_STATUS_A2F))
|
||||||
|
{
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getRegisterBit(DS1337_STATUS, DS1337_STATUS_A1F))
|
||||||
|
{
|
||||||
|
unsetRegister(DS1337_STATUS, DS1337_STATUS_A1F);
|
||||||
|
unsetRegister(DS1337_STATUS, DS1337_STATUS_A2F);
|
||||||
|
res = true;
|
||||||
|
} else if (res) res = false;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean DS1337::alarmCheck(void)
|
||||||
|
{
|
||||||
|
if (getRegisterBit(DS1337_STATUS, (alarmId == false ? DS1337_STATUS_A1F : DS1337_STATUS_A2F)))
|
||||||
|
{
|
||||||
|
unsetRegister(DS1337_STATUS, (alarmId == false ? DS1337_STATUS_A1F : DS1337_STATUS_A2F));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DS1337::alarmSave(void)
|
||||||
|
{
|
||||||
|
Wire.beginTransmission(DS1337_WADDR);
|
||||||
|
Wire.send((alarmId == false ? DS1337_ALARM1 : DS1337_ALARM2));
|
||||||
|
|
||||||
|
for(uint8_t i=(alarmId == false ? 0 : 1); i<4; i++)
|
||||||
|
{
|
||||||
|
Wire.send(rtc_alarm[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
delay(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void DS1337::printRegisters(void)
|
||||||
|
{
|
||||||
|
for(int ii=0;ii<0x10;ii++)
|
||||||
|
{
|
||||||
|
SPrint("0x");
|
||||||
|
Serial.print(ii, HEX);
|
||||||
|
SPrint(" ");
|
||||||
|
Serial.println(getRegister(ii), BIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(200);
|
||||||
|
}
|
@ -0,0 +1,349 @@
|
|||||||
|
/*
|
||||||
|
DS1337.h - library for DS1337 I2C Real Time Clock
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DS1337_h
|
||||||
|
#define DS1337_h
|
||||||
|
|
||||||
|
// include types & constants of Wiring core API
|
||||||
|
#include <WConstants.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
// include types & constants of Wire ic2 lib
|
||||||
|
#include <Wire/Wire.h>
|
||||||
|
|
||||||
|
// Include global RTC configs
|
||||||
|
#include "../configs/RTC/rtcConfig.h"
|
||||||
|
|
||||||
|
// Ucomment this to enable setting the clock from a
|
||||||
|
// unix time stamp with gmt and dst correction
|
||||||
|
#define DS1337_USE_SET_UTS
|
||||||
|
|
||||||
|
// Uncomment this enable setting the clock using BCD
|
||||||
|
//#define DS1337_USE_BCD_CLOCKSET
|
||||||
|
|
||||||
|
// Uncomment this if you need to read back unix time stamp (without DTS correction)
|
||||||
|
//#define DS1337_USE_GET_UTS
|
||||||
|
|
||||||
|
// Uncomment this to support alarms
|
||||||
|
#define DS1337_USE_ALARMS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the position of the RTC buffer values
|
||||||
|
**/
|
||||||
|
#define DS1337_SEC 0
|
||||||
|
#define DS1337_MIN 1
|
||||||
|
#define DS1337_HR 2
|
||||||
|
#define DS1337_DOW 3
|
||||||
|
#define DS1337_DATE 4
|
||||||
|
#define DS1337_MTH 5
|
||||||
|
#define DS1337_YR 6
|
||||||
|
#define DS1337_CNTY 7
|
||||||
|
|
||||||
|
// For use externally
|
||||||
|
#define RTC_SEC DS1337_SEC
|
||||||
|
#define RTC_MIN DS1337_MIN
|
||||||
|
#define RTC_HR DS1337_HR
|
||||||
|
#define RTC_DOW DS1337_DOW
|
||||||
|
#define RTC_DATE DS1337_DATE
|
||||||
|
#define RTC_MTH DS1337_MTH
|
||||||
|
#define RTC_YR DS1337_YR
|
||||||
|
#define RTC_CNTY DS1337_CNTY
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the DS1337 I2C addresses
|
||||||
|
**/
|
||||||
|
#define DS1337_WADDR 0x68
|
||||||
|
#define DS1337_RADDR DS1337_WADDR | 0x01
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define registers and bit masks
|
||||||
|
**/
|
||||||
|
#define DS1337_LO_BCD B00001111
|
||||||
|
#define DS1337_HI_BCD B01110000
|
||||||
|
|
||||||
|
#define DS1337_HI_SEC B01110000
|
||||||
|
#define DS1337_HI_MIN B01110000
|
||||||
|
#define DS1337_HI_HR B00110000
|
||||||
|
#define DS1337_LO_DOW B00000111
|
||||||
|
#define DS1337_HI_DATE B00110000
|
||||||
|
#define DS1337_HI_MTH B00010000
|
||||||
|
#define DS1337_LO_CNTY B10000000
|
||||||
|
#define DS1337_HI_YR B11110000
|
||||||
|
|
||||||
|
#define DS1337_ARLM1 0x07
|
||||||
|
#define DS1337_ARLM1_LO_SEC B00001111
|
||||||
|
#define DS1337_ARLM1_HI_SEC B01110000
|
||||||
|
#define DS1337_ARLM1_LO_MIN B01110000
|
||||||
|
#define DS1337_ARLM1_HI_MIN B00001111
|
||||||
|
|
||||||
|
#define DS1337_SP 0x0E
|
||||||
|
#define DS1337_SP_EOSC B10000000
|
||||||
|
#define DS1337_SP_RS2 B00010000
|
||||||
|
#define DS1337_SP_RS1 B00001000
|
||||||
|
#define DS1337_SP_INTCN B00000100
|
||||||
|
#define DS1337_SP_A2IE B00000010
|
||||||
|
#define DS1337_SP_A1IE B00000001
|
||||||
|
|
||||||
|
#define DS1337_STATUS 0x0F
|
||||||
|
#define DS1337_STATUS_OSF B10000000
|
||||||
|
#define DS1337_STATUS_A2F B00000010
|
||||||
|
#define DS1337_STATUS_A1F B00000001
|
||||||
|
|
||||||
|
// Alarm registers and masks
|
||||||
|
#define DS1337_ALARM1 0x07
|
||||||
|
#define DS1337_ALARM2 0x0B
|
||||||
|
|
||||||
|
#define DS1337_ALARM_DT_MASK B01000000
|
||||||
|
#define DS1337_ALARM_MASK B10000000
|
||||||
|
|
||||||
|
#define DS1337_ALARM_MODE 4
|
||||||
|
#define DS1337_ALARM_DT 5
|
||||||
|
|
||||||
|
#define DS1337_ALARM_DT_DOW true
|
||||||
|
#define DS1337_ALARM_DT_DATE false
|
||||||
|
|
||||||
|
#define DS1337_ALARM_PER_SEC B00001111
|
||||||
|
#define DS1337_ALARM_PER_MIN B00000111 /* Used for alarm 2 only*/
|
||||||
|
#define DS1337_ALARM_MCH_SEC B00001110 /* Used for alarm 1 only */
|
||||||
|
#define DS1337_ALARM_MCH_MINSEC B00001100
|
||||||
|
#define DS1337_ALARM_MCH_HRMINSEC B00001000 /* Used for alarm 1 only */
|
||||||
|
#define DS1337_ALARM_MCH_DATEHRMINSEC B00000000
|
||||||
|
#define DS1337_ALARM_MCH_DOWHRMINSEC B10000000
|
||||||
|
|
||||||
|
// Alarm mode masks
|
||||||
|
#define DS1337_ALARM2_MODE_MASK B00001000
|
||||||
|
#define DS1337_ALARM_M1 B00000001
|
||||||
|
#define DS1337_ALARM_M2 B00000010
|
||||||
|
#define DS1337_ALARM_M3 B00000100
|
||||||
|
#define DS1337_ALARM_M4 B00001000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macros
|
||||||
|
**/
|
||||||
|
#define clockStart() unsetRegister(DS1337_SP, DS1337_SP_EOSC)
|
||||||
|
#define clockStop() setRegister(DS1337_SP, DS1337_SP_EOSC)
|
||||||
|
|
||||||
|
#define getRegisterSP() getRegisterSP(DS1337_SP)
|
||||||
|
#define getRegisterStatus() getRegisterStatus(DS1337_STATUS)
|
||||||
|
|
||||||
|
#define getRegisterBit(reg, bitMask) (getRegister(reg) & bitMask) && bitMask
|
||||||
|
|
||||||
|
#ifndef ISLEAP
|
||||||
|
#define ISLEAP(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BCDTOBIN
|
||||||
|
// This marco is for internal use only!
|
||||||
|
#define BCDTOBIN(index, hi) (10*((rtc_bcd[index] & hi)>>4))+(rtc_bcd[index] & DS1337_LO_BCD)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BINTOBCD
|
||||||
|
#define BINTOBCD(val) ((((val)/10)<<4) + (val)%10)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getUTS: Macro for calculateUTS
|
||||||
|
* returns the time as a unix time stamp
|
||||||
|
* This function doesn't take into account having DST set or not!
|
||||||
|
**/
|
||||||
|
#ifdef DS1337_USE_GET_UTS
|
||||||
|
#define getUTS(refresh) calculateUTS( RTC.clockGet(DS1337_YR, true), RTC.clockGet(DS1337_MTH, false), \
|
||||||
|
RTC.clockGet(DS1337_DATE, false), RTC.clockGet(DS1337_HR, false), \
|
||||||
|
RTC.clockGet(DS1337_MIN, false), RTC.clockGet(DS1337_SEC, false) \
|
||||||
|
)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this macro to the time from a unix time stamp
|
||||||
|
**/
|
||||||
|
#if defined(DS1337_USE_SET_UTS)
|
||||||
|
#define clockSet(UTS) clockSetWithUTS(UTS, false)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macros for getting time values without refreshing the RTC buffer
|
||||||
|
**/
|
||||||
|
#define clockGetSec() clockGet(DS1337_SEC, false)
|
||||||
|
#define clockGetMin() clockGet(DS1337_MIN, false)
|
||||||
|
#define clockGetHour() clockGet(DS1337_HR, false)
|
||||||
|
#define clockGetDate() clockGet(DS1337_DATE, false)
|
||||||
|
#define clockGetMonth() clockGet(DS1337_MTH, false)
|
||||||
|
#define clockGetDow() clockGet(DS1337_DOW, false)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macros for getting time values refreshing the RTC buffer before each read.
|
||||||
|
**/
|
||||||
|
#define clockGetRSec() clockGet(DS1337_SEC, true)
|
||||||
|
#define clockGetRMin() clockGet(DS1337_MIN, true)
|
||||||
|
#define clockGetRHour() clockGet(DS1337_HR, true)
|
||||||
|
#define clockGetRDate() clockGet(DS1337_DATE, true)
|
||||||
|
#define clockGetRMonth() clockGet(DS1337_MTH, true)
|
||||||
|
#define clockGetRDow() clockGet(DS1337_DOW, true)
|
||||||
|
|
||||||
|
|
||||||
|
// library interface description
|
||||||
|
class DS1337
|
||||||
|
{
|
||||||
|
// user-accessible "public" interface
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* clockExists: keeps track of the whether or not the RTC exists
|
||||||
|
**/
|
||||||
|
bool clockExists;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor
|
||||||
|
**/
|
||||||
|
DS1337();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init: initializes the clock
|
||||||
|
* If the I2C scan mod is available, it'll verify the RTC is reachable
|
||||||
|
**/
|
||||||
|
int8_t Init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checkClock: verifies the clock integrity
|
||||||
|
* Returns false when the integrity check fails
|
||||||
|
**/
|
||||||
|
boolean checkClock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setRegister: sets a register bit fromt he register number and bitmask
|
||||||
|
**/
|
||||||
|
void setRegister(uint8_t, uint8_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unsetRegister: unsets a register bit fromt he register number and bitmask
|
||||||
|
**/
|
||||||
|
void unsetRegister(uint8_t, uint8_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getRegister: returns the specified register
|
||||||
|
**/
|
||||||
|
uint8_t getRegister(uint8_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clockGet: fills an array with the current time data
|
||||||
|
**/
|
||||||
|
void clockGet(uint16_t *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clockGet: gets a specific item from the clock buffer
|
||||||
|
* use the second param to specify a buffer refresh
|
||||||
|
**/
|
||||||
|
uint16_t clockGet(uint8_t, boolean);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clockSet: Set the clock time using integer values
|
||||||
|
* Does not do any GMT or DST correction
|
||||||
|
**/
|
||||||
|
#ifdef DS1337_USE_BCD_CLOCKSET
|
||||||
|
void clockSet(uint8_t, uint16_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* calculateUTS: returns the time as a unix time stamp
|
||||||
|
* This function doesn't take into account having DST set or not!
|
||||||
|
*
|
||||||
|
* Use the macro getUTS macro to access this function!
|
||||||
|
**/
|
||||||
|
#ifdef DS1337_USE_GET_UTS
|
||||||
|
uint32_t calculateUTS(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clockSetWithUTS: sets the date & time from a unix time stamp
|
||||||
|
* pass the second param as true to skip DTS and GMT calculation
|
||||||
|
*
|
||||||
|
* Use the clockSet macro to access this function!
|
||||||
|
**/
|
||||||
|
void clockSetWithUTS(uint32_t, boolean);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints all of the DS1337 registers
|
||||||
|
**/
|
||||||
|
|
||||||
|
void printRegisters(void);
|
||||||
|
#ifdef DS1337_USE_ALARMS
|
||||||
|
/**
|
||||||
|
* alarmSelect: allows selection of the DS1337 alarm 1 or 2
|
||||||
|
* false for alarm 1 and true for alarm 2
|
||||||
|
**/
|
||||||
|
void alarmSelect(boolean);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows setting an alarm's date and time using integers
|
||||||
|
**/
|
||||||
|
void alarmSet(uint8_t, uint8_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* alarmCheck: checks if an alarm flag was set and reset the flag
|
||||||
|
* set param to true to check for both registers false (or void) to check for the selected alarm
|
||||||
|
**/
|
||||||
|
boolean alarmCheck(boolean);
|
||||||
|
boolean alarmCheck(void); // Same as above using false
|
||||||
|
#endif
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Hold a unix time stamp
|
||||||
|
**/
|
||||||
|
#if defined(DS1337_USE_SET_UTS) || defined(DS1337_USE_GET_UTS)
|
||||||
|
uint32_t tt;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds the RTC BCD time buffer
|
||||||
|
**/
|
||||||
|
uint8_t rtc_bcd[8];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a value to a clock register
|
||||||
|
**/
|
||||||
|
void writeRegister(uint8_t, uint8_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the RTC BCD buffer to the clock
|
||||||
|
**/
|
||||||
|
void clockSave(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the RTC BCD buffer to the clock
|
||||||
|
**/
|
||||||
|
void clockRead(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a BCD to a binary integer
|
||||||
|
**/
|
||||||
|
uint8_t bcdToBin(uint8_t, uint8_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a binary integer to BCD
|
||||||
|
**/
|
||||||
|
uint8_t binToBcd(uint8_t);
|
||||||
|
|
||||||
|
#ifdef DS1337_USE_ALARMS
|
||||||
|
/**
|
||||||
|
* Hold the buffer for alarm manipulation
|
||||||
|
**/
|
||||||
|
uint8_t rtc_alarm[4];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* alarmId: keeps track of which alarm we are working with
|
||||||
|
**/
|
||||||
|
boolean alarmId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the alarm buffer to the RTC
|
||||||
|
**/
|
||||||
|
void alarmSave(void);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the Object's name
|
||||||
|
**/
|
||||||
|
extern DS1337 RTC;
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,61 @@
|
|||||||
|
extern "C" {
|
||||||
|
#include <Wire/Wire.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "../global.h"
|
||||||
|
#include "ds1624.h"
|
||||||
|
|
||||||
|
DS1624::DS1624()
|
||||||
|
{
|
||||||
|
#ifdef WIRE_LIB_SCAN_MOD
|
||||||
|
/*if (!Wire.isStarted())*/ Wire.begin();
|
||||||
|
#else
|
||||||
|
Wire.begin();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
DS1624 TEMP = DS1624();
|
||||||
|
|
||||||
|
void DS1624::Init(void)
|
||||||
|
{
|
||||||
|
Wire.beginTransmission(DS1624_ADDR);
|
||||||
|
Wire.send(DS1624_CONFIG);
|
||||||
|
Wire.send(DS1624_CONFIGS);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
delay(10);
|
||||||
|
|
||||||
|
Wire.beginTransmission(DS1624_ADDR);
|
||||||
|
Wire.send(DS1624_CONFIG);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
Wire.requestFrom(DS1624_ADDR, 1);
|
||||||
|
|
||||||
|
Wire.beginTransmission(DS1624_ADDR);
|
||||||
|
Wire.send(DS1624_SMPL_START);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
#ifdef DS1624_HANDLE_BOOT_DELAY
|
||||||
|
delay(1500);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t DS1624::readTemp(void)
|
||||||
|
{
|
||||||
|
uint16_t res = 0;
|
||||||
|
Wire.beginTransmission(DS1624_ADDR);
|
||||||
|
Wire.send(DS1624_READ_TEMP);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
Wire.requestFrom(DS1624_ADDR, 2);
|
||||||
|
|
||||||
|
while (!Wire.available());
|
||||||
|
|
||||||
|
res = (uint8_t) (Wire.receive())<<8;
|
||||||
|
|
||||||
|
while (!Wire.available());
|
||||||
|
|
||||||
|
res |= (uint8_t) Wire.receive();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
#ifndef DS1624_H
|
||||||
|
#define DS1624_H
|
||||||
|
|
||||||
|
// include types & constants of Wiring core API
|
||||||
|
#include <WConstants.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
// include types & constants of Wire ic2 lib
|
||||||
|
#include <Wire/Wire.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comment this out if you don't want the
|
||||||
|
* init function to account for the ~1S startup
|
||||||
|
* delay for the first temperature sample!
|
||||||
|
**/
|
||||||
|
#define DS1624_HANDLE_BOOT_DELAY
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address byte selection
|
||||||
|
* Select 0 for low and 1 for high
|
||||||
|
**/
|
||||||
|
#define DS1624_A0 0
|
||||||
|
#define DS1624_A1 0
|
||||||
|
#define DS1624_A2 0
|
||||||
|
|
||||||
|
#define DS1624_BASE_ADDR B01001000
|
||||||
|
#define DS1624_ADDR DS1624_BASE_ADDR | (DS1624_A0 * B00000001) | (DS1624_A1 * B00000010) | (DS1624_A2 * B00000100)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers and bit mask definition
|
||||||
|
**/
|
||||||
|
#define DS1624_CONFIG 0xAC
|
||||||
|
#define DS1624_CONFIG_DONE B10000000
|
||||||
|
#define DS1624_CONFIG_1SHOT B00000001
|
||||||
|
#define DS1624_CONFIG_CONT B00000000
|
||||||
|
|
||||||
|
// Select your config here!
|
||||||
|
#define DS1624_CONFIGS DS1624_CONFIG_CONT
|
||||||
|
|
||||||
|
#define DS1624_READ_TEMP 0xAA
|
||||||
|
#define DS1624_SMPL_START 0xEE
|
||||||
|
#define DS1624_SMPL_STOP 0x22
|
||||||
|
#define DS1624_ACCESS_MEM 0x17
|
||||||
|
|
||||||
|
class DS1624
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DS1624();
|
||||||
|
void Init(void);
|
||||||
|
uint16_t readTemp(void);
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern DS1624 TEMP;
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,46 @@
|
|||||||
|
extern "C" {
|
||||||
|
#include <Wire/Wire.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "../global.h"
|
||||||
|
#include "ds1803.h"
|
||||||
|
|
||||||
|
DS1803::DS1803()
|
||||||
|
{
|
||||||
|
#ifdef WIRE_LIB_SCAN_MOD
|
||||||
|
/*if (!Wire.isStarted())*/ Wire.begin();
|
||||||
|
#else
|
||||||
|
Wire.begin();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate the object
|
||||||
|
**/
|
||||||
|
DS1803 DPOT = DS1803();
|
||||||
|
|
||||||
|
void DS1803::setWiper(uint8_t value, uint8_t wiperAddr)
|
||||||
|
{
|
||||||
|
if (!Wire.checkAddress(DPOT_WADDR)) return;
|
||||||
|
|
||||||
|
Wire.beginTransmission(DPOT_WADDR);
|
||||||
|
Wire.send(wiperAddr); // Send the wiper address
|
||||||
|
|
||||||
|
Wire.send(value);
|
||||||
|
|
||||||
|
Wire.endTransmission();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
uint8_t DS1803::getValue()
|
||||||
|
{
|
||||||
|
if (!Wire.checkAddress(DPOT_WADDR)) return;
|
||||||
|
|
||||||
|
Wire.requestFrom(DPOT_RADDR, 2);
|
||||||
|
|
||||||
|
while (Wire.available()) {
|
||||||
|
Serial.println((uint8_t)Wire.receive(), DEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*/
|
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef DS1803_H
|
||||||
|
#define DS1803_H
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#define DPOT_WADDR 0x28
|
||||||
|
#define DPOT_RADDR DPOT_WADDR | 0x01
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of available potentiometer wipers
|
||||||
|
**/
|
||||||
|
#define DPOT_NBR_WIPERS 0x02
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Digital pot selection commands
|
||||||
|
**/
|
||||||
|
#define DPOT_WIPERS B10101111
|
||||||
|
#define DPOT_WIPER_0 B10101001
|
||||||
|
#define DPOT_WIPER_1 B10101010
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macros
|
||||||
|
**/
|
||||||
|
#define setWiper1(value) setWiper(value, DPOT_WIPER_0)
|
||||||
|
#define setWiper2(value) setWiper(value, DPOT_WIPER_1)
|
||||||
|
#define setWipers(value) setWiper(value, DPOT_WIPERS)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DS1803 I2C Dual Digital Pot.
|
||||||
|
**/
|
||||||
|
class DS1803
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DS1803();
|
||||||
|
void setWiper(uint8_t, uint8_t);
|
||||||
|
//uint8_t getValue();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the object's name
|
||||||
|
**/
|
||||||
|
extern DS1803 DPOT;
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,45 @@
|
|||||||
|
#ifndef GLOBAL_H
|
||||||
|
#define GLOBAL_H
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "wiring.h"
|
||||||
|
#include "WConstants.h"
|
||||||
|
|
||||||
|
#include <HardwareSerial.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "staticPrint/staticPrint.h"
|
||||||
|
|
||||||
|
#ifndef BV
|
||||||
|
#define BV(bit) (1<<(bit))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef cbi
|
||||||
|
#define cbi(reg,bit) reg &= ~(BV(bit))
|
||||||
|
#endif
|
||||||
|
#ifndef sbi
|
||||||
|
#define sbi(reg,bit) reg |= (BV(bit))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CI
|
||||||
|
#define CI(reg,bit) (reg & ~(bit))
|
||||||
|
#endif
|
||||||
|
#ifndef SI
|
||||||
|
#define SI(reg,bit) (reg | bit)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef cli
|
||||||
|
#define cli() __asm__ __volatile__ ("cli" ::)
|
||||||
|
#endif
|
||||||
|
#ifndef sei
|
||||||
|
#define sei() __asm__ __volatile__ ("sei" ::)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,427 @@
|
|||||||
|
extern "C" {
|
||||||
|
#include <Wire/Wire.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "../global.h"
|
||||||
|
#include "../configs/LCD/lcd.h"
|
||||||
|
#include "twiLCD.h"
|
||||||
|
|
||||||
|
#ifdef TWI_LCD_DPOT_CTRL
|
||||||
|
#include "../ds1803/ds1803.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
twiLCD::twiLCD()
|
||||||
|
{
|
||||||
|
#if defined(__AVR_ATmega168__) && !defined(TWI_LCD_SMALL)
|
||||||
|
#if defined(TWI_LCD_CTRL) && !defined(TWI_LCD_BL_PWM)
|
||||||
|
backlightStatus = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TWI_LCD_BL_PWM
|
||||||
|
pinMode(TWI_LCD_BACKLIGHT, HIGH);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
displayStatus = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIRE_LIB_SCAN_MOD
|
||||||
|
/*if (!Wire.isStarted())*/ Wire.begin();
|
||||||
|
#else
|
||||||
|
Wire.begin();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
twiLCD LCD = twiLCD();
|
||||||
|
|
||||||
|
void twiLCD::Init() {
|
||||||
|
#ifdef TWI_LCD_CTRL
|
||||||
|
backlightOff();
|
||||||
|
#ifdef TWI_LCD_DPOT_CTRL
|
||||||
|
setBrightness(0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
delay(20);
|
||||||
|
/////////// 4 pin initialization
|
||||||
|
writeCommand(0x03); // function set: 4 pin initialization
|
||||||
|
delay(5);
|
||||||
|
writeCommand(0x03); // function set: 4 pin initialization
|
||||||
|
delay(1);
|
||||||
|
writeCommand(0x03); // function set: 4 pin initialization
|
||||||
|
delay(1);
|
||||||
|
writeCommand(0x02); // function set: 4 pin initialization
|
||||||
|
/////////// end of 4 pin initialization
|
||||||
|
|
||||||
|
|
||||||
|
writeCommand(LCD_FUNCTION_SET); // function set: 4-bit interface, 1 display lines, 5x7 font
|
||||||
|
writeCommand(LCD_ENTRY_MODE);
|
||||||
|
writeCommand(LCD_CURSOR);
|
||||||
|
clearScreen();
|
||||||
|
|
||||||
|
writeCommand(LCD_CLOSE_INIT);
|
||||||
|
|
||||||
|
#if defined(__AVR_ATmega168__) && !defined(TWI_LCD_SMALL)
|
||||||
|
#ifdef TWI_LCD_CTRL
|
||||||
|
#if defined(TWI_LCD_BL_PWM) || defined(TWI_LCD_DPOT_CTRL)
|
||||||
|
#ifdef TWI_LCD_DPOT_CTRL
|
||||||
|
setBrightness();
|
||||||
|
#endif
|
||||||
|
backlightOn(TWI_LCD_BL_LEVEL);
|
||||||
|
#else
|
||||||
|
backlightOn();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
displayStatus = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean twiLCD::checkLCDBusy(void)
|
||||||
|
{
|
||||||
|
Wire.requestFrom(PCF8574_RADDR, 1);
|
||||||
|
|
||||||
|
while (!Wire.available());
|
||||||
|
|
||||||
|
return (Wire.receive() & TWI_LCD_BUSY ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::writeCommand(uint8_t value)
|
||||||
|
{
|
||||||
|
int value1 = 0;
|
||||||
|
int control = 0; // stores RS and RW
|
||||||
|
|
||||||
|
#ifdef TWI_LCD_USE_TIMEOUT
|
||||||
|
previousMillis = millis();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
control = value >> 8; // get the control signals RS and RW
|
||||||
|
control >>= 5; // shift the control signals to the left
|
||||||
|
|
||||||
|
Wire.beginTransmission(PCF8574_WADDR);
|
||||||
|
|
||||||
|
value1 = value;
|
||||||
|
cbi(value1, TWI_LCD_DATAL); // Turn off LByte
|
||||||
|
|
||||||
|
cbi(value1, TWI_LCD_RS);
|
||||||
|
cbi(value1, TWI_LCD_RW);
|
||||||
|
|
||||||
|
sendPulse(value1);
|
||||||
|
|
||||||
|
delay(1);
|
||||||
|
|
||||||
|
cbi(value, TWI_LCD_DATAH); // Turn off HByte
|
||||||
|
value <<= 4;
|
||||||
|
|
||||||
|
cbi(value, TWI_LCD_RS);
|
||||||
|
cbi(value, TWI_LCD_RW);
|
||||||
|
|
||||||
|
sendPulse(value);
|
||||||
|
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::writeData(uint8_t value)
|
||||||
|
{
|
||||||
|
int value1 = 0;
|
||||||
|
int control = 0; // stores RS and RW
|
||||||
|
|
||||||
|
// Wait for the LCD to be ready
|
||||||
|
|
||||||
|
#ifdef TWI_LCD_USE_TIMEOUT
|
||||||
|
previousMillis = millis();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
control = value >> 8; // get the control signals RS and RW
|
||||||
|
control >>= 5; // shift the control signals to the left
|
||||||
|
|
||||||
|
value1 = value;
|
||||||
|
cbi(value1, TWI_LCD_DATAL); // Turn off LByte
|
||||||
|
sbi(value1, TWI_LCD_RS);
|
||||||
|
cbi(value1, TWI_LCD_RW);
|
||||||
|
|
||||||
|
while (checkLCDBusy());
|
||||||
|
|
||||||
|
Wire.beginTransmission(PCF8574_WADDR);
|
||||||
|
sendPulse(value1);
|
||||||
|
|
||||||
|
delay(1);
|
||||||
|
|
||||||
|
cbi(value, TWI_LCD_DATAH); // Turn off HByte
|
||||||
|
value <<= 4;
|
||||||
|
|
||||||
|
sbi(value, TWI_LCD_RS);
|
||||||
|
cbi(value, TWI_LCD_RW);
|
||||||
|
|
||||||
|
sendPulse(value);
|
||||||
|
Wire.endTransmission();
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::sendPulse(int value)
|
||||||
|
{
|
||||||
|
cbi(value, TWI_LCD_ENABLE);
|
||||||
|
writeToPCF(value);
|
||||||
|
|
||||||
|
sbi(value, TWI_LCD_ENABLE);
|
||||||
|
writeToPCF(value);
|
||||||
|
|
||||||
|
cbi(value, TWI_LCD_ENABLE);
|
||||||
|
writeToPCF(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::writeToPCF(int value)
|
||||||
|
{
|
||||||
|
#if defined(TWI_LCD_CTRL) && !defined(TWI_LCD_BL_PWM)
|
||||||
|
if (backlightStatus)
|
||||||
|
sbi(value, TWI_LCD_BACKLIGHT);
|
||||||
|
else
|
||||||
|
cbi(value, TWI_LCD_BACKLIGHT);
|
||||||
|
|
||||||
|
Wire.send(value);
|
||||||
|
#else
|
||||||
|
Wire.send(value);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::clearScreen(void)
|
||||||
|
{
|
||||||
|
writeCommand(LCD_CLEAR);
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
#if defined(__AVR_ATmega168__) && !defined(TWI_LCD_SMALL)
|
||||||
|
currentLine = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LCD_USE_CLRSCREEN_CALLBACK
|
||||||
|
onClearScreen();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::printString_P(const char *data)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
ch = pgm_read_byte( data++ );
|
||||||
|
if ( !ch ) return;
|
||||||
|
writeData(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__AVR_ATmega168__) && !defined(TWI_LCD_SMALL)
|
||||||
|
#ifdef TWI_LCD_USE_TIMEOUT
|
||||||
|
bool twiLCD::checkTimeout(void)
|
||||||
|
{
|
||||||
|
if (displayStatus && millis() - previousMillis > TWI_LCD_TIMEOUT) {
|
||||||
|
turnOff();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TWI_LCD_CTRL
|
||||||
|
#ifdef TWI_LCD_BL_PWM
|
||||||
|
void twiLCD::backlightOn(void)
|
||||||
|
{
|
||||||
|
digitalWrite(TWI_LCD_BACKLIGHT, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::backlightOn(uint8_t value)
|
||||||
|
{
|
||||||
|
analogWrite(TWI_LCD_BACKLIGHT, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::backlightOff(void)
|
||||||
|
{
|
||||||
|
digitalWrite(TWI_LCD_BACKLIGHT, LOW);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#ifdef TWI_LCD_DPOT_CTRL
|
||||||
|
void twiLCD::backlightOn(void)
|
||||||
|
{
|
||||||
|
DPOT.setWiper2(TWI_LCD_BL_LEVEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::backlightOn(uint8_t value)
|
||||||
|
{
|
||||||
|
DPOT.setWiper2(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::backlightOff(void)
|
||||||
|
{
|
||||||
|
DPOT.setWiper2(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::setBrightness(void)
|
||||||
|
{
|
||||||
|
DPOT.setWiper1(TWI_LCD_DB_LEVEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::setBrightness(uint8_t value)
|
||||||
|
{
|
||||||
|
DPOT.setWiper1(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
void twiLCD::backlightOn(void)
|
||||||
|
{
|
||||||
|
int val = 0;
|
||||||
|
backlightStatus = 1;
|
||||||
|
sbi(val, TWI_LCD_BACKLIGHT);
|
||||||
|
|
||||||
|
Wire.beginTransmission(PCF8574_WADDR);
|
||||||
|
Wire.send(val);
|
||||||
|
Wire.endTransmission();
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::backlightOff(void)
|
||||||
|
{
|
||||||
|
int val = 0;
|
||||||
|
backlightStatus = 0;
|
||||||
|
cbi(val, TWI_LCD_BACKLIGHT);
|
||||||
|
|
||||||
|
Wire.beginTransmission(PCF8574_WADDR);
|
||||||
|
Wire.send(val);
|
||||||
|
Wire.endTransmission();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void twiLCD::turnOff(void)
|
||||||
|
{
|
||||||
|
writeCommand(LCD_TURN_OFF);
|
||||||
|
#if defined(TWI_LCD_CTRL)
|
||||||
|
backlightOff();
|
||||||
|
#ifdef TWI_LCD_DPOT_CTRL
|
||||||
|
setBrightness(0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
displayStatus = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function needs a rewrite
|
||||||
|
**/
|
||||||
|
void twiLCD::setCursor(int index)
|
||||||
|
{
|
||||||
|
//0-79, index for one line display, 8 bit mode
|
||||||
|
//0-39 and 64-103 for lines one and two of two line display, not implemented yet
|
||||||
|
int cmd = 128+index;
|
||||||
|
writeCommand(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function needs a rewrite
|
||||||
|
**/
|
||||||
|
void twiLCD::moveToXY(uint8_t row, uint8_t column)
|
||||||
|
{
|
||||||
|
int position;
|
||||||
|
|
||||||
|
// Determine the new position
|
||||||
|
position = (row * 20) + column;
|
||||||
|
|
||||||
|
// Send the correct commands to the command register of the LCD
|
||||||
|
if(position < 20)
|
||||||
|
writeCommand(0x80 | position);
|
||||||
|
else if(position >= 20 && position < 40)
|
||||||
|
writeCommand(0x80 | (position % 20 + 0x40));
|
||||||
|
else if(position >= 41 && position < 60)
|
||||||
|
writeCommand(0x80 | (position % 40 + 0x14));
|
||||||
|
else if(position >= 20 && position < 40)
|
||||||
|
writeCommand(0x80 | (position % 60 + 0x54));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t twiLCD::getCurrentLine(void)
|
||||||
|
{
|
||||||
|
return currentLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::goToLine(uint8_t line)
|
||||||
|
{
|
||||||
|
if (line > LCD_ROWS) return;
|
||||||
|
moveToXY(line - 1, 0);
|
||||||
|
currentLine = line;
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::goToNextLine(void)
|
||||||
|
{
|
||||||
|
if (currentLine+1 > LCD_ROWS) {
|
||||||
|
goToLine(1);
|
||||||
|
} else {
|
||||||
|
goToLine(currentLine+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::goHome(void)
|
||||||
|
{
|
||||||
|
writeCommand(LCD_GO_HOME); // set cursor position to zero
|
||||||
|
currentLine = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::clearLine(void)
|
||||||
|
{
|
||||||
|
int ii;
|
||||||
|
moveToXY(currentLine-1, 0);
|
||||||
|
|
||||||
|
for (ii=0;ii<LCD_COLUMNS;ii++)
|
||||||
|
{
|
||||||
|
printString(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
moveToXY(currentLine-1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::shiftDisplayLeft(void)
|
||||||
|
{
|
||||||
|
writeCommand(LCD_SHIFT_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::shiftDisplayRight(void)
|
||||||
|
{
|
||||||
|
writeCommand(LCD_SHIFT_RIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool twiLCD::getCurrentStatus(void)
|
||||||
|
{
|
||||||
|
return displayStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::printInteger(uint16_t integer, bool leadingZero)
|
||||||
|
{
|
||||||
|
uint8_t thousands = integer / 1000;
|
||||||
|
uint8_t hundreds = (integer - thousands*1000) / 100;
|
||||||
|
uint8_t tens = (integer - thousands*1000 - hundreds*100 ) / 10;
|
||||||
|
writeData(tens + 0x30);
|
||||||
|
|
||||||
|
uint8_t ones = (integer - thousands*1000 - hundreds*100 - tens*10);
|
||||||
|
writeData(ones + 0x30);
|
||||||
|
}
|
||||||
|
|
||||||
|
void twiLCD::printInteger(int16_t integer)
|
||||||
|
{
|
||||||
|
if (integer < 0) {
|
||||||
|
printString("-");
|
||||||
|
integer = 0 - integer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Break down the original number into the thousands, hundreds, tens,
|
||||||
|
// and ones places and then immediately write that value to the LCD
|
||||||
|
uint8_t thousands = integer / 1000;
|
||||||
|
if (thousands > 0) writeData(thousands + 0x30);
|
||||||
|
|
||||||
|
uint8_t hundreds = (integer - thousands*1000) / 100;
|
||||||
|
if (hundreds > 0 || thousands > 0)
|
||||||
|
writeData(hundreds + 0x30);
|
||||||
|
|
||||||
|
uint8_t tens = (integer - thousands*1000 - hundreds*100 ) / 10;
|
||||||
|
if (tens || hundreds > 0 || thousands > 0)
|
||||||
|
writeData(tens + 0x30);
|
||||||
|
|
||||||
|
uint8_t ones = (integer - thousands*1000 - hundreds*100 - tens*10);
|
||||||
|
writeData(ones + 0x30);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,220 @@
|
|||||||
|
#ifndef twiLCD_H
|
||||||
|
#define twiLCD_H
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "twiLCDConfig.h"
|
||||||
|
|
||||||
|
#define PCF8574_WADDR 0x20
|
||||||
|
#define PCF8574_RADDR PCF8574_WADDR | 0x01
|
||||||
|
|
||||||
|
#define TWI_LCD_RS 0 /* RS pin */
|
||||||
|
#define TWI_LCD_RW 1 /* RW pin */
|
||||||
|
#define TWI_LCD_ENABLE 2 /* Enable pin */
|
||||||
|
#ifdef TWI_LCD_CTRL
|
||||||
|
#ifdef TWI_LCD_BL_PWM
|
||||||
|
#define TWI_LCD_BACKLIGHT 9 /* This is an Arduino pin number! */
|
||||||
|
#else
|
||||||
|
#define TWI_LCD_BACKLIGHT 3 /* Backlight pin */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TWI_LCD_CONTROL B00000111 /* Mask for the 3 control bits (E, RS, RW) */
|
||||||
|
#define TWI_LCD_DATA B11110000 /* Mask for the 4 bit word */
|
||||||
|
#define TWI_LCD_DATAH B11110000
|
||||||
|
#define TWI_LCD_DATAL B00001111
|
||||||
|
#define TWI_LCD_BUSY B00001000
|
||||||
|
|
||||||
|
#ifndef printString
|
||||||
|
#define printString(str) printString_P(PSTR(str))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class twiLCD {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor: initializes this class
|
||||||
|
**/
|
||||||
|
twiLCD();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LCD Initilization method
|
||||||
|
**/
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writeData: write a byte of data to the LCD
|
||||||
|
* @param: value: the byte to write
|
||||||
|
**/
|
||||||
|
void writeData(uint8_t value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clearScreen: clears the LCD and resets the cursor position to 0,0
|
||||||
|
**/
|
||||||
|
void clearScreen(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* printString_P: prints a program string to the LCD
|
||||||
|
* To call this function, use the LCD.printString() macro!
|
||||||
|
**/
|
||||||
|
void printString_P(const char *data);
|
||||||
|
/**
|
||||||
|
* These function are only available on the mega168 for space reasons
|
||||||
|
**/
|
||||||
|
#if defined(__AVR_ATmega168__) && !defined(TWI_LCD_SMALL)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Methods for dealing with LCD timeout
|
||||||
|
* Returns true if the time is expired
|
||||||
|
**/
|
||||||
|
#ifdef TWI_LCD_USE_TIMEOUT
|
||||||
|
bool checkTimeout(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backlight control functions
|
||||||
|
* Optionally enabled above
|
||||||
|
**/
|
||||||
|
#ifdef TWI_LCD_CTRL
|
||||||
|
/**
|
||||||
|
* backlightOn: Turn on the backlight at full brightness
|
||||||
|
**/
|
||||||
|
void backlightOn(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* backlightOff: turn off the LCD backlight
|
||||||
|
**/
|
||||||
|
void backlightOff(void);
|
||||||
|
|
||||||
|
// PWM Backlight Control
|
||||||
|
#if defined(TWI_LCD_BL_PWM) || defined(TWI_LCD_DPOT_CTRL)
|
||||||
|
/**
|
||||||
|
* backlightOn: turns on the backlight with a specific brightness
|
||||||
|
**/
|
||||||
|
void backlightOn(uint8_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TWI_LCD_DPOT_CTRL
|
||||||
|
/**
|
||||||
|
* setBrightness: sets the brightness level using a digital pot
|
||||||
|
* If no param is passed TWI_LCD_DB_LEVEL is used
|
||||||
|
**/
|
||||||
|
void setBrightness(void);
|
||||||
|
void setBrightness(uint8_t);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setCursor: set cursor a position "index"
|
||||||
|
**/
|
||||||
|
void setCursor(int);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* moveToXY: moves the cursor to position (row,column)
|
||||||
|
**/
|
||||||
|
void moveToXY(uint8_t, uint8_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn off the LCD (will turn off the backlight if control is enabled)
|
||||||
|
**/
|
||||||
|
void turnOff(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* goToLine: Allows to move at the beginning of a specific line
|
||||||
|
**/
|
||||||
|
void goToLine(uint8_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* goToNextLine: goes to the next line, wraps arround at the end
|
||||||
|
**/
|
||||||
|
void goToNextLine(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* goHome: goes to position (0,0)
|
||||||
|
**/
|
||||||
|
void goHome(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clearLine: clears the current line
|
||||||
|
**/
|
||||||
|
void clearLine(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shiftDisplayLeft: shift all lines of the display one position to the left
|
||||||
|
**/
|
||||||
|
void shiftDisplayLeft(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shiftDisplayRight: shift all lines of the display one position to the right
|
||||||
|
**/
|
||||||
|
void shiftDisplayRight(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getCurrentLine: returns the current line
|
||||||
|
**/
|
||||||
|
uint8_t getCurrentLine(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getCurrentStatus: returns whether the display is on or off
|
||||||
|
**/
|
||||||
|
bool getCurrentStatus(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* printInteger: writes an interger as text on the lcd
|
||||||
|
* The second version is only good for intergers < 99 and will add a leading zero
|
||||||
|
**/
|
||||||
|
void printInteger(int16_t);
|
||||||
|
void printInteger(uint16_t integer, bool leadingZero);
|
||||||
|
#endif
|
||||||
|
private:
|
||||||
|
#if defined(__AVR_ATmega168__) && !defined(TWI_LCD_SMALL)
|
||||||
|
#ifdef TWI_LCD_USE_TIMEOUT
|
||||||
|
unsigned long previousMillis;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(TWI_LCD_CTRL) && !defined(TWI_LCD_BL_PWM)
|
||||||
|
/**
|
||||||
|
* backlightStatus: used to keep track of the backlight status
|
||||||
|
**/
|
||||||
|
uint8_t backlightStatus;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* currentLine: keeps track of the current line
|
||||||
|
**/
|
||||||
|
uint8_t currentLine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* displayStatus: keeps track of whether the display is on or off
|
||||||
|
**/
|
||||||
|
bool displayStatus;
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* sendPulse: sends a byte of data with the appropiate Enable pulse
|
||||||
|
**/
|
||||||
|
void sendPulse(int);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writeToPCF: writes a new byte of data using twi
|
||||||
|
* This function is used to preserve some data through writes
|
||||||
|
* such as when bit3 of the expander is used to control the backlight
|
||||||
|
**/
|
||||||
|
void writeToPCF(int);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writeCommand: Writes an LCD command
|
||||||
|
* @param: value: the value to write
|
||||||
|
**/
|
||||||
|
void writeCommand(uint8_t value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checkLCDBusy: reads the busy state bit from the LCD
|
||||||
|
**/
|
||||||
|
boolean checkLCDBusy(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the object's name
|
||||||
|
**/
|
||||||
|
extern twiLCD LCD;
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef TWI_LCD_CONF_H
|
||||||
|
#define TWI_LCD_CONF_H
|
||||||
|
|
||||||
|
// Uncomment this to use minimal mode (less functions, not as big)
|
||||||
|
// #define TWI_LCD_SMALL
|
||||||
|
|
||||||
|
#if defined(__AVR_ATmega168__) && !defined(TWI_LCD_SMALL)
|
||||||
|
// Uncomment this to enable use of a timeout after which the LCD turns off
|
||||||
|
#define TWI_LCD_USE_TIMEOUT
|
||||||
|
|
||||||
|
#ifdef TWI_LCD_USE_TIMEOUT
|
||||||
|
#define TWI_LCD_TIMEOUT 5000 /* In milliseconds (30 sec) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Uncomment this to enable control of the backlight on pin 3
|
||||||
|
#define TWI_LCD_CTRL
|
||||||
|
|
||||||
|
#ifdef TWI_LCD_CTRL
|
||||||
|
// Uncomment this to use PWM for backlight control.
|
||||||
|
//#define TWI_LCD_BL_PWM
|
||||||
|
|
||||||
|
#ifdef TWI_LCD_BL_PWM
|
||||||
|
// Set this to the default brightness for PWM controlled backlight
|
||||||
|
#define TWI_LCD_BL_LEVEL 255
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TWI_LCD_BL_PWM
|
||||||
|
// Uncomment this use the DS1803 digi-pot for display/backlight brightness
|
||||||
|
#define TWI_LCD_DPOT_CTRL
|
||||||
|
|
||||||
|
#ifdef TWI_LCD_DPOT_CTRL
|
||||||
|
// Set this to the default value of the backlight (0 to 254)
|
||||||
|
#define TWI_LCD_BL_LEVEL 254
|
||||||
|
|
||||||
|
// Set this to the default value of the display brightness (0 to 254)
|
||||||
|
#define TWI_LCD_DB_LEVEL 225
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in new issue