summaryrefslogtreecommitdiffstats
path: root/c/src/libchip
diff options
context:
space:
mode:
authorTill Straumann <strauman@slac.stanford.edu>2005-11-03 02:52:41 +0000
committerTill Straumann <strauman@slac.stanford.edu>2005-11-03 02:52:41 +0000
commit78111c37c6174de035a546ca661f0f68bb68c4cd (patch)
tree4021f8669cde59979f675ec45a6dc940c13420a9 /c/src/libchip
parent2005-11-02 straumanatslacdotstanford.edu (diff)
downloadrtems-78111c37c6174de035a546ca661f0f68bb68c4cd.tar.bz2
2005-11-02 straumanatslacdotstanford.edu
* libchip/i2c/i2c-2b-eeprom.c, libchip/i2c/i2c-2b-eeprom.h, libchip/i2c/i2c-ds1621.c, libchip/i2c/i2c-ds1621.h: New files. * libchip/Makefile.am, libchip/preinstall.am, wrapup/Makefile.am: added a simple API/library for i2c devices and drivers for i2c 2-byte eeproms and a ds1621 temperature sensor; API is documented in libi2c.h
Diffstat (limited to 'c/src/libchip')
-rw-r--r--c/src/libchip/Makefile.am9
-rw-r--r--c/src/libchip/i2c/i2c-2b-eeprom.c132
-rw-r--r--c/src/libchip/i2c/i2c-2b-eeprom.h32
-rw-r--r--c/src/libchip/i2c/i2c-ds1621.c87
-rw-r--r--c/src/libchip/i2c/i2c-ds1621.h39
-rw-r--r--c/src/libchip/preinstall.am8
6 files changed, 307 insertions, 0 deletions
diff --git a/c/src/libchip/Makefile.am b/c/src/libchip/Makefile.am
index c4994535aa..90284212b8 100644
--- a/c/src/libchip/Makefile.am
+++ b/c/src/libchip/Makefile.am
@@ -62,6 +62,15 @@ endif
EXTRA_DIST += rtc/README.ds1643 rtc/README.icm7170 rtc/README.m48t08 \
rtc/README.m48t18 rtc/STATUS
+# i2c
+if LIBCHIP
+include_libchip_HEADERS += i2c/i2c-ds1621.h i2c/i2c-2b-eeprom.h
+
+noinst_LIBRARIES += libi2cio.a
+libi2cio_a_CPPFLAGS = $(AM_CPPFLAGS)
+libi2cio_a_SOURCES = i2c/i2c-ds1621.c i2c/i2c-2b-eeprom.c
+endif
+
# serial
if LIBCHIP
include_libchip_HEADERS += serial/mc68681.h serial/ns16550.h serial/z85c30.h \
diff --git a/c/src/libchip/i2c/i2c-2b-eeprom.c b/c/src/libchip/i2c/i2c-2b-eeprom.c
new file mode 100644
index 0000000000..c24463f5d5
--- /dev/null
+++ b/c/src/libchip/i2c/i2c-2b-eeprom.c
@@ -0,0 +1,132 @@
+/* $Id$ */
+
+/* Trivial i2c driver for reading "2-byte eeproms".
+ * On 'open' the read-pointer is reset to 0, subsequent
+ * read operations slurp data from there...
+ */
+
+/* Author: Till Straumann, 2005 */
+
+
+#include <rtems.h>
+#include <rtems/libi2c.h>
+
+#include <libchip/i2c-2b-eeprom.h>
+#include <rtems/libio.h>
+
+#define EEPROM_PG_SZ 32
+#define ALGN(x) (((unsigned32)(x) + EEPROM_PG_SZ) & ~(EEPROM_PG_SZ-1))
+
+static rtems_status_code
+send_file_ptr (rtems_device_minor_number minor, unsigned pos, int tout)
+{
+ int sc;
+ unsigned char bytes[2];
+
+ bytes[0] = (pos >> 8) & 0xff;
+ bytes[1] = (pos) & 0xff;
+
+ /* poll addressing the next page; if 'tout' is <=0 we only try once
+ * and return the status. If 'tout' is positive, we try 'tout' times
+ * and return RTEMS_TIMEOUT if it didnt work
+ */
+ while ((sc = rtems_libi2c_start_write_bytes (minor, bytes, 2)) < 0) {
+ if (--tout <= 0)
+ return tout ? -sc : RTEMS_TIMEOUT;
+ rtems_task_wake_after (1);
+ }
+ return RTEMS_SUCCESSFUL;
+}
+
+static rtems_status_code
+i2c_2b_eeprom_write (rtems_device_major_number major,
+ rtems_device_minor_number minor, void *arg)
+{
+ rtems_libio_rw_args_t *rwargs = arg;
+ unsigned off = rwargs->offset;
+ int cnt = rwargs->count;
+ char *buf = rwargs->buffer;
+ int sc;
+ unsigned end;
+ int l;
+
+ if (cnt <= 0)
+ return RTEMS_SUCCESSFUL;
+
+ if ((sc = send_file_ptr (minor, off, 0)))
+ return sc;
+
+ do {
+ /* write up to next page boundary */
+ end = ALGN (off);
+ l = end - off;
+ if (l > cnt)
+ l = cnt;
+
+ sc = rtems_libi2c_write_bytes (minor, buf, l);
+ if (sc < 0)
+ return -sc;
+
+ sc = rtems_libi2c_send_stop (minor);
+ if (sc)
+ return sc;
+
+ rwargs->bytes_moved += l;
+
+ buf += l;
+ cnt -= l;
+ off += l;
+
+ /* poll addressing the next page */
+ if ((sc = send_file_ptr (minor, off, 100)))
+ return sc;
+
+ } while (cnt > 0);
+
+ return rtems_libi2c_send_stop (minor);
+}
+
+static rtems_status_code
+i2c_2b_eeprom_read (rtems_device_major_number major,
+ rtems_device_minor_number minor, void *arg)
+{
+ int sc;
+ rtems_libio_rw_args_t *rwargs = arg;
+
+ if (RTEMS_SUCCESSFUL != (sc = send_file_ptr (minor, rwargs->offset, 0)))
+ return -sc;
+
+ sc = rtems_libi2c_start_read_bytes (minor, rwargs->buffer, rwargs->count);
+
+ if (sc < 0) {
+ rwargs->bytes_moved = 0;
+ return -sc;
+ }
+ rwargs->bytes_moved = sc;
+
+ return rtems_libi2c_send_stop (minor);
+}
+
+static rtems_driver_address_table myops = {
+ read_entry: i2c_2b_eeprom_read,
+ write_entry: i2c_2b_eeprom_write,
+};
+
+static rtems_libi2c_drv_t my_drv_tbl = {
+ ops: &myops,
+ size: sizeof (my_drv_tbl),
+};
+
+/* provide a second table for R/O access */
+static rtems_driver_address_table my_ro_ops = {
+ read_entry: i2c_2b_eeprom_read,
+};
+
+static rtems_libi2c_drv_t my_ro_drv_tbl = {
+ ops: &my_ro_ops,
+ size: sizeof (my_ro_drv_tbl),
+};
+
+
+rtems_libi2c_drv_t *i2c_2b_eeprom_driver_descriptor = &my_drv_tbl;
+rtems_libi2c_drv_t *i2c_2b_eeprom_ro_driver_descriptor = &my_ro_drv_tbl;
diff --git a/c/src/libchip/i2c/i2c-2b-eeprom.h b/c/src/libchip/i2c/i2c-2b-eeprom.h
new file mode 100644
index 0000000000..e5c72554c3
--- /dev/null
+++ b/c/src/libchip/i2c/i2c-2b-eeprom.h
@@ -0,0 +1,32 @@
+/* $Id$ */
+#ifndef I2C_2B_EEPROM_DRIVER_H
+#define I2C_2B_EEPROM_DRIVER_H
+
+/* Trivial i2c driver for reading and writing "2-byte eeproms".
+ * On 'open' the file-pointer is reset to 0, subsequent
+ * read/write operations slurp/write data from there...
+ */
+
+/* Author: Till Straumann, 2005 */
+
+
+#include <rtems.h>
+#include <rtems/libi2c.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* pass one of these to rtems_libi2c_register_drv() */
+
+/* These ops provide no write access */
+extern rtems_libi2c_drv_t *i2c_2b_eeprom_ro_driver_descriptor;
+
+/* Use these for writing and reading */
+extern rtems_libi2c_drv_t *i2c_2b_eeprom_driver_descriptor;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/c/src/libchip/i2c/i2c-ds1621.c b/c/src/libchip/i2c/i2c-ds1621.c
new file mode 100644
index 0000000000..fc76e83750
--- /dev/null
+++ b/c/src/libchip/i2c/i2c-ds1621.c
@@ -0,0 +1,87 @@
+/* $Id$ */
+
+/* Trivial i2c driver for the maxim DS1621 temperature sensor;
+ * just implements reading constant conversions with 8-bit
+ * resolution.
+ * Demonstrates the implementation of a i2c high-level driver.
+ */
+
+/* Author: Till Straumann, 2005 */
+#include <rtems.h>
+#include <rtems/libi2c.h>
+
+#include <libchip/i2c-ds1621.h>
+
+#include <rtems/libio.h>
+
+
+static rtems_status_code
+ds1621_init (rtems_device_major_number major, rtems_device_minor_number minor,
+ void *arg)
+{
+ int sc;
+ char csr[2] = { DS1621_CMD_CSR_ACCESS, 0 }, cmd;
+
+ /* First start command acquires a lock for the bus */
+
+ /* Initialize; switch continuous conversion on */
+ sc = rtems_libi2c_start_write_bytes (minor, csr, 1);
+ if (sc < 0)
+ return -sc;
+
+ sc = rtems_libi2c_start_read_bytes (minor, csr + 1, 1);
+ if (sc < 0)
+ return -sc;
+
+ csr[1] &= ~DS1621_CSR_1SHOT;
+
+ sc = rtems_libi2c_start_write_bytes (minor, csr, 2);
+ if (sc < 0)
+ return -sc;
+
+ /* Start conversion */
+ cmd = DS1621_CMD_START_CONV;
+
+ sc = rtems_libi2c_start_write_bytes (minor, &cmd, 1);
+ if (sc < 0)
+ return -sc;
+
+ /* sending 'stop' relinquishes the bus mutex -- don't hold it
+ * across system calls!
+ */
+ return rtems_libi2c_send_stop (minor);
+}
+
+static rtems_status_code
+ds1621_read (rtems_device_major_number major, rtems_device_minor_number minor,
+ void *arg)
+{
+ int sc;
+ rtems_libio_rw_args_t *rwargs = arg;
+ char cmd = DS1621_CMD_READ_TEMP;
+
+ sc = rtems_libi2c_start_write_bytes (minor, &cmd, 1);
+ if (sc < 0)
+ return -sc;
+ if (sc < 1)
+ return RTEMS_IO_ERROR;
+ sc = rtems_libi2c_start_read_bytes (minor, rwargs->buffer, 1);
+ if (sc < 0) {
+ rwargs->bytes_moved = 0;
+ return -sc;
+ }
+ rwargs->bytes_moved = 1;
+ return rtems_libi2c_send_stop (minor);
+}
+
+static rtems_driver_address_table myops = {
+ initialization_entry: ds1621_init,
+ read_entry: ds1621_read,
+};
+
+static rtems_libi2c_drv_t my_drv_tbl = {
+ ops: &myops,
+ size: sizeof (my_drv_tbl),
+};
+
+rtems_libi2c_drv_t *i2c_ds1621_driver_descriptor = &my_drv_tbl;
diff --git a/c/src/libchip/i2c/i2c-ds1621.h b/c/src/libchip/i2c/i2c-ds1621.h
new file mode 100644
index 0000000000..802af03727
--- /dev/null
+++ b/c/src/libchip/i2c/i2c-ds1621.h
@@ -0,0 +1,39 @@
+/* $Id$ */
+#ifndef I2C_DS_1621_DRIVER_H
+#define I2C_DS_1621_DRIVER_H
+
+/* Trivial i2c driver for the maxim DS1621 temperature sensor;
+ * just implements reading constant conversions with 8-bit
+ * resolution.
+ * Demonstrates the implementation of a i2c high-level driver.
+ */
+
+/* Author: Till Straumann, 2005 */
+
+#define DS1621_CMD_READ_TEMP 0xaa
+#define DS1621_CMD_CSR_ACCESS 0xac
+#define DS1621_CMD_START_CONV 0xee
+
+/* CSR bits */
+#define DS1621_CSR_DONE (1<<7)
+#define DS1621_CSR_TEMP_HI (1<<6) /* T >= hi register */
+#define DS1621_CSR_TEMP_LO (1<<5) /* T <= lo register */
+#define DS1621_CSR_NVMEM_BSY (1<<4) /* non-volatile memory busy */
+#define DS1621_CSR_OUT_POL (1<<1) /* Thermostat output active polarity */
+#define DS1621_CSR_1SHOT (1<<0) /* Oneshot mode */
+
+#include <rtems.h>
+#include <rtems/libi2c.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* for registration with libi2c */
+extern rtems_libi2c_drv_t *i2c_ds1621_driver_descriptor;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/c/src/libchip/preinstall.am b/c/src/libchip/preinstall.am
index 3e5c1947bf..c563522367 100644
--- a/c/src/libchip/preinstall.am
+++ b/c/src/libchip/preinstall.am
@@ -77,6 +77,14 @@ $(PROJECT_INCLUDE)/libchip/rtc.h: rtc/rtc.h $(PROJECT_INCLUDE)/libchip/$(dirstam
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libchip/rtc.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libchip/rtc.h
+$(PROJECT_INCLUDE)/libchip/i2c-ds1621.h: i2c/i2c-ds1621.h $(PROJECT_INCLUDE)/libchip/$(dirstamp)
+ $(INSTALL_DATA) $< $@
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/libchip/i2c-ds1621.h
+
+$(PROJECT_INCLUDE)/libchip/i2c-2b-eeprom.h: i2c/i2c-2b-eeprom.h $(PROJECT_INCLUDE)/libchip/$(dirstamp)
+ $(INSTALL_DATA) $< $@
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/libchip/i2c-2b-eeprom.h
+
$(PROJECT_INCLUDE)/libchip/icm7170.h: rtc/icm7170.h $(PROJECT_INCLUDE)/libchip/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libchip/icm7170.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libchip/icm7170.h