root/ds1337/ds1337.cpp

Revision 12, 14.8 KB (checked in by mlalondesvn, 15 months ago)

DS1624:

ADDED - Support for read/write to the EEPROM
ADDED - DS1624_USE_EEPROM Define in the config to enable eeprom functions
MODIF - Moved the start/stop conversion routine to the start/stopConversion() functions


DS1803 & DS1337:

FIXED - Removed r/w addresses and changed for single address

Line 
1extern "C" {
2    #include <Wire/Wire.h>
3}
4
5#include "ds1337.h"
6
7// Internal macro for storing month days!
8#ifndef GETMONTHDAYS
9PROGMEM prog_uint16_t   monthcount[] = {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
10#define GETMONTHDAYS(index) (pgm_read_word_near(monthcount + index))
11#endif
12
13#ifndef CI
14    #define CI(reg,bit)     (reg & ~(bit))
15#endif
16
17#ifndef SI
18    #define SI(reg,bit)     (reg | bit)
19#endif
20
21DS1337::DS1337()
22{       
23    clockExists = false;
24    alarmId     = false;
25   
26#ifdef WIRE_LIB_SCAN_MOD
27    /*if (!Wire.isStarted()) */Wire.begin();
28#else
29    Wire.begin();
30#endif
31}
32
33DS1337 RTC = DS1337();
34
35#ifdef WIRE_LIB_SCAN_MOD
36int8_t DS1337::Init(void)
37{
38    delay(500); //Account for the crystal startup time
39   
40    // Check address and returns false is there is an error
41    if (Wire.checkAddress(DS1337_ADDR)) {
42        // Possibly set the default registers here
43       
44        clockExists = true;
45       
46        // Start the oscillator if need
47        if (getRegisterBit(DS1337_SP, DS1337_SP_EOSC) || getRegisterBit(DS1337_STATUS, DS1337_STATUS_OSF))
48        {
49            clockStart();
50           
51        #if defined(DS1337_USE_ALARM_INTERRUPTS) && !defined(DS1337_USE_SQW_OUTPUT)
52            setRegister(DS1337_SP, DS1337_SQW_INTCN);
53        #endif
54        }
55       
56        return DS1337_ADDR;
57    } else clockExists  = false;
58   
59    return -1; 
60}
61#else
62int8_t DS1337::Init(void)
63{
64    delay(500); //Account for the crystal startup time
65   
66    clockExists = true;
67   
68    // Start the oscillator if need
69    if (getRegisterBit(DS1337_SP, DS1337_SP_EOSC) || getRegisterBit(DS1337_STATUS, DS1337_STATUS_OSF))
70    {   
71        clockStart();
72    }
73   
74    return DS1337_ADDR;
75}
76#endif
77
78void DS1337::setRegister(uint8_t registerNumber, uint8_t registerMask)
79{
80    writeRegister(registerNumber, SI(getRegister(registerNumber), registerMask));
81}
82
83void DS1337::unsetRegister(uint8_t registerNumber, uint8_t registerMask)
84{
85    writeRegister(registerNumber, CI(getRegister(registerNumber), registerMask));
86}
87
88void DS1337::writeRegister(uint8_t registerNumber, uint8_t registerValue)
89{
90    if (!clockExists) return;
91   
92    Wire.beginTransmission(DS1337_ADDR);
93    Wire.send(registerNumber);
94   
95    Wire.send(registerValue);
96   
97    Wire.endTransmission();
98}
99
100uint8_t DS1337::getRegister(uint8_t registerNumber)
101{
102    if (!clockExists) return 0;
103   
104    Wire.beginTransmission(DS1337_ADDR);
105    Wire.send(registerNumber);
106    Wire.endTransmission();
107   
108    Wire.requestFrom(DS1337_ADDR, 1);
109   
110    while (!Wire.available());
111   
112    return Wire.receive();
113}
114
115void DS1337::clockStart(void)
116{
117    // Start the oscillator
118    unsetRegister(DS1337_SP, DS1337_SP_EOSC);
119   
120    // Reset the status register
121    writeRegister(DS1337_STATUS, B00000000);
122}
123
124void DS1337::clockRead(void)
125{
126    if (!clockExists) return;
127   
128    Wire.beginTransmission(DS1337_ADDR);
129    Wire.send(0x00);
130    Wire.endTransmission();
131
132    Wire.requestFrom(DS1337_ADDR, 7);
133    while (!Wire.available());
134   
135    for(int i=0; i<7; i++)
136    {
137        if (Wire.available())
138            rtc_bcd[i]  = Wire.receive();
139    }
140}
141
142void DS1337::clockSave(void)
143{
144    if (!clockExists) return;
145   
146    // Stop the clock
147    clockStop();
148   
149    Wire.beginTransmission(DS1337_ADDR);
150    Wire.send(0x00);
151   
152    for(int i=0; i<7; i++)
153    {
154        Wire.send(rtc_bcd[i]);
155    }
156   
157    Wire.endTransmission();
158   
159    // Restart the oscillator
160    clockStart();
161}
162
163void DS1337::clockGet(uint16_t *rtc)
164{
165    clockRead();
166   
167    for(int i=0;i<8;i++)  // cycle through each component, create array of data
168    {
169        rtc[i]=clockGet(i, 0);
170    }
171}
172
173uint16_t DS1337::clockGet(uint8_t c, boolean refresh)
174{
175    if(refresh) clockRead();
176   
177    int timeValue=-1;
178    switch(c)
179    {
180        case DS1337_SEC:
181            timeValue = bcdToBin(DS1337_SEC, DS1337_HI_SEC);
182        break;
183        case DS1337_MIN:
184            timeValue = bcdToBin(DS1337_MIN, DS1337_HI_MIN);
185        break;
186        case DS1337_HR:
187            timeValue = bcdToBin(DS1337_HR, DS1337_HI_HR);
188        break;
189        case DS1337_DOW:
190            timeValue = rtc_bcd[DS1337_DOW] & DS1337_LO_DOW;
191        break;
192        case DS1337_DATE:
193            timeValue = bcdToBin(DS1337_DATE, DS1337_HI_DATE);
194        break;
195        case DS1337_MTH:
196            timeValue = CI(bcdToBin(DS1337_MTH, DS1337_HI_MTH), DS1337_LO_CNTY);
197        break;
198        case DS1337_YR:
199            timeValue = bcdToBin(DS1337_YR, DS1337_HI_YR)+(1900 + (rtc_bcd[DS1337_MTH] & DS1337_LO_CNTY ? 100 : 0));
200        break;
201        case DS1337_CNTY:
202            timeValue = rtc_bcd[DS1337_MTH] & DS1337_LO_CNTY>>7;
203        break;
204    } // end switch
205   
206    return timeValue;
207}
208
209#ifdef DS1337_USE_BCD_CLOCKSET
210void DS1337::clockSet(uint8_t timeSection, uint16_t timeValue)
211{
212    switch(timeSection)
213    {
214        case DS1337_SEC:
215        if(timeValue<60)
216        {
217            rtc_bcd[DS1337_SEC]     = binToBcd(timeValue);
218        }
219        break;
220       
221        case DS1337_MIN:
222        if(timeValue<60)
223        {
224            rtc_bcd[DS1337_MIN]     = binToBcd(timeValue);
225        }
226        break;
227       
228        case DS1337_HR:
229        // TODO : AM/PM  12HR/24HR
230        if(timeValue<24)
231        {
232            rtc_bcd[DS1337_HR]      = binToBcd(timeValue);
233        }
234        break;
235       
236        case DS1337_DOW: 
237        if(timeValue<8)
238        {
239            rtc_bcd[DS1337_DOW]     = timeValue;
240        }
241        break;
242       
243        case DS1337_DATE:
244        if(timeValue<31)
245        {
246            rtc_bcd[DS1337_DATE]    = binToBcd(timeValue);
247        }
248        break;
249       
250        case DS1337_MTH:
251        if(timeValue<13)
252        {
253            rtc_bcd[DS1337_MTH]     = SI(CI(binToBcd(timeValue),DS1337_LO_CNTY), (rtc_bcd[DS1337_MTH] & DS1337_LO_CNTY));
254        }
255        break;
256       
257        case DS1337_YR:
258        if(timeValue<1000)
259        {
260            rtc_bcd[DS1337_YR]      = binToBcd(timeValue);
261        }
262        break;
263       
264        case DS1337_CNTY:
265        if (timeValue > 0)
266        {
267            rtc_bcd[DS1337_MTH]     = SI(rtc_bcd[DS1337_MTH], DS1337_LO_CNTY);
268        } else {
269            rtc_bcd[DS1337_MTH]     = CI(rtc_bcd[DS1337_MTH], DS1337_LO_CNTY);
270        }
271        break;
272    } // end switch
273       
274    clockSave();
275}
276#endif
277
278#ifdef DS1337_USE_GET_UTS
279uint32_t DS1337::calculateUTS(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec)
280{
281    // Number of days per month
282    // Compute days
283    tt = (year - 1970) * 365 + GETMONTHDAYS(month) + day - 1;
284   
285    // Compute for leap year
286    for (month <= 2 ? year-- : 0; year >= 1970; year--)
287        if (ISLEAP(year))
288            tt++;
289   
290    // Plus the time
291    tt = sec + 60 * (min + 60 * (tt * 24 + hour - RTC_GMT_OFFSET));
292   
293    return tt;
294}
295#endif
296
297#ifdef DS1337_USE_SET_UTS
298void DS1337::clockSetWithUTS(uint32_t unixTimeStamp, boolean correctedTime)
299{
300    int8_t      ii;
301    uint16_t    year;
302    uint16_t    *yrPtr  = &year;
303    uint16_t    thisYear;
304    uint16_t    *tyPtr  = &thisYear;
305#if defined(RTC_DST_TYPE)
306    uint8_t     thisDate;
307    uint8_t     *tdPtr  = &thisDate;
308#endif
309   
310    // Serial.print((uint32_t)unixTimeStamp, DEC); delay(5); SPrint(" ");
311   
312    /**
313     * Calculate GMT and DST
314    **/
315#if defined(RTC_GMT_OFFSET)
316    if (!correctedTime) unixTimeStamp = (uint32_t)unixTimeStamp + (RTC_GMT_OFFSET * 3600);
317#endif
318   
319    // Years
320    tt          = (uint32_t)unixTimeStamp / 3600 / 24 / 365;
321    year        = tt + 1970;
322   
323    thisYear    = year;
324   
325    // Set the century bit
326    if (tt > 30) {
327        rtc_bcd[DS1337_MTH] = SI(rtc_bcd[DS1337_MTH], DS1337_LO_CNTY);
328        tt-= 30;
329    } else {
330        rtc_bcd[DS1337_MTH] = CI(rtc_bcd[DS1337_MTH], DS1337_LO_CNTY);
331    }
332   
333    // Set the year
334    rtc_bcd[DS1337_YR]      = binToBcd(tt);
335   
336    // Number of days left in the year
337    // Serial.print((uint32_t)unixTimeStamp, DEC); delay(5); SPrint(" "); delay(5);
338    // Serial.print((uint32_t)unixTimeStamp%31536000, DEC); delay(5); SPrint(" "); delay(5);
339    tt = ((uint32_t)(uint32_t)unixTimeStamp%31536000 / 3600 / 24) + 1;
340   
341    // Serial.print(tt, DEC); delay(5); SPrint(" "); delay(5);
342   
343    // leap year correction
344    for (year--; year > 1970; year--) {
345        if (ISLEAP(year))
346        {
347            tt--;
348        }
349    }
350   
351    free(yrPtr);
352   
353    // Serial.print(tt, DEC); SPrint(" ");
354   
355    // Grab the number of previous days, account for leap years, and save the month
356    for (ii = 1; ii < 12; ii++)
357    {
358        if (( GETMONTHDAYS(ii+1) + ((ISLEAP(thisYear) && ii >= 2) ? 1 : 0) ) > tt)
359        {
360            rtc_bcd[DS1337_MTH]     = SI(CI(binToBcd(ii), DS1337_LO_CNTY), (rtc_bcd[DS1337_MTH] & DS1337_LO_CNTY));
361            break;
362        }
363    }
364    // Serial.print(ii, DEC);
365    // SPrint(" ");
366   
367    // Date
368#if defined(RTC_DST_TYPE)
369    if (!correctedTime) {
370        thisDate = tt - (GETMONTHDAYS(ii) + ((ISLEAP(thisYear) && ii >= 2) ? 1 : 0));
371    }
372#endif
373   
374    // Date
375    rtc_bcd[DS1337_DATE]    = binToBcd( tt - (GETMONTHDAYS(ii) + ((ISLEAP(thisYear) && ii >= 2) * 1)) );
376    // Serial.print( tt - (GETMONTHDAYS(ii) + ((ISLEAP(thisYear) && ii >= 2) * 1)) , DEC);
377    // SPrint(" ");
378   
379    // Day of the week
380    rtc_bcd[DS1337_DOW]     = ((tt)%7 + 1) & DS1337_LO_DOW;
381    // Serial.print(((tt)%7 + 1) & DS1337_LO_DOW, DEC);
382    // SPrint(" ");
383   
384    // Hour
385    tt = (uint32_t)unixTimeStamp%86400 / 3600;
386    rtc_bcd[DS1337_HR]      = binToBcd(tt);
387    // Serial.print(tt, DEC);
388    // SPrint(" ");
389   
390#if defined(RTC_DST_TYPE)
391    if (!correctedTime) {
392        uint8_t dstStartMo, dstStopMo, dstStart, dstStop;
393        uint8_t *dstStartMoPtr  = &dstStartMo;
394        uint8_t *dstStopMoPtr   = &dstStopMo;
395        uint8_t *dstStartPtr    = &dstStart;
396        uint8_t *dstStopPtr     = &dstStop;
397       
398    #ifndef RTC_CHECK_OLD_DST
399        dstStart    = DSTCALCULATION1(thisYear);
400    #if RTC_DST_TYPE == 1
401        dstStop     = DSTCALCULATION1(thisYear);    // EU DST
402    #else
403        dstStop     = DSTCALCULATION2(thisYear);    // US DST
404    #endif
405        dstStartMo  = 3;
406        dstStopMo   = 11;
407    #else
408        if (thisYear < RTC_DST_OLD_YEAR) {
409            dstStart    = ((2+6 * thisYear - (thisYear / 4) ) % 7 + 1);
410            dstStop     = (14 - ((1 + thisYear * 5 / 4) % 7));
411            dstStartMo  = 4;
412            dstStopMo   = 10;
413        } else {
414            dstStart    = DSTCALCULATION1(thisYear)
415        #if RTC_DST_TYPE == 1
416            dstStop     = DSTCALCULATION1(thisYear) // EU DST
417        #else
418            dstStop     = DSTCALCULATION2(thisYear);    // US DST
419        #endif
420            dstStartMo  = 3;
421            dstStopMo   = 11;
422        }
423    #endif
424        if (ii >= dstStartMo && ii <= dstStopMo)
425        {
426            if ( (ii < dstStopMo && (ii > dstStartMo || thisDate > dstStart || thisDate == dstStart && tt >= 2)) ||
427                 (thisDate < dstStop || thisDate == dstStop && tt < 2) )
428            {
429                /**
430                 * Free as much memory as possible before entering recursion
431                **/
432                free(tyPtr);
433                free(tdPtr);
434                free(dstStopPtr);
435                free(dstStartPtr);
436                free(dstStopMoPtr);
437                free(dstStartMoPtr);
438               
439                clockSetWithUTS((uint32_t)unixTimeStamp + 3600, true);
440                return;
441            }
442        }
443    }
444#endif
445   
446    // Minutes
447    tt = (uint32_t)unixTimeStamp%3600 / 60;
448    rtc_bcd[DS1337_MIN]     = binToBcd(tt);
449    // Serial.print(tt, DEC);
450    // SPrint(" ");
451   
452    // Seconds
453    tt = ((uint32_t)unixTimeStamp%3600)%60;
454    rtc_bcd[DS1337_SEC]     = binToBcd(tt);
455    // Serial.print(tt, DEC);
456    // SPrint(" ");
457   
458    // Save buffer to the RTC
459    clockSave();
460}
461#endif
462
463uint8_t DS1337::bcdToBin(uint8_t index, uint8_t hi)
464{
465    return (10*((rtc_bcd[index] & hi)>>4))+(rtc_bcd[index] & DS1337_LO_BCD);
466}
467uint8_t DS1337::binToBcd(uint8_t val)
468{
469    return ((((val)/10)<<4) + (val)%10);
470}
471
472/**
473 * Alarm support functions
474**/
475#ifdef DS1337_USE_ALARMS
476void DS1337::alarmSelect(boolean alarm)
477{
478    alarmId = alarm;
479    return;
480}
481
482#ifdef DS1337_USE_ALARMS_CALLBACK
483void DS1337::alarmSetCallback(void (*userFunc)(void))
484{
485    DS1337callbackFunc[(alarmId ? 1 : 0)] = userFunc;
486}
487
488void DS1337::alarmUnsetCallback(void)
489{
490    DS1337callbackFunc[(alarmId ? 1 : 0)] = 0;
491}
492
493void DS1337::alarmChecks(void)
494{
495    if (getRegisterBit(DS1337_STATUS, DS1337_STATUS_A1F))
496    {
497        if (DS1337callbackFunc[0]) DS1337callbackFunc[0]();
498        unsetRegister(DS1337_STATUS, DS1337_STATUS_A1F);
499    }
500   
501    if (getRegisterBit(DS1337_STATUS, DS1337_STATUS_A2F))
502    {
503        if (DS1337callbackFunc[1]) DS1337callbackFunc[1]();
504        unsetRegister(DS1337_STATUS, DS1337_STATUS_A2F);
505    }
506   
507    return;
508}
509#endif
510
511void DS1337::alarmSet(uint8_t timeSection, uint8_t timeValue)
512{
513    if (timeSection > DS1337_ALARM_DT)          return;
514   
515    if (alarmId == true) rtc_alarm[DS1337_SEC]  = 0;
516   
517    switch(timeSection)
518    {
519        case DS1337_SEC:
520        if(alarmId == false && timeValue<60)
521        {
522            rtc_alarm[DS1337_SEC]           = (binToBcd(timeValue) & ~DS1337_ALARM_MASK) | (rtc_alarm[DS1337_SEC] & DS1337_ALARM_MASK);
523        }
524        break;
525       
526        case DS1337_MIN:
527        if(timeValue < 60)
528        {
529            rtc_alarm[DS1337_MIN]           = (binToBcd(timeValue) & ~DS1337_ALARM_MASK) | (rtc_alarm[DS1337_MIN] & DS1337_ALARM_MASK);
530        }
531        break;
532       
533        case DS1337_HR:
534        if(timeValue < 24)
535        {
536            rtc_alarm[DS1337_HR]            = (binToBcd(timeValue) & ~DS1337_ALARM_MASK) | (rtc_alarm[DS1337_HR] & DS1337_ALARM_MASK);
537        }
538        break;
539       
540        case DS1337_DOW: 
541        if(timeValue < 31)
542        {
543            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);
544        }
545        break;
546       
547        case DS1337_ALARM_MODE:
548        {
549            if (alarmId) {
550                timeValue                   = (timeValue>>1)<<1;
551            } else
552                // A1M1
553                rtc_alarm[DS1337_SEC]       = (rtc_alarm[DS1337_SEC] & ~DS1337_ALARM_MASK)  | DS1337_ALARM_MASK & timeValue<<7;
554           
555            // AM2
556            rtc_alarm[DS1337_MIN]           = (rtc_alarm[DS1337_MIN] & ~DS1337_ALARM_MASK)  | DS1337_ALARM_MASK & timeValue<<6;
557            // AM3
558            rtc_alarm[DS1337_HR]            = (rtc_alarm[DS1337_HR] & ~DS1337_ALARM_MASK)   | DS1337_ALARM_MASK & timeValue<<5;
559            // AM4
560            rtc_alarm[DS1337_DOW]           = (rtc_alarm[DS1337_DOW] & ~DS1337_ALARM_MASK)  | DS1337_ALARM_MASK & timeValue<<4;
561           
562            if (timeValue == DS1337_ALARM_MCH_DOWHRMINSEC || timeValue == DS1337_ALARM_MCH_DOWHRMIN)
563            {
564                rtc_alarm[DS1337_DOW]       = (rtc_alarm[DS1337_DOW] & ~DS1337_ALARM_DT_MASK)   | DS1337_ALARM_DT_MASK;
565            }
566        }
567       
568        break;
569       
570        case DS1337_ALARM_DT:
571        {
572            rtc_alarm[DS1337_DOW]           = (rtc_alarm[DS1337_DOW] & ~DS1337_ALARM_DT_MASK) | (timeValue == 1 ? DS1337_ALARM_DT_MASK : 0);
573        }
574        break;
575    } // end switch
576   
577    alarmSave();
578}
579
580boolean DS1337::alarmCheck(void)
581{
582    if (getRegisterBit(DS1337_STATUS, (alarmId == false ? DS1337_STATUS_A1F : DS1337_STATUS_A2F)))
583    {
584        unsetRegister(DS1337_STATUS, (alarmId == false ? DS1337_STATUS_A1F : DS1337_STATUS_A2F));
585       
586        return true;
587    }
588   
589    return false;
590}
591
592void DS1337::alarmSave(void)
593{
594    Wire.beginTransmission(DS1337_ADDR);
595    Wire.send((alarmId == false ? DS1337_ALARM1 : DS1337_ALARM2));
596   
597    for(uint8_t i=(alarmId == false ? 0 : 1); i<4; i++)
598    {
599        Wire.send(rtc_alarm[i]);
600    }
601   
602    Wire.endTransmission();
603   
604    delay(5);
605}
606
607#ifdef DS1337_USE_ALARM_INTERRUPTS
608void DS1337::alarmDisableInterrupts(void)
609{
610    unsetRegister(DS1337_SP, DS1337_ALARM_INT1);
611    unsetRegister(DS1337_SP, DS1337_ALARM_INT2);
612   
613    return;
614}
615
616void DS1337::alarmSetInterrupt(void)
617{
618#ifndef DS1337_USE_SQW_OUTPUT
619    if (alarmId) setRegister(DS1337_SP, DS1337_SQW_INTCN);
620#endif
621   
622    setRegister(DS1337_SP, (alarmId == false ? DS1337_ALARM_INT1 : DS1337_ALARM_INT2));
623   
624    return;
625}
626
627void DS1337::alarmUnsetInterrupt(void)
628{
629    unsetRegister(DS1337_SP, (alarmId == false ? DS1337_ALARM_INT1 : DS1337_ALARM_INT2));
630   
631    return;
632}
633#endif
634#endif
635
636#ifdef DS1337_USE_SQW_OUTPUT
637void DS1337::sqwEnable(void)
638{
639    unsetRegister(DS1337_SP, DS1337_SQW_INTCN);
640    return; 
641}
642
643void DS1337::sqwDisable(void)
644{
645    setRegister(DS1337_SP, DS1337_SQW_INTCN);
646    return; 
647}
648
649void DS1337::sqwSetRate(uint8_t sqwRate)
650{
651    writeRegister(DS1337_SP, (getRegisterSP() & ~DS1337_SQW_RS | sqwRate));
652   
653    return;
654}
655#endif
656
657#ifdef DS1337_USE_OSC_INTEGRITY
658void DS1337::clockIntegrityCallback(void (*userFunc)(void))
659{
660    DS1337callbackFunc[2]   = userFunc;
661}
662#endif
663
664#if defined(DS1337_USE_ALARMS_CALLBACK) || defined(DS1337_USE_OSC_INTEGRITY)
665void DS1337::clockChecks(void)
666{
667#ifdef DS1337_USE_OSC_INTEGRITY
668    if (getRegisterBit(DS1337_STATUS, DS1337_STATUS_OSF) && !getRegisterBit(DS1337_SP, DS1337_SP_EOSC))
669    {
670        clockStop();
671       
672        if (DS1337callbackFunc[2]) DS1337callbackFunc[2]();
673       
674        return;
675    }
676#endif
677#ifdef DS1337_USE_ALARMS_CALLBACK
678    alarmChecks();
679#endif
680}
681#endif
682
683#ifdef DS1337_DEBUG
684void DS1337::printRegisters(void)
685{
686    for(int ii=0;ii<0x10;ii++)
687    {
688        SPrint("0x");
689        Serial.print(ii, HEX);
690        SPrint(" ");
691        Serial.println(getRegister(ii), BIN);
692    }
693   
694    delay(200);
695}
696#endif
Note: See TracBrowser for help on using the browser.