From 699f7c626fe5fc35ea9fb5042b945d937ff9b64b Mon Sep 17 00:00:00 2001 From: johanknol Date: Fri, 2 Feb 2001 09:49:30 +0000 Subject: [PATCH] just another tini example git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@557 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- device/examples/rtc390/Makefile | 19 +++ device/examples/rtc390/lcd.c | 166 ++++++++++++++++++++++++ device/examples/rtc390/lcd.h | 12 ++ device/examples/rtc390/rtc390.c | 215 ++++++++++++++++++++++++++++++++ 4 files changed, 412 insertions(+) create mode 100755 device/examples/rtc390/Makefile create mode 100644 device/examples/rtc390/lcd.c create mode 100644 device/examples/rtc390/lcd.h create mode 100755 device/examples/rtc390/rtc390.c diff --git a/device/examples/rtc390/Makefile b/device/examples/rtc390/Makefile new file mode 100755 index 00000000..484bceab --- /dev/null +++ b/device/examples/rtc390/Makefile @@ -0,0 +1,19 @@ +CC = sdcc + +MFLAGS = -mds390 --model-flat24 --stack-10bit +LFLAGS = --xram-loc 0x100080 --code-loc 0x10000 -Wl-r + +OBJECTS = rtc390.rel lcd.rel + +all: rtc390.hex + +clean: + rm -f *~ \#* *.asm *.cdb *.rel *.hex *.ihx *.lst *.map *.rst *.sym *.lnk + +rtc390.hex: $(OBJECTS) + $(CC) $(MFLAGS) $(LFLAGS) $(OBJECTS) + packihx rtc390.ihx >rtc390.hex + #tinitalk -c execute rtc390.hex + +%.rel: %.c + $(CC) -c $(MFLAGS) -I . $< diff --git a/device/examples/rtc390/lcd.c b/device/examples/rtc390/lcd.c new file mode 100644 index 00000000..1c079fbc --- /dev/null +++ b/device/examples/rtc390/lcd.c @@ -0,0 +1,166 @@ +/*------------------------------------------------------------------------- + lcd.c - lcd routines for the DS80C390 (tested on TINI) + + Written By - Johan Knol, johan.knol@iduna.nl + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +#include +#include +#include "lcd.h" + +#define LCD_ROWS 4 +#define LCD_COLLUMNS 20 + +xdata at 0x380002 static unsigned char lcdIwr; +xdata at 0x38000a static unsigned char lcdDwr; + +#ifdef LCD_RW + +xdata at 0x380003 static unsigned char lcdIrd; +xdata at 0x38000b static unsigned char lcdDrd; + +#define LcdWait { while (lcdIrd&0x80) ; } + +#else ifdef LCD_RW + +// wait for 100us +#define LcdWait { ClockMicroSecondsDelay(100) ; } + +#endif ifdef LCD_RW + +// set the dd ram addresses for the rows +// this one is for a 20x4 LCD +xdata static unsigned char lcdLinesStart[LCD_ROWS]={0, 0x40, 0x14, 0x54}; + +void LcdInit() { + + ClockMilliSecondsDelay(16); // >15 ms + + lcdIwr=0x38 ; + ClockMilliSecondsDelay(5); // >4.1 ms + + lcdIwr=0x38; + ClockMicroSecondsDelay(101); // >100 us + + lcdIwr=0x38; + ClockMicroSecondsDelay(101); // >100 us + + lcdIwr=0x38; // interface 8 bit + ClockMicroSecondsDelay(41); // >40 us + + lcdIwr=0x0c; // display on + ClockMicroSecondsDelay(41); // >40 us + + LcdClear(); +} + +void LcdOn() { + lcdIwr=0x0c; // display on + LcdWait; +} + +void LcdOff() { + lcdIwr=0x08; // display off + LcdWait; +} + +void LcdCursorOn() { + // TODO +} + +void LcdCursorOff() { + // TODO +} + +void LcdScrollOn() { + // TODO +} + +void LcdScrollOff() { + // TODO +} + +void LcdCharDefine() { + // TODO +} + +void LcdClear() { + lcdIwr=0x01; // display clear + ClockMilliSecondsDelay(6); // > 5ms +} + +void LcdHome() { + lcdIwr=0x80; // set dd ram address 0 + LcdWait; +} + +void LcdGoto(unsigned int collumnRow) { // msb=collumn, lsb=row + lcdIwr=0x80 + \ + lcdLinesStart[collumnRow&0xff] + (collumnRow>>8); + LcdWait; +} + +void LcdPutChar(char c) { + lcdDwr=c; + LcdWait; +} + +void LcdPutString (char *string) { + char c; + while (c=*string++) { + LcdPutChar (c); + } +} + +void LcdLPutString (unsigned int collumnRow, char *string) { + LcdGoto(collumnRow); + LcdPutString(string); +} + +// let's hope that no one ever printf's more than the display width, +// however they will :), so to be sure +static char lcdPrintfBuffer[LCD_COLLUMNS*4]; + +void LcdPrintf (xdata const char *format, ...) reentrant { + va_list arg; + + va_start (arg, format); + vsprintf (lcdPrintfBuffer, format, arg); + puts (lcdPrintfBuffer); + LcdPutString(lcdPrintfBuffer); + + va_end (arg); +} + +void LcdLPrintf (unsigned int collumnRow, xdata const char *format, ...) reentrant { + va_list arg; + + LcdGoto(collumnRow); + + // we can not just call LcdPrintf since we have no idea what is on the stack, + // so we have to do it all over again + va_start (arg, format); + vsprintf (lcdPrintfBuffer, format, arg); + + LcdPutString(lcdPrintfBuffer); + + va_end (arg); +} diff --git a/device/examples/rtc390/lcd.h b/device/examples/rtc390/lcd.h new file mode 100644 index 00000000..d14699ea --- /dev/null +++ b/device/examples/rtc390/lcd.h @@ -0,0 +1,12 @@ +extern void LcdInit(void); +extern void LcdOn(void); +extern void LcdOff(void); +extern void LcdClear(void); +extern void LcdHome(void); +extern void LcdGoto(unsigned int collumnRow); +extern void LcdPutChar(char c); +extern void LcdPutString(char *string); +extern void LcdLPutString(unsigned int collumnRow, char *string); +extern void LcdPrintf(xdata const char *format, ...) reentrant; +extern void LcdLPrintf(unsigned int collumnRow, xdata const char *format, ...) reentrant; + diff --git a/device/examples/rtc390/rtc390.c b/device/examples/rtc390/rtc390.c new file mode 100755 index 00000000..6c45191d --- /dev/null +++ b/device/examples/rtc390/rtc390.c @@ -0,0 +1,215 @@ +/*------------------------------------------------------------------------- + rtc390.c - rtc routines for the DS1315 (tested on TINI) + + Written By - Johan Knol, johan.knol@iduna.nl + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +#include + +#include +#include + +//#define USE_LCD + +#ifdef USE_LCD +#include "lcd.h" +#endif + +/* this is the address of the ds1315 phantom time chip, although + it doesn't really matter as long as it's in the 300000-3ffff + range since the chip only uses CE3* +*/ + +xdata at 0x310000 static volatile unsigned char rtc; + +// this is the 64bit pattern that has to be recognized by the ds1315 +code unsigned char rtcMagic[8]={0xc5,0x3a,0xa3,0x5c,0xc5,0x3a,0xa3,0x5c}; + +static struct RTCDate{ + int year; + unsigned char month, day, weekDay, hour, minute, second, hundredth; +}; + +#define BCDtoINT(x) (((x)&0x0f)+((x)>>4)*10) +#define INTtoBCD(x) (((x)%10)+(((x)/10)<<4)) + +void RtcSync(void) { + unsigned char dummy, byte,bitMask; + + // reset rtc chip + dummy=rtc; + + // say the magic word + for (byte=0; byte<8; byte++) { + for (bitMask=0x01; bitMask; bitMask<<=1) { + rtc = (rtcMagic[byte]&bitMask) ? 0xff : 0x00; + } + } +} + +unsigned char RtcRead(struct RTCDate *rtcDate) { + unsigned char rtcBytes[8]; + unsigned char byte,bitMask; + + RtcSync(); + + for (byte=0; byte<8; byte++) { + rtcBytes[byte]=0; + for (bitMask=0x01; bitMask; bitMask<<=1) { + if (rtc&1) { + rtcBytes[byte]|=bitMask; + } + } + } + rtcDate->year=2000 + BCDtoINT(rtcBytes[7]); + rtcDate->month=BCDtoINT(rtcBytes[6]); + rtcDate->day=BCDtoINT(rtcBytes[5]); + rtcDate->weekDay=rtcBytes[4]&0x07; + rtcDate->hour=BCDtoINT(rtcBytes[3]); + rtcDate->minute=BCDtoINT(rtcBytes[2]); + rtcDate->second=BCDtoINT(rtcBytes[1]); + rtcDate->hundredth=BCDtoINT(rtcBytes[0]); + if ((rtcBytes[4]&0x30) || (rtcBytes[3]&0x80)) { + //oscillator not running, reset not active or in 12h mode + return 0; + } + return 1; +} + +void RtcWrite(struct RTCDate *rtcDate) { + unsigned char rtcBytes[8]; + unsigned char byte,bitMask; + + rtcBytes[7]=INTtoBCD(rtcDate->year-2000); + rtcBytes[6]=INTtoBCD(rtcDate->month); + rtcBytes[5]=INTtoBCD(rtcDate->day); + rtcBytes[4]=INTtoBCD(rtcDate->weekDay)&0x07; //set 24h mode + rtcBytes[3]=INTtoBCD(rtcDate->hour)&0x3f; // oscilator on, reset on + rtcBytes[2]=INTtoBCD(rtcDate->minute); + rtcBytes[1]=INTtoBCD(rtcDate->second); + rtcBytes[0]=INTtoBCD(rtcDate->hundredth); + + RtcSync(); + + for (byte=0; byte<8; byte++) { + for (bitMask=0x01; bitMask; bitMask<<=1) { + rtc = (rtcBytes[byte]&bitMask) ? 0xff : 0x00; + } + } +} + +int ScanInt(int current) { + char reply[32], *r; + + gets(reply); + if (isdigit(*(r=reply))) { + current=0; + do { + current*=10; + current+=(*r++)-'0'; + } while (isdigit(*r)); + } + return current; +} + +char GetTime(struct RTCDate *rtcDate) { + printf ("Enter year [%d]: ", rtcDate->year); + rtcDate->year=ScanInt(rtcDate->year); + printf ("Enter month [%d]: ", rtcDate->month); + rtcDate->month=ScanInt(rtcDate->month); + printf ("Enter day [%d]: ", rtcDate->day); + rtcDate->day=ScanInt(rtcDate->day); + printf ("Enter hour [%d]: ", rtcDate->hour); + rtcDate->hour=ScanInt(rtcDate->hour); + printf ("Enter minute [%d]: ", rtcDate->minute); + rtcDate->minute=ScanInt(rtcDate->minute); + printf ("Enter second [%d]: ", rtcDate->second); + rtcDate->second=ScanInt(rtcDate->second); + rtcDate->hundredth=0; +} + +void PrintTime(struct RTCDate *rtcDate) { + printf ("%04d-%02bd-%02bd %02bd:%02bd:%02bd.%02bd\n", + rtcDate->year, rtcDate->month, rtcDate->day, + rtcDate->hour, rtcDate->minute, rtcDate->second, + rtcDate->hundredth); +} + +unsigned int intmul(unsigned int a, unsigned int b) { + return a*b; +} + +long longmul(long a, long b) { + return a*b; +} + +void main (void) { + struct RTCDate rtcDate; + unsigned char seconds=0xff; + + printf ("\nStarting RTC demo.\n"); + +#ifdef USE_LCD + LcdInit(); + LcdLPrintf (0, "Starting RTC demo."); +#endif + + while(1) { + RtcRead(&rtcDate); + +#ifdef USE_LCD + // if lcd is enabled it only syncs the second time + RtcRead(&rtcDate); +#endif + +#ifdef USE_LCD + LcdLPrintf (2,"%04d-%02bd-%02bd", + rtcDate.year, rtcDate.month, rtcDate.day); + LcdLPrintf (3, "%02bd:%02bd:%02bd.%02bd", + rtcDate.hour, rtcDate.minute, rtcDate.second, + rtcDate.hundredth); +#endif + if (rtcDate.second!=seconds) { + PrintTime(&rtcDate); + seconds=rtcDate.second; + } + + if (Serial0CharArrived()) { + switch (getchar()) + { + case 0: + break; + case 'q': + printf ("Ok.\n"); + return; + default: + if (GetTime(&rtcDate)) { +#ifndef USE_LCD + PrintTime(&rtcDate); + RtcWrite(&rtcDate); + printf ("Time written.\n"); +#endif + } + } + } + } + +} -- 2.39.5