From 5d7017ea449f6555e7ffb415d9d2408dd0fe4ca6 Mon Sep 17 00:00:00 2001 From: johanknol Date: Wed, 11 Oct 2000 08:44:46 +0000 Subject: [PATCH] Moved and unpacked examples to sdcc/device/examples/ds390 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@456 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- device/examples/ds390/clock390/Makefile | 18 ++ device/examples/ds390/clock390/clock390.c | 72 +++++ device/examples/ds390/clock390/lcd.c | 174 +++++++++++ device/examples/ds390/clock390/lcd.h | 16 + device/examples/ds390/hello390/Makefile | 10 + device/examples/ds390/hello390/hello390.c | 17 ++ device/examples/ds390/i2c390/Makefile | 20 ++ device/examples/ds390/i2c390/ds1621.c | 60 ++++ device/examples/ds390/i2c390/ds1621.h | 12 + device/examples/ds390/i2c390/i2c390.c | 34 +++ device/examples/ds390/i2c390/i2clole.c | 351 ++++++++++++++++++++++ device/examples/ds390/i2c390/i2clole.h | 48 +++ device/examples/ds390/i2c390/pcf8591.c | 21 ++ device/examples/ds390/i2c390/pcf8591.h | 2 + 14 files changed, 855 insertions(+) create mode 100644 device/examples/ds390/clock390/Makefile create mode 100644 device/examples/ds390/clock390/clock390.c create mode 100644 device/examples/ds390/clock390/lcd.c create mode 100644 device/examples/ds390/clock390/lcd.h create mode 100644 device/examples/ds390/hello390/Makefile create mode 100644 device/examples/ds390/hello390/hello390.c create mode 100644 device/examples/ds390/i2c390/Makefile create mode 100644 device/examples/ds390/i2c390/ds1621.c create mode 100644 device/examples/ds390/i2c390/ds1621.h create mode 100644 device/examples/ds390/i2c390/i2c390.c create mode 100644 device/examples/ds390/i2c390/i2clole.c create mode 100644 device/examples/ds390/i2c390/i2clole.h create mode 100644 device/examples/ds390/i2c390/pcf8591.c create mode 100644 device/examples/ds390/i2c390/pcf8591.h diff --git a/device/examples/ds390/clock390/Makefile b/device/examples/ds390/clock390/Makefile new file mode 100644 index 00000000..e5ebe099 --- /dev/null +++ b/device/examples/ds390/clock390/Makefile @@ -0,0 +1,18 @@ +CC = sdcc + +MFLAGS = -mds390 --model-flat24 --stack-10bit +LFLAGS = --xram-loc 0x100080 --code-loc 0x10000 -Wl-r + +all: clock390.hex + +clean: + rm -f *~ \#* *.asm *.cdb *.rel *.hex *.ihx *.lst *.map *.rst *.sym *.lnk + +clock390.hex: clock390.ihx + packihx clock390.ihx >clock390.hex + +clock390.ihx: clock390.rel lcd.rel + $(CC) $(MFLAGS) $(LFLAGS) clock390.rel lcd.rel + +%.rel: %.c + $(CC) -c $(MFLAGS) $< diff --git a/device/examples/ds390/clock390/clock390.c b/device/examples/ds390/clock390/clock390.c new file mode 100644 index 00000000..a2b0785a --- /dev/null +++ b/device/examples/ds390/clock390/clock390.c @@ -0,0 +1,72 @@ +/* This example compiles right out of the box for TINI after you did a + make install of sdcc (latest revision :). + + Just do a "make" which compiles and compresses it a little. + Than use JavaKit to load clock390.hex (it goes into bank 1, see Makefile) + Type 'E' in JavaKit and enjoy :) */ + +/* if you are using the (default) interrupt scheme for serial i/o, + you need to include this in the main program, so the vector will + be initialized */ +#include + +#include +#include +#include "lcd.h" + +volatile unsigned long milliSeconds=0; + +#define RELOAD_VALUE 18432000/2/1000 // appr. 1ms + +void Timer2Handler (void) interrupt 5 using 1 { + TF2=0; // reset overflow flag + milliSeconds++; + // that's all for now :) +} + +// we can't just use milliSeconds +unsigned long GetMilliSeconds(void) { + unsigned long ms; + ET2=0; + ms=milliSeconds; + ET2=1; + return ms; +} + +void main (void) { + unsigned long ms, seconds, oldSeconds=-1; + + printf ("\n\rStarting timer 2 test.\n\r"); + + // initialise timer + ET2=0; // disable timer interrupts initially + T2CON=0; // stop, timer mode, autoreload + T2MOD&=0xf4; + + TL2=RTL2=(-RELOAD_VALUE)&0xff; + TH2=RTH2=(-RELOAD_VALUE)>>8; + TR2=1; // run + + ET2=1; // enable timer interrupts + + // now do something + LcdInit(); + LcdLPutString(0, "Testing timer2"); + LcdLPutString(2, "ms: "); + while (1) { + ms=GetMilliSeconds(); + seconds=ms/1000; + LcdLPrintf (2 + (4<<8), "%ld", ms); + if (seconds!=oldSeconds) { + printf ("%02d:%02d.%02d\n\r", (int)seconds/3600, + (int)(seconds/60)%60, + (int)seconds%60); + oldSeconds=seconds; + _asm + cpl P3.5 ; toggle led + _endasm; + } + } +} + + diff --git a/device/examples/ds390/clock390/lcd.c b/device/examples/ds390/clock390/lcd.c new file mode 100644 index 00000000..a6b05ef5 --- /dev/null +++ b/device/examples/ds390/clock390/lcd.c @@ -0,0 +1,174 @@ +#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*time +// check this, _PLEASE_ + +static void Wait100u(long time) { + register long timeout=time*50; + while (timeout--) + ; +} + +#define LcdWait { Wait100u(1);} + +#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}; + +#include +#include +#include +#include +#include "lcd.h" + +void LcdInit() { + + Wait100u(150); // >15 ms + + lcdIwr=0x38 ; + Wait100u(50); // >4.1 ms + + lcdIwr=0x38; + Wait100u(1); // >100 us + + lcdIwr=0x38; + Wait100u(1); // >100 u + + lcdIwr=0x38; // interface 8 bit + Wait100u(1); // >40u + + lcdIwr=0x0c; // display on + Wait100u(1); // >40u + LcdClear(); + Wait100u(1); // >40u +} + +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 + Wait100u(50); +} + +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 +xdata static char lcdPrintfBuffer[LCD_COLLUMNS*4]; + +void LcdPrintf (xdata const char *format, ...) reentrant { + va_list arg; + + va_start (arg, format); + vsprintf (lcdPrintfBuffer, format, arg); + + 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); +} + +#if 0 +// These don't belong here +void LedOn (void) { + _asm + setb P3.5 + _endasm; +} + +void LedOff (void) { + _asm + clr P3.5 + _endasm; +} + +void LedToggle (void) { + _asm + cpl P3.5 + _endasm; +} +#endif diff --git a/device/examples/ds390/clock390/lcd.h b/device/examples/ds390/clock390/lcd.h new file mode 100644 index 00000000..b0543328 --- /dev/null +++ b/device/examples/ds390/clock390/lcd.h @@ -0,0 +1,16 @@ +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; + +// These don't belong here +extern void LedOn (void); +extern void LedOff (void); +extern void LedToggle (void); diff --git a/device/examples/ds390/hello390/Makefile b/device/examples/ds390/hello390/Makefile new file mode 100644 index 00000000..73cb15ae --- /dev/null +++ b/device/examples/ds390/hello390/Makefile @@ -0,0 +1,10 @@ +hello390.hex: hello390.ihx + packihx hello390.ihx >hello390.hex + +hello390.ihx: hello390.c + sdcc -mds390 --model-flat24 --stack-10bit \ + --xram-loc 0x100080 --code-loc 0x10000 \ + -Wl-r hello390.c + +clean: + rm -f *~ \#* *.asm *.cdb *.rel *.hex *.ihx *.lst *.map *.rst *.sym *.lnk diff --git a/device/examples/ds390/hello390/hello390.c b/device/examples/ds390/hello390/hello390.c new file mode 100644 index 00000000..b735641b --- /dev/null +++ b/device/examples/ds390/hello390/hello390.c @@ -0,0 +1,17 @@ +/* This example compiles right out of the box for TINI after you did a + make install of sdcc (latest revision :). + + Just do a "make" which compiles and compresses it a little. + Than use JavaKit to load hello390.hex (it goes into bank 1, see Makefile) + Type 'E' in JavaKit and enjoy :) */ + +/* if you are using the (default) interrupt scheme for serial i/o, + you need to include this in the main program, so the vector will + be initialized */ +#include + +#include + +void main (void) { + printf ("\n\rHello from 390.\n\rSee you, bye..."); +} diff --git a/device/examples/ds390/i2c390/Makefile b/device/examples/ds390/i2c390/Makefile new file mode 100644 index 00000000..7e408d54 --- /dev/null +++ b/device/examples/ds390/i2c390/Makefile @@ -0,0 +1,20 @@ +CC = sdcc + +MFLAGS = -mds390 --model-flat24 --stack-10bit +LFLAGS = --xram-loc 0x180000 --code-loc 0x10000 -Wl-r + +OBJECTS = i2c390.rel i2clole.rel ds1621.rel pcf8591.rel + +all: i2c390.hex + +clean: + rm -f *~ \#* *.asm *.cdb *.rel *.hex *.ihx *.lst *.map *.rst *.sym *.lnk + +i2c390.hex: i2c390.ihx + packihx i2c390.ihx >i2c390.hex + +i2c390.ihx: $(OBJECTS) + $(CC) $(MFLAGS) $(LFLAGS) $(OBJECTS) + +%.rel: %.c + $(CC) -c $(MFLAGS) $< diff --git a/device/examples/ds390/i2c390/ds1621.c b/device/examples/ds390/i2c390/ds1621.c new file mode 100644 index 00000000..fd99ef7b --- /dev/null +++ b/device/examples/ds390/i2c390/ds1621.c @@ -0,0 +1,60 @@ +#include "i2clole.h" +#include "ds1621.h" + +#if USE_FLOAT // defined in ds1621.h +static float temperature +signed char counter, slope; +float +#else +#include +static char temperature[10]; +char * +#endif + +ReadDS1621(char address) { + int id=DS1621_ID + (address<<1); + + while (!I2CReset()) { + //fprintf (stderr, "I2C bus busy, retrying.\n"); + } + + i2cTransmitBuffer[0]=0xac; // access config command + i2cTransmitBuffer[1]=0x09; // mode (8=continuous, 9=one-shot) + if (I2CSend(id, 2)) return -999; + + i2cTransmitBuffer[0]=0xee; // start conversion command + if (I2CSend(id, 1)) return -999; + + do { + i2cTransmitBuffer[0]=0xac; // access config command + if (I2CSendReceive(id, 1, 1)) return -999; + } while ((i2cReceiveBuffer[0]&0x80)==0); // wait for conversion done + + + // if we did not do this, sdcc thinks i2cReceiveBuffer[0] is still in r3 + i2cReceiveBuffer[0]=0; + + i2cTransmitBuffer[0]=0xaa; // read temperature command + +#if !USE_FLOAT + if (I2CSendReceive(id, 1, 2)) return -999; + sprintf (temperature, "% 3bd.%c", i2cReceiveBuffer[0], + i2cReceiveBuffer[1]?'5':'0'); + return temperature; +#else + if (I2CSendReceive(id, 1, 1)) return -999; + temperature=i2cReceiveBuffer[0]; + i2cTransmitBuffer[0]=0xa8; // read counter command + if (I2CSendReceive(id, 1, 1)) return -999; + counter=i2cReceiveBuffer[0]; + + i2cTransmitBuffer[0]=0xa9; // read slope command + if (I2CSendReceive(id, 1, 1)) return -999; + slope=i2cReceiveBuffer[0]; + + temperature=(int)temperature - 0.25 + + ((float)slope-(float)counter)/(float)slope; + return temperature; +#endif +} + diff --git a/device/examples/ds390/i2c390/ds1621.h b/device/examples/ds390/i2c390/ds1621.h new file mode 100644 index 00000000..9f782c03 --- /dev/null +++ b/device/examples/ds390/i2c390/ds1621.h @@ -0,0 +1,12 @@ +#define DS1621_ID 0x90 + +// we have no decent float support in sdcc yet +#define USE_FLOAT 0 + +#if USE_FLOAT +extern float +#else +extern char * +#endif + +ReadDS1621(char address); diff --git a/device/examples/ds390/i2c390/i2c390.c b/device/examples/ds390/i2c390/i2c390.c new file mode 100644 index 00000000..0b6de2d6 --- /dev/null +++ b/device/examples/ds390/i2c390/i2c390.c @@ -0,0 +1,34 @@ +/* This example compiles right out of the box for TINI after you did a + make install of sdcc (latest revision :). + + It prints the value of the DS1621 temperature sensor (at address 2) + and the 4 values of the PCF8591 ad-convertor (at address 0). + It (ab)uses the CAN CTX and CTR pins of the DS80C390. + Make sure you have pull-up resistors connected or it WON'T work. + + Just do a "make" which compiles and compresses it a little. + Than use JavaKit to load i2c390.hex (it goes into bank 1, see Makefile) + Type 'E' in JavaKit and enjoy :) */ + +/* if you are using the (default) interrupt scheme for serial i/o, + you need to include this in the main program, so the vector will + be initialized */ +#include + +#include + +#include "ds1621.h" +#include "pcf8591.h" + + +void main (void) { + + while(1) { + printf ("%s %03bu %03bu %03bu %03bu\n\r", + ReadDS1621(2), + ReadPCF8591(0,0), + ReadPCF8591(0,1), + ReadPCF8591(0,2), + ReadPCF8591(0,3)); + } +} diff --git a/device/examples/ds390/i2c390/i2clole.c b/device/examples/ds390/i2c390/i2clole.c new file mode 100644 index 00000000..8a2ebcb2 --- /dev/null +++ b/device/examples/ds390/i2c390/i2clole.c @@ -0,0 +1,351 @@ +/* This implemenation is based on an example I once grabbed from + the Philips bbs. + Don't know who wrote it, but is has been hacked so heavely, he/she wouldn't + recogize it anyway */ + +#define DEBUG_I2C + +#ifdef DEBUG_I2C +#include +#endif + +#include +#include "i2clole.h" + +#define I2CDELAY 1 + +// we are (ab)using the CAN CTX and CRX for serial data and serial clock +#define SCL_HIGH (P5 |= 1) +#define SCL_LOW (P5 &= ~1) +#define SDA_HIGH (P5 |= 2) +#define SDA_LOW (P5 &= ~2) + +#define SDA_OUT(b) (b ? SDA_HIGH : SDA_LOW) +#define SDA_IN ((P5>>1)&1) +#define SCL_IN (P5&1) + +char i2cTransmitBuffer[I2C_BUFSIZE]; /* Global transfer buffers */ +char i2cReceiveBuffer[I2C_BUFSIZE]; + +char i2cError = 0; /* Last error */ + + +/* + * Makes sure that the bus is in a known condition. Returns 1 on success, + * 0 if some other device is pulling on the bus. + */ + +char I2CReset(void) +{ + //puts (""); + SDA_LOW; + SCL_LOW; + SCL_HIGH; + SDA_HIGH; + i2cError = 0; + return (SCL_IN && SDA_IN); +} + + +/* + * Generates a start condition on the bus. Returns 0 on success, 1 if some + * other device is holding the bus. + */ + +char I2CStart(void) +{ + //puts (""); + + SDA_HIGH; + SCL_HIGH; + I2CDelay(I2CDELAY); + SDA_LOW; /* Pull SDA down... */ + I2CDelay(I2CDELAY); + SCL_LOW; /* ...and then SCL -> start condition. */ + I2CDelay(I2CDELAY); + return 0; +} + + +/* + * Generates a stop condition on the bus. Returns 0 on success, 1 if some + * other device is holding the bus. + */ + +char I2CStop(void) +{ + //puts (""); + + SDA_LOW; + SCL_HIGH; /* Let SCL go up */ + I2CDelay(I2CDELAY); + SDA_HIGH; /* ...and then SDA up -> stop condition. */ + I2CDelay(I2CDELAY); + + return (SCL_IN && SDA_IN); /* Both will be up, if everything is fine */ +} + + +/* + * Clock out one bit. + * Returns 0 on success, 1 if we lose arbitration. + */ + +char BitOutI2C(char bout) +{ + //puts(""); + + SDA_OUT(bout); /* Put data out on SDA */ + I2CDelay(I2CDELAY); + SCL_HIGH; /* Let SCL go up */ + while(!SCL_IN) /* Wait until all other devices are ready */ + { + // should do a timeout here + } + + if (SDA_IN != bout) /* Arbitration lost, release bus and return */ + { + SDA_HIGH; /* Should be up anyway, but make sure */ + i2cError = I2CERR_LOST; + I2CDumpError(i2cError); + return 1; + } + I2CDelay(I2CDELAY); + SCL_LOW; /* Pull SCL back down */ + I2CDelay(I2CDELAY); + return 0; /* OK */ +} + + +/* + * Clock in one bit. + */ + +char BitInI2C(void) +{ + char bin; + + //puts (""); + + // SDA is opencollector, so: + SDA_HIGH; + + SCL_HIGH; /* Let SCL go up */ + while(!SCL_IN) /* Wait for other devices */ + { + // should do a timeout here + } + bin = SDA_IN; /* Read in data */ + I2CDelay(I2CDELAY); + SCL_LOW; /* Pull SCL back up */ + I2CDelay(I2CDELAY); + return bin; /* Return the sampled bit */ +} + + +/* + * Send one byte on the bus. No start or stop conditions are generated here, + * but i2cError will be set according to the result. + * Returns 0 on success, 1 if we lose arbitration or if the slave doesn't + * acknowledge the byte. Check i2cError for the actual result on error. + */ + +char ByteOutI2C(char dat) +{ + char bit_count; + + //puts (""); + + bit_count = 8; + while(bit_count) { + if (dat & 0x80) { + if (BitOutI2C(1)) { + I2CDumpError(i2cError); + return 1; + } + } else { + if (BitOutI2C(0)) { + I2CDumpError(i2cError); + return 1; + } + } + dat <<= 1; + bit_count--; + } + + if (BitInI2C()) { + i2cError = I2CERR_NAK; + I2CDumpError(i2cError); + return 1; + } + return 0; +} + + +/* + * Reads one byte in from the slave. Ack must be 1 if this is the last byte + * to be read during this transfer, 0 otherwise (as per I2C bus specification, + * the receiving master must acknowledge all but the last byte during a + * transfer). + */ + +char I2CByteIn(char ack) +{ + char bit_count, byte_in; + + //puts (""); + + bit_count = 8; + byte_in = 0; + + while(bit_count) + { + byte_in <<= 1; + if (BitInI2C()) byte_in |= 0x01; + bit_count--; + } + + BitOutI2C(ack); + SDA_HIGH; /* Added 18-Jul-95 - thanks to Ray Bellis */ + return byte_in; +} + + +/* + * Send 'count' bytes to slave 'addr'. + * Returns 0 on success. Stop condition is sent only when send_stop is true. + */ + +char I2CSendStop(char addr, char count, char send_stop) +{ + char byteptr, byte_out; + + //puts (""); + + if (I2CStart()) return 1; + i2cError = 0; + + byte_out = addr & 0xfe; /* Ensure that it's a write address */ + count++; /* Include slave address to byte count */ + byteptr = 0; + while(count) + { + if (ByteOutI2C(byte_out)) + { + if (i2cError == I2CERR_NAK && send_stop) I2CStop(); + return i2cError; + } + byte_out = i2cTransmitBuffer[byteptr]; + byteptr++; + count--; + } + + if (send_stop) I2CStop(); + return 0; +} + + +/* + * Read in 'count' bytes from slave 'addr'. + * Returns 0 on success. + */ + +char i2c_recv(char addr, char count) +{ + char byteptr, byte_in; + + //puts (""); + + if (I2CStart()) return 1; + i2cError = 0; + byteptr = 0; + + byte_in = addr | 0x01; + + if (ByteOutI2C(byte_in)) + { + if (i2cError == I2CERR_NAK) I2CStop(); + return i2cError; + } + + while(count) + { + count-=1; + if (count) { + byte_in = I2CByteIn(0); + } else { + byte_in = I2CByteIn(1); /* No ACK during last byte */ + } + i2cReceiveBuffer[byteptr] = byte_in; + byteptr++; + } + + I2CStop(); + + return (i2cError ? 1 : 0); +} + + +/* + * Write 'tx_count' bytes to slave 'addr', then use a repeated start condition + * to read 'rx_count' bytes from the same slave during the same transfer. + * Returns 0 on success, 1 otherwise. On error, check i2cError for the actual + * error value. + */ + +char I2CSendReceive(char addr, char tx_count, char rx_count) +{ + //puts (""); + + if (I2CSendStop(addr, tx_count, 0)) + { + /* If send fails, abort but don't send a stop condition if we lost + arbitration */ + + if (i2cError != I2CERR_LOST) I2CStop(); + return 1; + } + + SDA_HIGH; /* One of these may be low now, in which case the next */ + SCL_HIGH; /* start condition wouldn't be detected so make */ + I2CDelay(I2CDELAY); /* sure that they're up and wait for one delay slot */ + + if (i2c_recv((char)(addr|0x01), rx_count)) return 1; + return (i2cError ? 1 : 0); +} + +/* + * Dump an error message. + */ + +void I2CDumpError(char error) +{ +#ifdef DEBUG_I2C + switch(error) + { + case 0: + puts("I2C: OK."); + break; + case I2CERR_NAK: + puts("I2C: Slave didn't acknowledge"); + break; + case I2CERR_LOST: + puts("I2C: Lost arbitration with another master"); + break; + case I2CERR_TIMEOUT: + puts("I2C: Timeout on bus"); + break; + case I2CERR_BUS: + puts("I2C: The bus is stuck"); + break; + default: + puts("I2C: Unknown error"); + break; + } +#endif +} + +void I2CDelay(volatile long delay) { + while (delay--) + ; +} diff --git a/device/examples/ds390/i2c390/i2clole.h b/device/examples/ds390/i2c390/i2clole.h new file mode 100644 index 00000000..9ce2e4f3 --- /dev/null +++ b/device/examples/ds390/i2c390/i2clole.h @@ -0,0 +1,48 @@ +#ifndef _I2C_H +#define _I2C_H + +#define I2C_BUFSIZE 128 + +extern char I2CReset(void); +extern char I2CStart(void); +extern char I2CStop(void); +extern char I2CSendStop(char addr, char count, + char send_stop); +extern char I2CReceive(char addr, char count); +extern char I2CSendReceive(char addr, char tx_count, char rx_count); +extern char I2CByteOut(char); +extern void I2CDumpError(char); +extern void I2CDelay(volatile long); + +/* + * Macro for normal send transfer ending with a stop condition + */ + +#define I2CSend(addr, count) I2CSendStop(addr, count, 1) + +/* + * Global variables in i2clole.c + */ + +extern char i2cTransmitBuffer[]; /* Transmit buffer */ +extern char i2cReceiveBuffer[]; /* Receive buffer */ +extern char i2cError; /* Set to last error value, see below */ + +/* + * I2C error values + */ + +#define I2CERR_OK 0 /* No error */ +#define I2CERR_NAK 1 /* No ACK from slave */ +#define I2CERR_LOST 2 /* Arbitration lost */ +#define I2CERR_BUS 3 /* Bus is stuck (not used yet) */ +#define I2CERR_TIMEOUT 4 /* Timeout on bus */ + +#endif + + + + + + + diff --git a/device/examples/ds390/i2c390/pcf8591.c b/device/examples/ds390/i2c390/pcf8591.c new file mode 100644 index 00000000..7b1352cf --- /dev/null +++ b/device/examples/ds390/i2c390/pcf8591.c @@ -0,0 +1,21 @@ +#include "i2clole.h" +#include "pcf8591.h" + +unsigned char ReadPCF8591(char address, char channel) { + + unsigned char id=PCF8591_ID + address<<1; + + while (!I2CReset()) { + //fprintf (stderr, "I2C bus busy, retrying.\n"); + } + + i2cTransmitBuffer[0]=channel&0x03 + 0x40; //output enable, not autoincrement + //i2cTransmitBuffer[1]=0; // dac output + + // read 2 bytes, since the first one is the old value + if (I2CSendReceive(id, 1, 2)) + return 0; + + return i2cReceiveBuffer[1]; +} + diff --git a/device/examples/ds390/i2c390/pcf8591.h b/device/examples/ds390/i2c390/pcf8591.h new file mode 100644 index 00000000..60f3f9c4 --- /dev/null +++ b/device/examples/ds390/i2c390/pcf8591.h @@ -0,0 +1,2 @@ +#define PCF8591_ID 0x90; +extern unsigned char ReadPCF8591(char address, char channel); -- 2.30.2