diff --git a/configs/LCD/lcd.h b/configs/LCD/lcd.h index fb8a05d..60b3339 100644 --- a/configs/LCD/lcd.h +++ b/configs/LCD/lcd.h @@ -53,6 +53,6 @@ #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 +#define LCD_USE_CLRSCREEN_CALLBACK #endif diff --git a/ds1337/ds1337.cpp b/ds1337/ds1337.cpp index c63d41c..3587a1b 100644 --- a/ds1337/ds1337.cpp +++ b/ds1337/ds1337.cpp @@ -37,9 +37,6 @@ 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 @@ -53,6 +50,9 @@ int8_t DS1337::Init(void) { unsetRegister(DS1337_STATUS, DS1337_STATUS_OSF); } + #if defined(DS1337_USE_ALARM_INTERRUPTS) && !defined(DS1337_USE_SQW_OUTPUT) + setRegister(DS1337_SP, DS1337_SQW_INTCN); + #endif clockStart(); } @@ -87,16 +87,6 @@ int8_t DS1337::Init(void) } #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)); @@ -488,13 +478,41 @@ uint8_t DS1337::binToBcd(uint8_t val) * Alarm support functions **/ #ifdef DS1337_USE_ALARMS - void DS1337::alarmSelect(boolean alarm) { alarmId = alarm; return; } +#ifdef DS1337_USE_ALARMS_CALLBACK +void DS1337::alarmSetCallback(void (*userFunc)(void)) +{ + DS1337callbackFunc[(alarmId ? 1 : 0)] = userFunc; +} + +void DS1337::alarmUnsetCallback(void) +{ + DS1337callbackFunc[(alarmId ? 1 : 0)] = 0; +} + +void DS1337::alarmChecks(void) +{ + if (getRegisterBit(DS1337_STATUS, DS1337_STATUS_A1F)) + { + unsetRegister(DS1337_STATUS, DS1337_STATUS_A1F); delay(10); + if (DS1337callbackFunc) DS1337callbackFunc[0](); + } + + if (getRegisterBit(DS1337_STATUS, DS1337_STATUS_A2F)) + { + unsetRegister(DS1337_STATUS, DS1337_STATUS_A2F); delay(10); + if (DS1337callbackFunc) DS1337callbackFunc[1](); + } + + return; +} +#endif + void DS1337::alarmSet(uint8_t timeSection, uint8_t timeValue) { if (timeSection > DS1337_ALARM_DT) return; @@ -560,26 +578,6 @@ void DS1337::alarmSet(uint8_t timeSection, uint8_t timeValue) 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))) @@ -607,8 +605,86 @@ void DS1337::alarmSave(void) delay(5); } +#ifdef DS1337_USE_ALARM_INTERRUPTS +void DS1337::alarmDisableInterrupts(void) +{ + unsetRegister(DS1337_SP, DS1337_ALARM_INT1); + unsetRegister(DS1337_SP, DS1337_ALARM_INT2); + + return; +} + +void DS1337::alarmSetInterrupt(void) +{ +#ifndef DS1337_USE_SQW_OUTPUT + if (alarmId) setRegister(DS1337_SP, DS1337_SQW_INTCN); #endif + + setRegister(DS1337_SP, (alarmId == false ? DS1337_ALARM_INT1 : DS1337_ALARM_INT2)); + + return; +} +void DS1337::alarmUnsetInterrupt(void) +{ + unsetRegister(DS1337_SP, (alarmId == false ? DS1337_ALARM_INT1 : DS1337_ALARM_INT2)); + + return; +} +#endif +#endif + +#ifdef DS1337_USE_SQW_OUTPUT +void DS1337::sqwEnable(void) +{ + unsetRegister(DS1337_SP, DS1337_SQW_INTCN); + return; +} + +void DS1337::sqwDisable(void) +{ + setRegister(DS1337_SP, DS1337_SQW_INTCN); + return; +} + +void DS1337::sqwSetRate(uint8_t sqwRate) +{ + writeRegister(DS1337_SP, (getRegisterSP() & ~DS1337_SQW_RS | sqwRate)); + + return; +} +#endif + +#ifdef DS1337_USE_OSC_INTEGRITY +void DS1337::clockIntegrityCallback(void (*userFunc)(void)) +{ + DS1337callbackFunc[2] = userFunc; +} +#endif + +#if defined(DS1337_USE_ALARMS_CALLBACK) || defined(DS1337_USE_OSC_INTEGRITY) +void DS1337::clockChecks(void) +{ +#ifdef DS1337_USE_OSC_INTEGRITY + if (getRegisterBit(DS1337_STATUS, DS1337_STATUS_OSF)) + { + clockStop(); + unsetRegister(DS1337_STATUS, DS1337_STATUS_OSF); + unsetRegister(DS1337_STATUS, DS1337_STATUS_A1F); + unsetRegister(DS1337_STATUS, DS1337_STATUS_A2F); + + if (DS1337callbackFunc[2]) DS1337callbackFunc[2](); + + return; + } +#endif +#ifdef DS1337_USE_ALARMS_CALLBACK + alarmChecks(); +#endif +} +#endif + +#ifdef DS1337_DEBUG void DS1337::printRegisters(void) { for(int ii=0;ii<0x10;ii++) @@ -621,3 +697,4 @@ void DS1337::printRegisters(void) delay(200); } +#endif diff --git a/ds1337/ds1337.h b/ds1337/ds1337.h index 605b902..f97e94e 100644 --- a/ds1337/ds1337.h +++ b/ds1337/ds1337.h @@ -4,10 +4,10 @@ #ifndef DS1337_h #define DS1337_h +#define DS1337_DEBUG // include types & constants of Wiring core API -#include -#include +#include "../global.h" // include types & constants of Wire ic2 lib #include @@ -28,6 +28,21 @@ // Uncomment this to support alarms #define DS1337_USE_ALARMS +#ifdef DS1337_USE_ALARMS +// Uncomment this to allow use external alarm interrupts +#define DS1337_USE_ALARM_INTERRUPTS + +// Uncomment this to allow alarm functions callback +#define DS1337_USE_ALARMS_CALLBACK +#endif + +// Uncomment this to use integrity check functions +//#define DS1337_USE_OSC_INTEGRITY + +// Uncomment this to support square wave output +// If this is enabled, alarm 2 will output it's interrupt on INTA +#define DS1337_USE_SQW_OUTPUT + /** * Define the position of the RTC buffer values **/ @@ -118,14 +133,31 @@ #define DS1337_ALARM_M3 B00000100 #define DS1337_ALARM_M4 B00001000 +// Alarm interrupt bitmask +#define DS1337_ALARM_INT1 B00000001 +#define DS1337_ALARM_INT2 B00000010 + +// Square Wave output masks +#define DS1337_SQW_INTCN B00000100 +#define DS1337_SQW_RS1 B00001000 +#define DS1337_SQW_RS2 B00010000 + +// Square Wave output modes +#define DS1337_SQW_RS B00011000 +#define DS1337_SQW_1HZ B00000000 +#define DS1337_SQW_4096KHZ DS1337_SQW_RS1 +#define DS1337_SQW_8192KHZ DS1337_SQW_RS2 +#define DS1337_SQW_OSC DS1337_SQW_RS1 | DS1337_SQW_RS2 + /** * Macros **/ -#define clockStart() unsetRegister(DS1337_SP, DS1337_SP_EOSC) +// Starts the oscillator and delay a little to account for long oscillator startup times +#define clockStart() unsetRegister(DS1337_SP, DS1337_SP_EOSC); delay(500); #define clockStop() setRegister(DS1337_SP, DS1337_SP_EOSC) -#define getRegisterSP() getRegisterSP(DS1337_SP) -#define getRegisterStatus() getRegisterStatus(DS1337_STATUS) +#define getRegisterSP() getRegister(DS1337_SP) +#define getRegisterStatus() getRegister(DS1337_STATUS) #define getRegisterBit(reg, bitMask) (getRegister(reg) & bitMask) && bitMask @@ -182,6 +214,13 @@ #define clockGetRDow() clockGet(DS1337_DOW, true) +#if defined(DS1337_USE_ALARMS_CALLBACK) || defined(DS1337_USE_OSC_INTEGRITY) +/** + * Holds the pointer to callback functions +**/ +volatile static voidFuncPtr DS1337callbackFunc[3]; +#endif + // library interface description class DS1337 { @@ -202,13 +241,20 @@ class DS1337 * If the I2C scan mod is available, it'll verify the RTC is reachable **/ int8_t Init(void); - + #ifdef DS1337_USE_OSC_INTEGRITY /** - * checkClock: verifies the clock integrity - * Returns false when the integrity check fails + * chockSetIntegrityCallback: allow setting the callback function + * for the oscillator fault check. **/ - boolean checkClock(); - + void clockIntegrityCallback(void (*)(void)); + #endif + #if defined(DS1337_USE_ALARMS_CALLBACK) || defined(DS1337_USE_OSC_INTEGRITY) + /** + * clockChecks: performs various clock checks such as integrity and alarms + * Will trigger the + **/ + void clockChecks(void); + #endif /** * setRegister: sets a register bit fromt he register number and bitmask **/ @@ -260,12 +306,12 @@ class DS1337 * Use the clockSet macro to access this function! **/ void clockSetWithUTS(uint32_t, boolean); - + #ifdef DS1337_DEBUG /** * Prints all of the DS1337 registers **/ - void printRegisters(void); + #endif #ifdef DS1337_USE_ALARMS /** * alarmSelect: allows selection of the DS1337 alarm 1 or 2 @@ -284,6 +330,62 @@ class DS1337 **/ boolean alarmCheck(boolean); boolean alarmCheck(void); // Same as above using false + + #ifdef DS1337_USE_ALARMS_CALLBACK + /** + * alarmSetCallback: allows setting of a callback function associated with alarm + * The function will be passed a boolean indicating which of alarm1 (false) or alarm2 (true) + * triggered the callback + **/ + void alarmSetCallback(void (*)(void)); + + /** + * alarmUnsetCallback: removes the callback function attached to the current alarm + **/ + void alarmUnsetCallback(void); + + /** + * alarmChecks: will trigger the callback function if an alarm is high + * This function need to be placed somewhere in the main loop + **/ + void alarmChecks(void); + #endif + + #ifdef DS1337_USE_ALARM_INTERRUPTS + /** + * alarmDisableInterrupts: disables all alarm interrupts + **/ + void alarmDisableInterrupts(void); + + /** + * alarmSetInterrupt: sets the alarm interrupt for the selected alarm + **/ + void alarmSetInterrupt(void); + + /** + * alarmUnsetInterrupt: disable interrupt for the select alarm + **/ + void alarmUnsetInterrupt(void); + #endif + #endif + + #ifdef DS1337_USE_SQW_OUTPUT + /** + * sqwEnable: Enable the square wave output on SQW/INTB + * If this is enabled and an interrupt is set for alarm 2 + * the interrupt will INTA instead of SQW/INTB + **/ + void sqwEnable(void); + + /** + * sqwDisable: Disables the square wave output on SQW/INTB + **/ + void sqwDisable(void); + + /** + * sqwSetRate: Sets the square wave rate + **/ + void sqwSetRate(uint8_t sqwRate); #endif private: /** @@ -328,7 +430,6 @@ class DS1337 * Hold the buffer for alarm manipulation **/ uint8_t rtc_alarm[4]; - /** * alarmId: keeps track of which alarm we are working with **/ diff --git a/global.h b/global.h index 7b9d230..795dc00 100644 --- a/global.h +++ b/global.h @@ -8,6 +8,7 @@ extern "C" { #include #include + #include "wiring_private.h" #include "wiring.h" #include "WConstants.h" diff --git a/twiLCD/twiLCD.cpp b/twiLCD/twiLCD.cpp index d804fa8..446e676 100644 --- a/twiLCD/twiLCD.cpp +++ b/twiLCD/twiLCD.cpp @@ -193,7 +193,7 @@ void twiLCD::clearScreen(void) #endif #ifdef LCD_USE_CLRSCREEN_CALLBACK - onClearScreen(); + if (twiLCDcallbackFunc[0]) twiLCDcallbackFunc[0](); #endif } @@ -210,7 +210,7 @@ void twiLCD::printString_P(const char *data) #if defined(__AVR_ATmega168__) && !defined(TWI_LCD_SMALL) #ifdef TWI_LCD_USE_TIMEOUT -bool twiLCD::checkTimeout(void) +boolean twiLCD::checkTimeout(void) { if (displayStatus && millis() - previousMillis > TWI_LCD_TIMEOUT) { turnOff(); @@ -425,3 +425,10 @@ void twiLCD::printInteger(int16_t integer) } #endif + +#ifdef LCD_USE_CLRSCREEN_CALLBACK +void twiLCD::setClrscreenCallback(void (*userFunc)(void)) +{ + twiLCDcallbackFunc[0] = userFunc; +} +#endif diff --git a/twiLCD/twiLCD.h b/twiLCD/twiLCD.h index 86aabd7..7300ade 100644 --- a/twiLCD/twiLCD.h +++ b/twiLCD/twiLCD.h @@ -1,8 +1,8 @@ #ifndef twiLCD_H - #define twiLCD_H - - #include +#define twiLCD_H + #include "../global.h" + #include "../configs/LCD/lcd.h" #include "twiLCDConfig.h" #define PCF8574_WADDR 0x20 @@ -29,6 +29,10 @@ #define printString(str) printString_P(PSTR(str)) #endif +#ifdef LCD_USE_CLRSCREEN_CALLBACK + volatile static voidFuncPtr twiLCDcallbackFunc[1]; +#endif + class twiLCD { public: /** @@ -39,24 +43,28 @@ /** * LCD Initilization method **/ - void Init(); + void Init(); /** * writeData: write a byte of data to the LCD * @param: value: the byte to write **/ - void writeData(uint8_t value); + void writeData(uint8_t); /** * clearScreen: clears the LCD and resets the cursor position to 0,0 **/ - void clearScreen(void); + 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); + void printString_P(const char *); + + #ifdef LCD_USE_CLRSCREEN_CALLBACK + void setClrscreenCallback(void (*)(void)); + #endif /** * These function are only available on the mega168 for space reasons **/ @@ -67,7 +75,7 @@ * Returns true if the time is expired **/ #ifdef TWI_LCD_USE_TIMEOUT - bool checkTimeout(void); + boolean checkTimeout(void); #endif /** @@ -78,12 +86,12 @@ /** * backlightOn: Turn on the backlight at full brightness **/ - void backlightOn(void); + void backlightOn(void); /** * backlightOff: turn off the LCD backlight **/ - void backlightOff(void); + void backlightOff(void); // PWM Backlight Control #if defined(TWI_LCD_BL_PWM) || defined(TWI_LCD_DPOT_CTRL) diff --git a/twiLCD/twiLCDConfig.h b/twiLCD/twiLCDConfig.h index 6ddf4dd..8d5754f 100644 --- a/twiLCD/twiLCDConfig.h +++ b/twiLCD/twiLCDConfig.h @@ -36,7 +36,10 @@ #define TWI_LCD_DB_LEVEL 225 #endif #endif +// End LCD Control #endif + +// End Small version #endif #endif