Moved and unpacked examples to sdcc/device/examples/ds390
authorjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 11 Oct 2000 08:44:46 +0000 (08:44 +0000)
committerjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 11 Oct 2000 08:44:46 +0000 (08:44 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@456 4a8a32a2-be11-0410-ad9d-d568d2c75423

14 files changed:
device/examples/ds390/clock390/Makefile [new file with mode: 0644]
device/examples/ds390/clock390/clock390.c [new file with mode: 0644]
device/examples/ds390/clock390/lcd.c [new file with mode: 0644]
device/examples/ds390/clock390/lcd.h [new file with mode: 0644]
device/examples/ds390/hello390/Makefile [new file with mode: 0644]
device/examples/ds390/hello390/hello390.c [new file with mode: 0644]
device/examples/ds390/i2c390/Makefile [new file with mode: 0644]
device/examples/ds390/i2c390/ds1621.c [new file with mode: 0644]
device/examples/ds390/i2c390/ds1621.h [new file with mode: 0644]
device/examples/ds390/i2c390/i2c390.c [new file with mode: 0644]
device/examples/ds390/i2c390/i2clole.c [new file with mode: 0644]
device/examples/ds390/i2c390/i2clole.h [new file with mode: 0644]
device/examples/ds390/i2c390/pcf8591.c [new file with mode: 0644]
device/examples/ds390/i2c390/pcf8591.h [new file with mode: 0644]

diff --git a/device/examples/ds390/clock390/Makefile b/device/examples/ds390/clock390/Makefile
new file mode 100644 (file)
index 0000000..e5ebe09
--- /dev/null
@@ -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 (file)
index 0000000..a2b0785
--- /dev/null
@@ -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 <serial390.h>
+
+#include <ds80c390.h>
+#include <stdio.h>
+#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 (file)
index 0000000..a6b05ef
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#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 (file)
index 0000000..b054332
--- /dev/null
@@ -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 (file)
index 0000000..73cb15a
--- /dev/null
@@ -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 (file)
index 0000000..b735641
--- /dev/null
@@ -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 <serial390.h>
+
+#include <stdio.h>
+
+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 (file)
index 0000000..7e408d5
--- /dev/null
@@ -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 (file)
index 0000000..fd99ef7
--- /dev/null
@@ -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 <stdio.h>
+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 (file)
index 0000000..9f782c0
--- /dev/null
@@ -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 (file)
index 0000000..0b6de2d
--- /dev/null
@@ -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 <serial390.h>
+
+#include <stdio.h>
+
+#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 (file)
index 0000000..8a2ebcb
--- /dev/null
@@ -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 <stdio.h>
+#endif
+
+#include <ds80c390.h>
+#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 ("<I2CReset>");
+  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 ("<I2CStart>");
+
+  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 ("<I2CStop>");
+
+  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("<BitOutI2C>");
+
+  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 ("<BitInI2C>");
+
+  // 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 ("<ByteOutI2C>");
+
+  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 ("<I2CByteIn>");
+
+  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 ("<I2CSendStop>");
+
+  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 ("<i2c_rec>");
+
+  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 ("<i2c_send_recv>");
+
+  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 (file)
index 0000000..9ce2e4f
--- /dev/null
@@ -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 (file)
index 0000000..7b1352c
--- /dev/null
@@ -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 (file)
index 0000000..60f3f9c
--- /dev/null
@@ -0,0 +1,2 @@
+#define PCF8591_ID 0x90;
+extern unsigned char ReadPCF8591(char address, char channel);