summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/examples/ostest/mqueue.c6
-rw-r--r--apps/examples/ostest/sighand.c6
-rw-r--r--apps/examples/ostest/timedmqueue.c12
-rw-r--r--apps/namedapp/binfs.c2
-rw-r--r--apps/netutils/dhcpc/dhcpc.c4
-rwxr-xr-xapps/netutils/thttpd/thttpd_cgi.c2
-rw-r--r--apps/nshlib/nsh_apps.c7
-rw-r--r--nuttx/ChangeLog9
-rw-r--r--nuttx/Documentation/NuttX.html19
-rw-r--r--nuttx/Documentation/NuttxPortingGuide.html32
-rw-r--r--nuttx/Makefile22
-rw-r--r--nuttx/TODO12
-rw-r--r--nuttx/arch/arm/src/lpc313x/lpc313x_i2c.c2
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_i2c.h6
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_i2c.c434
-rwxr-xr-xnuttx/arch/arm/src/stm32/stm32_i2c.h2
-rw-r--r--nuttx/arch/z80/src/ez80/ez80_i2c.c4
-rwxr-xr-xnuttx/arch/z80/src/z8/z8_i2c.c4
-rw-r--r--nuttx/configs/README.txt14
-rwxr-xr-xnuttx/configs/demo9s12ne64/ostest/defconfig3
-rwxr-xr-xnuttx/configs/ea3131/locked/Makefile2
-rwxr-xr-xnuttx/configs/ea3131/pgnsh/defconfig1
-rwxr-xr-xnuttx/configs/ne64badge/ostest/defconfig3
-rwxr-xr-xnuttx/configs/sam3u-ek/README.txt17
-rwxr-xr-xnuttx/configs/sam3u-ek/kernel/Makefile2
-rw-r--r--nuttx/configs/sam3u-ek/kernel/kernel.ld1
-rwxr-xr-xnuttx/configs/sam3u-ek/knsh/Make.defs2
-rwxr-xr-xnuttx/configs/sam3u-ek/knsh/defconfig1
-rwxr-xr-xnuttx/configs/vsn/include/nsh_romfsimg.h40
-rwxr-xr-xnuttx/configs/vsn/include/rcS.template4
-rwxr-xr-xnuttx/configs/vsn/nsh/defconfig13
-rw-r--r--nuttx/configs/vsn/src/sif.c47
-rw-r--r--nuttx/drivers/Makefile7
-rw-r--r--nuttx/drivers/i2c/Make.defs42
-rw-r--r--nuttx/drivers/i2c/st_lis331dl.c270
-rw-r--r--nuttx/include/nuttx/i2c/i2c.h (renamed from nuttx/include/nuttx/i2c.h)31
-rw-r--r--nuttx/include/nuttx/i2c/st_lis331dl.h170
37 files changed, 1034 insertions, 221 deletions
diff --git a/apps/examples/ostest/mqueue.c b/apps/examples/ostest/mqueue.c
index e68cfc012..95e6bbfc8 100644
--- a/apps/examples/ostest/mqueue.c
+++ b/apps/examples/ostest/mqueue.c
@@ -1,5 +1,5 @@
/**************************************************************************
- * mqueue.c
+ * apps/examples/ostest/mqueue.c
*
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
@@ -212,9 +212,9 @@ static void *receiver_thread(void *arg)
* it is not a failure.
*/
- if (*get_errno_ptr() != EINTR)
+ if (errno != EINTR)
{
- printf("receiver_thread: ERROR mq_receive failure on msg %d, errno=%d\n", i, *get_errno_ptr());
+ printf("receiver_thread: ERROR mq_receive failure on msg %d, errno=%d\n", i, errno);
nerrors++;
}
else
diff --git a/apps/examples/ostest/sighand.c b/apps/examples/ostest/sighand.c
index 46650be1c..66f98cb58 100644
--- a/apps/examples/ostest/sighand.c
+++ b/apps/examples/ostest/sighand.c
@@ -1,7 +1,7 @@
/***********************************************************************
- * examples/ostest/sighand.c
+ * apps/examples/ostest/sighand.c
*
- * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -160,7 +160,7 @@ static int waiter_main(int argc, char *argv[])
status = sem_wait(&sem);
if (status != 0)
{
- int error = *get_errno_ptr();
+ int error = errno;
if (error == EINTR)
{
printf("waiter_main: sem_wait() successfully interrupted by signal\n" );
diff --git a/apps/examples/ostest/timedmqueue.c b/apps/examples/ostest/timedmqueue.c
index 9c14ec414..49fe1c4c6 100644
--- a/apps/examples/ostest/timedmqueue.c
+++ b/apps/examples/ostest/timedmqueue.c
@@ -1,7 +1,7 @@
/**************************************************************************
- * examples/ostest/mqueue.c
+ * apps/examples/ostest/mqueue.c
*
- * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -157,13 +157,13 @@ static void *sender_thread(void *arg)
status = mq_timedsend(mqfd, msg_buffer, TEST_MSGLEN, 42, &time);
if (status < 0)
{
- if (i == TEST_SEND_NMSGS-1 && *get_errno_ptr() == ETIMEDOUT)
+ if (i == TEST_SEND_NMSGS-1 && errno == ETIMEDOUT)
{
printf("sender_thread: mq_timedsend %d timed out as expected\n", i);
}
else
{
- printf("sender_thread: ERROR mq_timedsend failure=%d on msg %d\n", *get_errno_ptr(), i);
+ printf("sender_thread: ERROR mq_timedsend failure=%d on msg %d\n", errno, i);
nerrors++;
}
}
@@ -248,13 +248,13 @@ static void *receiver_thread(void *arg)
nbytes = mq_timedreceive(mqfd, msg_buffer, TEST_MSGLEN, 0, &time);
if (nbytes < 0)
{
- if (i == TEST_SEND_NMSGS-1 && *get_errno_ptr() == ETIMEDOUT)
+ if (i == TEST_SEND_NMSGS-1 && errno == ETIMEDOUT)
{
printf("receiver_thread: Receive %d timed out as expected\n", i);
}
else
{
- printf("receiver_thread: ERROR mq_timedreceive failure=%d on msg %d\n", *get_errno_ptr(), i);
+ printf("receiver_thread: ERROR mq_timedreceive failure=%d on msg %d\n", errno, i);
nerrors++;
}
}
diff --git a/apps/namedapp/binfs.c b/apps/namedapp/binfs.c
index 15ed4cc88..a2f14dd75 100644
--- a/apps/namedapp/binfs.c
+++ b/apps/namedapp/binfs.c
@@ -156,7 +156,7 @@ static void binfs_semtake(struct binfs_state_s *bm)
* the wait was awakened by a signal.
*/
- ASSERT(*get_errno_ptr() == EINTR);
+ ASSERT(errno == EINTR);
}
}
diff --git a/apps/netutils/dhcpc/dhcpc.c b/apps/netutils/dhcpc/dhcpc.c
index dc80988bb..b5551c6f1 100644
--- a/apps/netutils/dhcpc/dhcpc.c
+++ b/apps/netutils/dhcpc/dhcpc.c
@@ -492,7 +492,7 @@ int dhcpc_request(void *handle, struct dhcpc_state *presult)
* Then loop and send the DISCOVER command again.
*/
- else if (*get_errno_ptr() != EAGAIN)
+ else if (errno != EAGAIN)
{
/* An error other than a timeout was received -- error out */
@@ -570,7 +570,7 @@ int dhcpc_request(void *handle, struct dhcpc_state *presult)
* 3 times).
*/
- else if (*get_errno_ptr() != EAGAIN)
+ else if (errno != EAGAIN)
{
/* An error other than a timeout was received */
diff --git a/apps/netutils/thttpd/thttpd_cgi.c b/apps/netutils/thttpd/thttpd_cgi.c
index ee126795a..3d2eb57b8 100755
--- a/apps/netutils/thttpd/thttpd_cgi.c
+++ b/apps/netutils/thttpd/thttpd_cgi.c
@@ -152,7 +152,7 @@ static inline void cgi_semtake(void)
* awakened by a signal.
*/
- ASSERT(*get_errno_ptr() == EINTR);
+ ASSERT(errno == EINTR);
}
}
diff --git a/apps/nshlib/nsh_apps.c b/apps/nshlib/nsh_apps.c
index a8f9eb9bf..c41f2448a 100644
--- a/apps/nshlib/nsh_apps.c
+++ b/apps/nshlib/nsh_apps.c
@@ -46,6 +46,7 @@
#include <stdbool.h>
#include <errno.h>
+#include <string.h>
#include <apps/apps.h>
@@ -98,7 +99,8 @@ int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
{
int err = -errno;
int i;
-
+
+#ifndef CONFIG_APPS_BINDIR
/* On failure, list the set of available built-in commands */
nsh_output(vtbl, "Builtin Apps: ");
@@ -116,6 +118,9 @@ int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
}
return OK;
+#else
+ return err;
+#endif
}
#ifdef CONFIG_SCHED_WAITPID
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index b1a1903df..13e40f303 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -1642,5 +1642,14 @@
unable to replicate the build problems in my environment, but the changes
have be incorporated in hope of correcting the build issues in other
environments.
+ * drivers/i2c/st_lis331dl.c: I2C-based driver for the LIS331DL MEMS
+ motion sensor. Contributed by Uros Platise.
+ * Makefile: The NuttX build system will now supported building NuttX as two
+ separately linked images: (1) a kernel-mode RTOS image, and (2) a user-
+ mode application image that communicates to the RTOS kernel via system
+ calls. A lot more still must be done.
+
+
+
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index 224b1bef8..5721c5eff 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
- <p>Last Updated: March 30, 2011</p>
+ <p>Last Updated: April 3, 2011</p>
</td>
</tr>
</table>
@@ -2188,11 +2188,28 @@ nuttx-6.1 2011-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
* syscall/: The beginnings of an optional syscall kernel interface.
* tools/mksyscall.c: Add a tool that will auto-generate syscall proxies
and stubs from a comma-separated-value (CSV) data file.
+ * arch/arm/src/cortexm3/mpu.h: Add a header file describing the Cortex-M3
+ MPU registers.
+ * Numerous modifications to the build system. Various people have reported
+ build problems since the re-organization and release of NuttX-6.0. I am
+ unable to replicate the build problems in my environment, but the changes
+ have be incorporated in hope of correcting the build issues in other
+ environments.
+ * drivers/i2c/st_lis331dl.c: I2C-based driver for the LIS331DL MEMS
+ motion sensor. Contributed by Uros Platise.
+ * Makefile: The NuttX build system will now supported building NuttX as two
+ separately linked images: (1) a kernel-mode RTOS image, and (2) a user-
+ mode application image that communicates to the RTOS kernel via system
+ calls. A lot more still must be done.
apps-6.1 2011-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
* Creation of auto-generated header files now occurs during the context
build phase.
+ * Added sdcard insert and eject, nsh command '?' and some code remarks
+ * Renamed nuttapp to namedapp
+ * namedapp/binfs.c -- Create a tiny filesystem that can be used
+ to show the internal named apps under /bin.
pascal-2.1 2011-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html
index ef444506f..eaa603a4a 100644
--- a/nuttx/Documentation/NuttxPortingGuide.html
+++ b/nuttx/Documentation/NuttxPortingGuide.html
@@ -12,7 +12,7 @@
<h1><big><font color="#3c34ec">
<i>NuttX RTOS Porting Guide</i>
</font></big></h1>
- <p>Last Updated: April 1, 2011</p>
+ <p>Last Updated: April 3, 2011</p>
</td>
</tr>
</table>
@@ -2034,7 +2034,7 @@ extern void up_ledoff(int led);
<ul>
<li>
<p>
- <b><code>include/nuttx/i2c.h</code></b>.
+ <b><code>include/nuttx/i2c/i2c.h</code></b>.
All structures and APIs needed to work with I2C drivers are provided in this header file.
</p>
</li>
@@ -2790,7 +2790,7 @@ build
Two-pass Build Options.
If the 2 pass build option is selected, then these options configure the make system build a extra link object.
This link object is assumed to be an incremental (relative) link object, but could be a static library (archive)
- (some modification to this Makefile would be required if CONFIG_PASS1_OBJECT is an archive).
+ (some modification to this Makefile would be required if CONFIG_PASS1_TARGET generates an archive).
Pass 1 1ncremental (relative) link objects should be put into the processor-specific source directory
where other link objects will be created - ff the pass1 obect is an archive, it could go anywhere.
</p>
@@ -2805,15 +2805,27 @@ build
</p>
<ul>
<li>
- <code>CONFIG_PASS1_OBJECT</code>: The name of the first pass object.
+ <p>
+ <code>CONFIG_PASS1_TARGET</code>: The name of the first pass build target.
+ </p>
</li>
<li><code>CONFIG_PASS1_BUILDIR</code>:
- The path, relative to the top NuttX build directory to directory that contains the Makefile to build the first pass object.
- The Makefile must support the following targets:
- <ul>
- <li>The special target <code>arch/$(CONFIG_ARCH)/src/$(CONFIG_PASS1_OBJECT)</code>, and</li>
- <li>The usual depend, clean, and distclean targets.</li>
- </ul>
+ <p>
+ The path, relative to the top NuttX build directory to directory that contains the Makefile to build the first pass object.
+ The Makefile must support the following targets:
+ </p>
+ <p>
+ <ul>
+ <li>The special target <code>CONFIG_PASS1_TARGET</code> (if defined), and</li>
+ <li>The usual depend, clean, and distclean targets.</li>
+ </ul>
+ </p>
+ </li>
+ <li>
+ <code>CONFIG_PASS1_OBJECT</code>: May be used to include an extra, pass1 object into the final link.
+ This would probably be the object generated from the <code>CONFIG_PASS1_TARGET</code>.
+ It may be available at link time in the <code>arch/&lt;architecture&gt;/src</code> directory.
+ </li>
</ul>
<h2>General OS setup</h2>
diff --git a/nuttx/Makefile b/nuttx/Makefile
index dea43c109..1ecc8563e 100644
--- a/nuttx/Makefile
+++ b/nuttx/Makefile
@@ -153,7 +153,6 @@ CLEANDIRS += net
# be created). If the pass1 obect is an archive, it could go anywhere.
ifeq ($(CONFIG_BUILD_2PASS),y)
-#EXTRA_OBJS = $(TOPDIR)/$(CONFIG_PASS1_BUILDIR)/$(CONFIG_PASS1_OBJECT)
EXTRA_OBJS += $(CONFIG_PASS1_OBJECT)
endif
@@ -168,11 +167,12 @@ NUTTXLIBS = sched/libsched$(LIBEXT) $(ARCH_SRC)/libarch$(LIBEXT) mm/libmm$(LIBEX
lib/liblib$(LIBEXT)
USERLIBS =
-# Add libraries for syscall support.
+# Add libraries for syscall support. The C library will be needed by
+# both the kernel- and user-space builds.
ifeq ($(CONFIG_NUTTX_KERNEL),y)
NUTTXLIBS += syscall/libstubs$(LIBEXT)
-USERLIBS += syscall/libproxies$(LIBEXT)
+USERLIBS += syscall/libproxies$(LIBEXT) lib/liblib$(LIBEXT)
endif
# Add libraries for network support. CXX, CXXFLAGS, and COMPILEXX must
@@ -334,19 +334,17 @@ syscall/libproxies$(LIBEXT): context
@$(MAKE) -C syscall TOPDIR="$(TOPDIR)" libproxies$(LIBEXT)
# If the 2 pass build option is selected, then this pass1 target is
-# configured be build a extra link object. This is assumed to be an
-# incremental (relative) link object, but could be a static library
-# (archive); some modification to this Makefile would be required if
-# CONFIG_PASS1_OBJECT is an archive.
+# configured to built before the pass2 target. This pass1 target may, as an
+# example, build an extra link object (CONFIG_PASS1_OBJECT) which may be an
+# incremental (relative) link object, but could be a static library (archive);
+# some modification to this Makefile would be required if CONFIG_PASS1_OBJECT
+# is an archive. Exactly what is performed during pass1 or what it generates
+# is unknown to this makefule unless CONFIG_PASS1_OBJECT is defined.
pass1deps: context depend $(USERLIBS)
pass1: pass1deps
ifeq ($(CONFIG_BUILD_2PASS),y)
- @if [ -z "$(CONFIG_PASS1_OBJECT)" ]; then \
- echo "ERROR: CONFIG_PASS1_OBJECT not defined"; \
- exit 1; \
- fi
@if [ -z "$(CONFIG_PASS1_BUILDIR)" ]; then \
echo "ERROR: CONFIG_PASS1_BUILDIR not defined"; \
exit 1; \
@@ -359,7 +357,7 @@ ifeq ($(CONFIG_BUILD_2PASS),y)
echo "ERROR: No Makefile in CONFIG_PASS1_BUILDIR"; \
exit 1; \
fi
- @$(MAKE) -C $(CONFIG_PASS1_BUILDIR) TOPDIR="$(TOPDIR)" LINKLIBS="$(NUTTXLIBS)" USERLIBS="$(USERLIBS)" "$(ARCH_SRC)/$(CONFIG_PASS1_OBJECT)"
+ @$(MAKE) -C $(CONFIG_PASS1_BUILDIR) TOPDIR="$(TOPDIR)" LINKLIBS="$(NUTTXLIBS)" USERLIBS="$(USERLIBS)" "$(CONFIG_PASS1_TARGET)"
endif
pass2deps: context depend $(NUTTXLIBS)
diff --git a/nuttx/TODO b/nuttx/TODO
index 99be2df88..d9b2491b0 100644
--- a/nuttx/TODO
+++ b/nuttx/TODO
@@ -1,4 +1,4 @@
-NuttX TODO List (Last updated March 16 2011)
+NuttX TODO List (Last updated April 2 2011)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
nuttx/
@@ -19,7 +19,7 @@ nuttx/
(1) Documentation (Documentation/)
(5) Build system / Toolchains
(7) Linux/Cywgin simulation (arch/sim)
- (3) ARM (arch/arm/)
+ (4) ARM (arch/arm/)
(1) ARM/C5471 (arch/arm/src/c5471/)
(3) ARM/DM320 (arch/arm/src/dm320/)
(2) ARM/i.MX (arch/arm/src/imx/)
@@ -612,6 +612,14 @@ o ARM (arch/arm/)
Status: Open
Priority: Low
+ Description: The ARM interrupt handling (arch/arm/src/arm/up_vectors.S) returns
+ using 'ldmia sp, {r0-r15}^' My understanding is that this works
+ fine because everything is in kernel-mode. In an operating model
+ where applications run in user mode and interrupts/traps run in
+ kernel-mode, I think that there is a problem with this.
+ Status: Open
+ Priority: Low until I get around to implement security for the ARM platform.
+
o ARM/C5471 (arch/arm/src/c5471/)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/nuttx/arch/arm/src/lpc313x/lpc313x_i2c.c b/nuttx/arch/arm/src/lpc313x/lpc313x_i2c.c
index 137b2b315..dc2e454b9 100644
--- a/nuttx/arch/arm/src/lpc313x/lpc313x_i2c.c
+++ b/nuttx/arch/arm/src/lpc313x/lpc313x_i2c.c
@@ -50,7 +50,7 @@
#include <debug.h>
#include <nuttx/arch.h>
-#include <nuttx/i2c.h>
+#include <nuttx/i2c/i2c.h>
#include <arch/irq.h>
#include <arch/board/board.h>
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h b/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h
index 3510b2f41..00a24b355 100644
--- a/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h
@@ -102,7 +102,7 @@
#define I2C_CR2_FREQ_SHIFT (0) /* Bits 5-0: Peripheral Clock Frequency */
#define I2C_CR2_FREQ_MASK (0x3f << I2C_CR2_FREQ_SHIFT)
#define I2C_CR2_ITERREN (1 << 8) /* Bit 8: Error Interrupt Enable */
-#define I2C_CR2_ITEVTEN (1 << 9) /* Bit 9: Event Interrupt Enable */
+#define I2C_CR2_ITEVFEN (1 << 9) /* Bit 9: Event Interrupt Enable */
#define I2C_CR2_ITBUFEN (1 << 10) /* Bit 10: Buffer Interrupt Enable */
#define I2C_CR2_DMAEN (1 << 11) /* Bit 11: DMA Requests Enable */
#define I2C_CR2_LAST (1 << 12) /* Bit 12: DMA Last Transfer */
@@ -135,6 +135,7 @@
#define I2C_SR1_BTF (1 << 2) /* Bit 2: Byte Transfer Finished */
#define I2C_SR1_ADD10 (1 << 3) /* Bit 3: 10-bit header sent (Master mode) */
#define I2C_SR1_STOPF (1 << 4) /* Bit 4: Stop detection (Slave mode) */
+ /* Bit 5: Reserved */
#define I2C_SR1_RXNE (1 << 6) /* Bit 6: Data Register not Empty (receivers) */
#define I2C_SR1_TXE (1 << 7) /* Bit 7: Data Register Empty (transmitters) */
#define I2C_SR1_BERR (1 << 8) /* Bit 8: Bus Error */
@@ -142,9 +143,12 @@
#define I2C_SR1_AF (1 << 10) /* Bit 10: Acknowledge Failure */
#define I2C_SR1_OVR (1 << 11) /* Bit 11: Overrun/Underrun */
#define I2C_SR1_PECERR (1 << 12) /* Bit 12: PEC Error in reception */
+ /* Bit 13: Reserved */
#define I2C_SR1_TIMEOUT (1 << 14) /* Bit 14: Timeout or Tlow Error */
#define I2C_SR1_SMBALERT (1 << 15) /* Bit 15: SMBus Alert */
+#define I2C_SR1_ERRORMASK (I2C_SR1_BERR|I2C_SR1_ARLO|I2C_SR1_AF|I2C_SR1_OVR|I2C_SR1_PECERR)
+
/* Status register 2 */
#define I2C_SR2_MSL (1 << 0) /* Bit 0: Master/Slave */
diff --git a/nuttx/arch/arm/src/stm32/stm32_i2c.c b/nuttx/arch/arm/src/stm32/stm32_i2c.c
index 05afd5a7b..de9ca60c8 100644
--- a/nuttx/arch/arm/src/stm32/stm32_i2c.c
+++ b/nuttx/arch/arm/src/stm32/stm32_i2c.c
@@ -43,14 +43,15 @@
* - Interrupt based operation
*
* Structure naming:
- * - Device: structure as defined by the nuttx/i2c.h
+ * - Device: structure as defined by the nuttx/i2c/i2c.h
* - Instance: represents each individual access to the I2C driver, obtained by
- * the i2c_init(); it extends the Device structure from the nuttx/i2c.h;
+ * the i2c_init(); it extends the Device structure from the nuttx/i2c/i2c.h;
* Instance points to OPS, to common I2C Hardware private data and contains
* its own private data, as frequency, address, mode of operation (in the future)
* - Private: Private data of an I2C Hardware
*
* \todo
+ * - Check for all possible deadlocks (as BUSY='1' I2C needs to be reset in HW using the I2C_CR1_SWRST)
* - SMBus support (hardware layer timings are already supported) and add SMBA gpio pin
* - Slave support with multiple addresses (on multiple instances):
* - 2 x 7-bit address or
@@ -64,9 +65,11 @@
#include <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
+#include <nuttx/i2c/i2c.h>
#include <arch/board/board.h>
#include <sys/types.h>
+#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
@@ -79,6 +82,7 @@
#include "stm32_rcc.h"
#include "stm32_i2c.h"
+
#if defined(CONFIG_STM32_I2C1) || defined(CONFIG_STM32_I2C2)
/************************************************************************************
@@ -91,10 +95,16 @@
struct stm32_i2c_priv_s {
uint32_t base;
int refs;
- sem_t sem;
+ sem_t sem_excl;
+ sem_t sem_isr;
uint8_t msgc;
- FAR struct i2c_msg_s *msgv;
+ struct i2c_msg_s *msgv;
+ uint8_t * ptr;
+ int dcnt;
+ uint16_t flags;
+
+ uint32_t status;
};
@@ -134,62 +144,72 @@ struct stm32_i2c_priv_s stm32_i2c2_priv = {
************************************************************************************/
/** Get register value by offset */
-static inline uint16_t stm32_i2c_getreg(FAR struct i2c_dev_s *dev, uint8_t offset)
+static inline uint16_t stm32_i2c_getreg(FAR struct stm32_i2c_priv_s *priv, uint8_t offset)
{
- return getreg16( ((struct stm32_i2c_inst_s *)dev)->priv->base + offset);
+ return getreg16(priv->base + offset);
}
/** Put register value by offset */
-static inline void stm32_i2c_putreg(FAR struct i2c_dev_s *dev, uint8_t offset, uint16_t value)
+static inline void stm32_i2c_putreg(FAR struct stm32_i2c_priv_s *priv, uint8_t offset, uint16_t value)
{
- //printf("putreg(%8x)=%4x\n", ((struct stm32_i2c_priv_s *)dev)->base + offset, value );
- putreg16(value, ((struct stm32_i2c_inst_s *)dev)->priv->base + offset);
+ putreg16(value, priv->base + offset);
}
/** Modify register value by offset */
-static inline void stm32_i2c_modifyreg(FAR struct i2c_dev_s *dev, uint8_t offset, uint16_t clearbits, uint16_t setbits)
+static inline void stm32_i2c_modifyreg(FAR struct stm32_i2c_priv_s *priv, uint8_t offset, uint16_t clearbits, uint16_t setbits)
{
- modifyreg16( ((struct stm32_i2c_inst_s *)dev)->priv->base + offset, clearbits, setbits);
+ modifyreg16(priv->base + offset, clearbits, setbits);
}
void inline stm32_i2c_sem_wait(FAR struct i2c_dev_s *dev)
{
- while( sem_wait( &((struct stm32_i2c_inst_s *)dev)->priv->sem ) != 0 ) {
+ while( sem_wait( &((struct stm32_i2c_inst_s *)dev)->priv->sem_excl ) != 0 ) {
ASSERT(errno == EINTR);
}
}
+int inline stm32_i2c_sem_waitisr(FAR struct i2c_dev_s *dev)
+{
+ while( sem_wait( &((struct stm32_i2c_inst_s *)dev)->priv->sem_isr ) != 0 ) {
+ ASSERT(errno == EINTR);
+ }
+ return OK;
+}
+
+
void inline stm32_i2c_sem_post(FAR struct i2c_dev_s *dev)
{
- sem_post( &((struct stm32_i2c_inst_s *)dev)->priv->sem );
+ sem_post( &((struct stm32_i2c_inst_s *)dev)->priv->sem_excl );
}
void inline stm32_i2c_sem_init(FAR struct i2c_dev_s *dev)
{
- sem_init( &((struct stm32_i2c_inst_s *)dev)->priv->sem, 0, 1);
+ sem_init( &((struct stm32_i2c_inst_s *)dev)->priv->sem_excl, 0, 1);
+ sem_init( &((struct stm32_i2c_inst_s *)dev)->priv->sem_isr, 0, 0);
}
void inline stm32_i2c_sem_destroy(FAR struct i2c_dev_s *dev)
{
- sem_destroy( &((struct stm32_i2c_inst_s *)dev)->priv->sem );
+ sem_destroy( &((struct stm32_i2c_inst_s *)dev)->priv->sem_excl );
+ sem_destroy( &((struct stm32_i2c_inst_s *)dev)->priv->sem_isr );
}
-static void stm32_i2c_setclock(FAR struct i2c_dev_s *inst, uint32_t frequency)
+static void stm32_i2c_setclock(FAR struct stm32_i2c_priv_s *priv, uint32_t frequency)
{
/* Disable Peripheral if rising time is to be changed,
* and restore state on return. */
- uint16_t cr1 = stm32_i2c_getreg(inst, STM32_I2C_CR1_OFFSET);
+ uint16_t cr1 = stm32_i2c_getreg(priv, STM32_I2C_CR1_OFFSET);
if (cr1 & I2C_CR1_PE)
- stm32_i2c_putreg(inst, STM32_I2C_CR1_OFFSET, cr1 ^ I2C_CR1_PE);
+ stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, cr1 ^ I2C_CR1_PE);
/* Update timing and control registers */
@@ -199,8 +219,8 @@ static void stm32_i2c_setclock(FAR struct i2c_dev_s *inst, uint32_t frequency)
* Risetime: 1000 ns
* Duty: t_low / t_high = 1
*/
- stm32_i2c_putreg(inst, STM32_I2C_CCR_OFFSET, STM32_BOARD_HCLK/200000);
- stm32_i2c_putreg(inst, STM32_I2C_TRISE_OFFSET, 1 + STM32_BOARD_HCLK/1000000);
+ stm32_i2c_putreg(priv, STM32_I2C_CCR_OFFSET, STM32_BOARD_HCLK/200000);
+ stm32_i2c_putreg(priv, STM32_I2C_TRISE_OFFSET, 1 + STM32_BOARD_HCLK/1000000);
}
else {
@@ -208,68 +228,206 @@ static void stm32_i2c_setclock(FAR struct i2c_dev_s *inst, uint32_t frequency)
* Risetime: 1000 ns ??? \todo check rise time for 400 kHz devices
* Duty: t_low / t_high = 2
*/
- stm32_i2c_putreg(inst, STM32_I2C_CCR_OFFSET, STM32_BOARD_HCLK/1200000);
- stm32_i2c_putreg(inst, STM32_I2C_TRISE_OFFSET, 1 + STM32_BOARD_HCLK/1000000);
+ stm32_i2c_putreg(priv, STM32_I2C_CCR_OFFSET, STM32_BOARD_HCLK/1200000);
+ stm32_i2c_putreg(priv, STM32_I2C_TRISE_OFFSET, 1 + STM32_BOARD_HCLK/1000000);
}
/* Restore state */
if (cr1 & I2C_CR1_PE)
- stm32_i2c_putreg(inst, STM32_I2C_CR1_OFFSET, cr1);
+ stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, cr1);
}
-static inline void stm32_i2c_sendstart(FAR struct i2c_dev_s *inst)
+static inline void stm32_i2c_sendstart(FAR struct stm32_i2c_priv_s *priv)
{
- stm32_i2c_modifyreg(inst, STM32_I2C_CR1_OFFSET, 0, I2C_CR1_START);
+ /* Disable ACK on receive by default and generate START */
+ stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, I2C_CR1_START);
}
-static inline void stm32_i2c_sendstop(FAR struct i2c_dev_s *inst)
+static inline void stm32_i2c_sendstop(FAR struct stm32_i2c_priv_s *priv)
{
- stm32_i2c_modifyreg(inst, STM32_I2C_CR1_OFFSET, 0, I2C_CR1_STOP);
+ stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, I2C_CR1_STOP);
+}
+
+
+static inline uint32_t stm32_i2c_getstatus(FAR struct stm32_i2c_priv_s *priv)
+{
+ uint32_t status = stm32_i2c_getreg(priv, STM32_I2C_SR1_OFFSET);
+ status |= (stm32_i2c_getreg(priv, STM32_I2C_SR2_OFFSET) << 16);
+ return status;
}
/************************************************************************************
* Interrupt Service Routines
************************************************************************************/
-
-static int stm32_i2c_event_isr(struct stm32_i2c_priv_s * priv)
-{
- return OK;
-}
-
+//DEBUG TO BE CLEANED
+//#define NON_ISR
-static int stm32_i2c_error_isr(struct stm32_i2c_priv_s * priv)
+static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
{
+ uint32_t status = stm32_i2c_getstatus(priv);
+
+#ifdef NON_ISR
+ static uint32_t isr_count = 0;
+ static uint32_t old_status = 0xFFFF;
+
+ isr_count++;
+
+ if (old_status != status) {
+ printf("status = %8x, count=%d\n", status, isr_count); fflush(stdout);
+ old_status = status;
+ }
+#endif
+
+ /* Was start bit sent */
+
+ if (status & I2C_SR1_SB) {
+
+ /* Get run-time data */
+
+ priv->ptr = priv->msgv->buffer;
+ priv->dcnt = priv->msgv->length;
+ priv->flags = priv->msgv->flags;
+
+ /* Send address byte and define addressing mode */
+
+ stm32_i2c_putreg(priv, STM32_I2C_DR_OFFSET, (priv->flags & I2C_M_TEN) ?
+ 0 :
+ ((priv->msgv->addr << 1) | (priv->flags & I2C_M_READ))
+ );
+
+ /* Enable RxNE and TxE buffers */
+
+ stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, 0, I2C_CR2_ITBUFEN);
+
+ /* Increment to next pointer and decrement message count */
+
+ priv->msgv++;
+ priv->msgc--;
+ }
+
+ /* In 10-bit addressing mode, was first byte sent */
+
+ else if (status & I2C_SR1_ADD10) {
+ /* \todo Finish 10-bit mode addressing */
+ }
+
+ /* Was address sent, continue with ether sending or reading data */
+
+ else if ( !(priv->flags & I2C_M_READ) &&
+ (status & (I2C_SR1_ADDR | I2C_SR1_TXE)) ) {
+
+ if (--priv->dcnt >= 0) { /* Send a byte */
+#ifdef NON_ISR
+ printf("Send byte: %2x\n", *priv->ptr);
+#endif
+ stm32_i2c_putreg(priv, STM32_I2C_DR_OFFSET, *priv->ptr++);
+ }
+ }
+
+ else if ( (priv->flags & I2C_M_READ) && (status & I2C_SR1_ADDR) ) {
+
+ /* Acknowledge bytes if there is more than one to be received */
+
+ if (priv->dcnt > 1) {
+ stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, 0, I2C_CR1_ACK);
+ }
+ }
+
+ /* More bytes to read */
+
+ else if ( status & I2C_SR1_RXNE ) {
+
+ /* Read a byte, if dcnt goes < 0, then read dummy bytes to ack ISRs */
+
+#ifdef NON_ISR
+ printf("dcnt=%d\n", priv->dcnt);
+#endif
+ if (--priv->dcnt >= 0) {
+ *priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET);
+#ifdef NON_ISR
+ printf("Received: %2x\n", *(priv->ptr-1) );
+#endif
+ /* Disable acknowledge when last byte is to be received */
+ if (priv->dcnt == 1) {
+ stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, 0);
+ }
+ }
+ }
+
+
+ /* Was last byte received or sent?
+ */
+
+ if (priv->dcnt<=0 && (status & I2C_SR1_BTF)) {
+#ifdef NON_ISR
+ printf("BTF\n");
+#endif
+ stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); /* ACK ISR */
+
+ /* Do we need to terminate or restart after this byte */
+
+ /* If there are more messages to send, then we may:
+ * - continue with repeated start
+ * - or just continue sending writeable part
+ * - or we close down by sending the stop bit
+ */
+ if (priv->msgc) {
+
+ if (priv->msgv->flags & I2C_M_NORESTART) {
+ priv->ptr = priv->msgv->buffer;
+ priv->dcnt = priv->msgv->length;
+ priv->flags = priv->msgv->flags;
+ priv->msgv++;
+ priv->msgc--;
+ }
+ else {
+ stm32_i2c_sendstart(priv);
+ }
+ }
+ else if (priv->msgv) {
+#ifdef NON_ISR
+ printf("stop2: status = %8x\n", status);
+#endif
+ stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_ITBUFEN, 0);
+ stm32_i2c_sendstop(priv);
+ sem_post( &priv->sem_isr );
+ priv->msgv = NULL; /* mark that we have stopped with this transaction */
+ }
+ }
+
+ /* Check for errors, in which case, stop the transfer and return
+ * Note that in master reception mode AF becomes set on last byte
+ * since ACK is not returned. We should ignore this error.
+ */
+
+ if (status & I2C_SR1_ERRORMASK) {
+ stm32_i2c_putreg(priv, STM32_I2C_SR1_OFFSET, 0); /* clear flags */
+ sem_post( &priv->sem_isr );
+ }
+
+ priv->status = status;
return OK;
}
+
/* Decode ***************************************************************************/
#if CONFIG_STM32_I2C1
-static int stm32_i2c1_event_isr(int irq, void *context)
-{
- return stm32_i2c_event_isr(&stm32_i2c1_priv);
-}
-
-static int stm32_i2c1_error_isr(int irq, void *context)
+static int stm32_i2c1_isr(int irq, void *context)
{
- return stm32_i2c_error_isr(&stm32_i2c1_priv);
+ return stm32_i2c_isr(&stm32_i2c1_priv);
}
#endif
#if CONFIG_STM32_I2C2
-static int stm32_i2c2_event_isr(int irq, void *context)
-{
- return stm32_i2c_event_isr(&stm32_i2c2_priv);
-}
-
-static int stm32_i2c2_error_isr(int irq, void *context)
+static int stm32_i2c2_isr(int irq, void *context)
{
- return stm32_i2c_error_isr(&stm32_i2c1_priv);
+ return stm32_i2c_isr(&stm32_i2c2_priv);
}
#endif
@@ -279,11 +437,11 @@ static int stm32_i2c2_error_isr(int irq, void *context)
************************************************************************************/
/** Setup the I2C hardware, ready for operation with defaults */
-static int stm32_i2c_init(FAR struct i2c_dev_s *inst)
+static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv)
{
/* Power-up and configure GPIOs */
- switch( ((struct stm32_i2c_inst_s *)inst)->priv->base ) {
+ switch( priv->base ) {
#if CONFIG_STM32_I2C1
case STM32_I2C1_BASE:
@@ -294,8 +452,8 @@ static int stm32_i2c_init(FAR struct i2c_dev_s *inst)
stm32_unconfiggpio(GPIO_I2C1_SCL);
return ERROR;
}
- irq_attach(STM32_IRQ_I2C1EV, stm32_i2c1_event_isr);
- irq_attach(STM32_IRQ_I2C1ER, stm32_i2c1_error_isr);
+ irq_attach(STM32_IRQ_I2C1EV, stm32_i2c1_isr);
+ irq_attach(STM32_IRQ_I2C1ER, stm32_i2c1_isr);
up_enable_irq(STM32_IRQ_I2C1EV);
up_enable_irq(STM32_IRQ_I2C1ER);
break;
@@ -310,8 +468,8 @@ static int stm32_i2c_init(FAR struct i2c_dev_s *inst)
stm32_unconfiggpio(GPIO_I2C2_SCL);
return ERROR;
}
- irq_attach(STM32_IRQ_I2C2EV, stm32_i2c2_event_isr);
- irq_attach(STM32_IRQ_I2C2ER, stm32_i2c2_error_isr);
+ irq_attach(STM32_IRQ_I2C2EV, stm32_i2c2_isr);
+ irq_attach(STM32_IRQ_I2C2ER, stm32_i2c2_isr);
up_enable_irq(STM32_IRQ_I2C2EV);
up_enable_irq(STM32_IRQ_I2C2ER);
break;
@@ -324,29 +482,31 @@ static int stm32_i2c_init(FAR struct i2c_dev_s *inst)
* for 100 kHz or 4 MHz for 400 kHz. Enable interrupt generation.
*/
- stm32_i2c_putreg(inst, STM32_I2C_CR2_OFFSET,
- I2C_CR2_ITERREN | I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN |
+ stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET,
+#ifndef NON_ISR
+ I2C_CR2_ITERREN | I2C_CR2_ITEVFEN | // I2C_CR2_ITBUFEN |
+#endif
(STM32_BOARD_HCLK / 1000000)
);
- stm32_i2c_setclock(inst, 100000);
+ stm32_i2c_setclock(priv, 100000);
/* Enable I2C */
- stm32_i2c_putreg(inst, STM32_I2C_CR1_OFFSET, I2C_CR1_PE);
+ stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_PE);
return OK;
}
/** Shutdown the I2C hardware */
-static int stm32_i2c_deinit(FAR struct i2c_dev_s *inst)
+static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv)
{
/* Disable I2C */
- stm32_i2c_putreg(inst, STM32_I2C_CR1_OFFSET, 0);
+ stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, 0);
- switch( ((struct stm32_i2c_inst_s *)inst)->priv->base ) {
+ switch( priv->base ) {
#if CONFIG_STM32_I2C1
case STM32_I2C1_BASE:
@@ -387,116 +547,164 @@ static int stm32_i2c_deinit(FAR struct i2c_dev_s *inst)
* Device Driver OPS - Blocking Type
************************************************************************************/
-uint32_t stm32_i2c_setfrequency(FAR struct i2c_dev_s *inst, uint32_t frequency)
+uint32_t stm32_i2c_setfrequency(FAR struct i2c_dev_s *dev, uint32_t frequency)
{
- stm32_i2c_sem_wait(inst);
+ stm32_i2c_sem_wait(dev);
#if STM32_BOARD_HCLK < 4000000
- ((struct stm32_i2c_inst_s *)inst)->frequency = 100000;
+ ((struct stm32_i2c_inst_s *)dev)->frequency = 100000;
#else
- ((struct stm32_i2c_inst_s *)inst)->frequency = frequency;
+ ((struct stm32_i2c_inst_s *)dev)->frequency = frequency;
#endif
- stm32_i2c_sem_post(inst);
- return ((struct stm32_i2c_inst_s *)inst)->frequency;
+ stm32_i2c_sem_post(dev);
+ return ((struct stm32_i2c_inst_s *)dev)->frequency;
}
-int stm32_i2c_setaddress(FAR struct i2c_dev_s *inst, int addr, int nbits)
+int stm32_i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits)
{
- stm32_i2c_sem_wait(inst);
+ stm32_i2c_sem_wait(dev);
- ((struct stm32_i2c_inst_s *)inst)->address = addr;
- ((struct stm32_i2c_inst_s *)inst)->flags = (nbits == 10) ? I2C_M_TEN : 0;
+ ((struct stm32_i2c_inst_s *)dev)->address = addr;
+ ((struct stm32_i2c_inst_s *)dev)->flags = (nbits == 10) ? I2C_M_TEN : 0;
- stm32_i2c_sem_post(inst);
+ stm32_i2c_sem_post(dev);
return OK;
}
-int stm32_i2c_process(FAR struct i2c_dev_s *inst, FAR struct i2c_msg_s *msgs, int count)
+int stm32_i2c_process(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, int count)
{
+ struct stm32_i2c_inst_s *inst = (struct stm32_i2c_inst_s *)dev;
+ uint32_t status = 0;
+ int status_errno = 0;
+
+ ASSERT(count);
+
/* The semaphore already ensures that I2C is ours, since we do not yet support
* non-blocking operation.
*/
- ((struct stm32_i2c_inst_s *)inst)->priv->msgv = msgs;
- ((struct stm32_i2c_inst_s *)inst)->priv->msgc = count;
+ inst->priv->msgv = msgs;
+ inst->priv->msgc = count;
- stm32_i2c_setclock(inst, ((struct stm32_i2c_inst_s *)inst)->frequency);
- stm32_i2c_sendstart(inst);
+ stm32_i2c_setclock(inst->priv, inst->frequency);
/* Trigger start condition, then the process moves into the ISR,
- * until semaphore is posted.
+ * waiting again for the samaphore ... the resulting status is
+ * found in the local status variable.
*/
- stm32_i2c_sem_wait(inst); /* wait again for the semaphore and */
- stm32_i2c_sem_post(inst); /* release it immediately. */
- return OK;
+ stm32_i2c_sendstart(inst->priv);
+
+#ifdef NON_ISR
+ do {
+ do {
+ stm32_i2c_isr(&stm32_i2c1_priv);
+ status = inst->priv->status;
+ } while( status & (I2C_SR2_BUSY<<16) );
+ }
+ while( sem_trywait( &((struct stm32_i2c_inst_s *)dev)->priv->sem_isr ) != 0 );
+#else
+ /* Wait for an ISR, if there was a timeout, fetch latest status to get the BUSY flag */
+
+ if (stm32_i2c_sem_waitisr(dev) == ERROR) {
+ status = stm32_i2c_getstatus(inst->priv);
+ }
+ else status = inst->priv->status & 0xFFFF; /* clear SR2 (BUSY flag) as we've done successfully */
+#endif
+
+ if (status & I2C_SR1_BERR) { /* Bus Error */
+ status_errno = EIO;
+ }
+ else if (status & I2C_SR1_ARLO) { /* Arbitration Lost (master mode) */
+ status_errno = EAGAIN;
+ }
+ else if (status & I2C_SR1_AF) { /* Acknowledge Failure */
+ status_errno = ENXIO;
+ }
+ else if (status & I2C_SR1_OVR) { /* Overrun/Underrun */
+ status_errno = EIO;
+ }
+ else if (status & I2C_SR1_PECERR) { /* PEC Error in reception */
+ status_errno = EPROTO;
+ }
+ else if (status & I2C_SR1_TIMEOUT) {/* Timeout or Tlow Error */
+ status_errno = ETIME;
+ }
+ else if (status & (I2C_SR2_BUSY<<16) ) { /* I2C Bus is for some reason busy */
+ status_errno = EBUSY;
+ }
+
+ stm32_i2c_sem_post(dev);
+
+ errno = status_errno;
+ return -status_errno;
}
-int stm32_i2c_write(FAR struct i2c_dev_s *inst, const uint8_t *buffer, int buflen)
+int stm32_i2c_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer, int buflen)
{
- stm32_i2c_sem_wait(inst); /* ensure that address or flags don't change meanwhile */
+ stm32_i2c_sem_wait(dev); /* ensure that address or flags don't change meanwhile */
struct i2c_msg_s msgv = {
- .addr = ((struct stm32_i2c_inst_s *)inst)->address,
- .flags = ((struct stm32_i2c_inst_s *)inst)->flags,
+ .addr = ((struct stm32_i2c_inst_s *)dev)->address,
+ .flags = ((struct stm32_i2c_inst_s *)dev)->flags,
.buffer = (uint8_t *)buffer,
.length = buflen
};
- return stm32_i2c_process(inst, &msgv, 1);
+ return stm32_i2c_process(dev, &msgv, 1);
}
-int stm32_i2c_read(FAR struct i2c_dev_s *inst, uint8_t *buffer, int buflen)
+int stm32_i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
{
- stm32_i2c_sem_wait(inst); /* ensure that address or flags don't change meanwhile */
+ stm32_i2c_sem_wait(dev); /* ensure that address or flags don't change meanwhile */
struct i2c_msg_s msgv = {
- .addr = ((struct stm32_i2c_inst_s *)inst)->address,
- .flags = ((struct stm32_i2c_inst_s *)inst)->flags | I2C_M_READ,
+ .addr = ((struct stm32_i2c_inst_s *)dev)->address,
+ .flags = ((struct stm32_i2c_inst_s *)dev)->flags | I2C_M_READ,
.buffer = buffer,
.length = buflen
};
- return stm32_i2c_process(inst, &msgv, 1);
+ return stm32_i2c_process(dev, &msgv, 1);
}
#ifdef CONFIG_I2C_WRITEREAD
-int stm32_i2c_writeread(FAR struct i2c_dev_s *inst, const uint8_t *wbuffer, int wbuflen,
- uint8_t *rbuffer, int rbuflen)
+int stm32_i2c_writeread(FAR struct i2c_dev_s *dev, const uint8_t *wbuffer, int wbuflen,
+ uint8_t *buffer, int buflen)
{
- stm32_i2c_sem_wait(inst); /* ensure that address or flags don't change meanwhile */
+ stm32_i2c_sem_wait(dev); /* ensure that address or flags don't change meanwhile */
struct i2c_msg_s msgv[2] = {
{
- .addr = ((struct stm32_i2c_inst_s *)inst)->address,
- .flags = ((struct stm32_i2c_inst_s *)inst)->flags,
+ .addr = ((struct stm32_i2c_inst_s *)dev)->address,
+ .flags = ((struct stm32_i2c_inst_s *)dev)->flags,
.buffer = (uint8_t *)wbuffer, /* this is really ugly, sorry const ... */
.length = wbuflen
},
{
- .addr = ((struct stm32_i2c_inst_s *)inst)->address,
- .flags = ((struct stm32_i2c_inst_s *)inst)->flags | I2C_M_READ,
- .buffer = rbuffer,
- .length = rbuflen
+ .addr = ((struct stm32_i2c_inst_s *)dev)->address,
+ .flags = ((struct stm32_i2c_inst_s *)dev)->flags | ((buflen>0) ? I2C_M_READ : I2C_M_NORESTART),
+ .buffer = buffer,
+ .length = (buflen>0) ? buflen : -buflen
}
};
- return stm32_i2c_process(inst, msgv, 2);
+ return stm32_i2c_process(dev, msgv, 2);
}
#endif
#ifdef CONFIG_I2C_TRANSFER
-int stm32_i2c_transfer(FAR struct i2c_dev_s *inst, FAR struct i2c_msg_s *msgs, int count)
+int stm32_i2c_transfer(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, int count)
{
- stm32_i2c_sem_wait(inst); /* ensure that address or flags don't change meanwhile */
- return stm32_i2c_process(inst, msgs, count);
+ stm32_i2c_sem_wait(dev); /* ensure that address or flags don't change meanwhile */
+ return stm32_i2c_process(dev, msgs, count);
}
#endif
@@ -574,7 +782,7 @@ FAR struct i2c_dev_s * up_i2cinitialize(int port)
if ((volatile int)priv->refs++ == 0) {
stm32_i2c_sem_init( (struct i2c_dev_s *)inst );
- stm32_i2c_init( (struct i2c_dev_s *)inst );
+ stm32_i2c_init( priv );
}
irqrestore(irqs);
@@ -583,22 +791,22 @@ FAR struct i2c_dev_s * up_i2cinitialize(int port)
}
-int up_i2cuninitialize(FAR struct i2c_dev_s * inst)
+int up_i2cuninitialize(FAR struct i2c_dev_s * dev)
{
int irqs;
- ASSERT(inst);
+ ASSERT(dev);
/* Decrement refs and check for underflow */
- if ( ((struct stm32_i2c_inst_s *)inst)->priv->refs == 0 )
+ if ( ((struct stm32_i2c_inst_s *)dev)->priv->refs == 0 )
return ERROR;
irqs = irqsave();
- if ( --((struct stm32_i2c_inst_s *)inst)->priv->refs ) {
+ if ( --((struct stm32_i2c_inst_s *)dev)->priv->refs ) {
irqrestore(irqs);
- free(inst);
+ free(dev);
return OK;
}
@@ -606,13 +814,13 @@ int up_i2cuninitialize(FAR struct i2c_dev_s * inst)
/* Disable power and other HW resource (GPIO's) */
- stm32_i2c_deinit( (struct i2c_dev_s *)inst );
+ stm32_i2c_deinit( ((struct stm32_i2c_inst_s *)dev)->priv );
/* Release unused resources */
- stm32_i2c_sem_destroy( (struct i2c_dev_s *)inst );
+ stm32_i2c_sem_destroy( (struct i2c_dev_s *)dev );
- free(inst);
+ free(dev);
return OK;
}
diff --git a/nuttx/arch/arm/src/stm32/stm32_i2c.h b/nuttx/arch/arm/src/stm32/stm32_i2c.h
index 23a06bc05..9bb17521a 100755
--- a/nuttx/arch/arm/src/stm32/stm32_i2c.h
+++ b/nuttx/arch/arm/src/stm32/stm32_i2c.h
@@ -41,7 +41,7 @@
************************************************************************************/
#include <nuttx/config.h>
-#include <nuttx/i2c.h>
+#include <nuttx/i2c/i2c.h>
#include "chip.h"
#include "chip/stm32_i2c.h"
diff --git a/nuttx/arch/z80/src/ez80/ez80_i2c.c b/nuttx/arch/z80/src/ez80/ez80_i2c.c
index d9defb0cf..74dc89919 100644
--- a/nuttx/arch/z80/src/ez80/ez80_i2c.c
+++ b/nuttx/arch/z80/src/ez80/ez80_i2c.c
@@ -1,7 +1,7 @@
/****************************************************************************
* arch/z80/src/ez80/ez80_i2c.c
*
- * Copyright(C) 2009 Gregory Nutt. All rights reserved.
+ * Copyright(C) 2009, 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -47,7 +47,7 @@
#include <assert.h>
#include <debug.h>
-#include <nuttx/i2c.h>
+#include <nuttx/i2c/i2c.h>
#include <arch/io.h>
#include <arch/board/board.h>
diff --git a/nuttx/arch/z80/src/z8/z8_i2c.c b/nuttx/arch/z80/src/z8/z8_i2c.c
index 796f389ec..11825ac59 100755
--- a/nuttx/arch/z80/src/z8/z8_i2c.c
+++ b/nuttx/arch/z80/src/z8/z8_i2c.c
@@ -1,7 +1,7 @@
/****************************************************************************
* arch/z80/src/z8/z8_i2c.c
*
- * Copyright(C) 2009 Gregory Nutt. All rights reserved.
+ * Copyright(C) 2009, 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -47,7 +47,7 @@
#include <assert.h>
#include <debug.h>
-#include <nuttx/i2c.h>
+#include <nuttx/i2c/i2c.h>
#include <arch/board/board.h>
#include <eZ8.h> /* eZ8 Register definitions */
diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt
index 152a45645..560aa2a11 100644
--- a/nuttx/configs/README.txt
+++ b/nuttx/configs/README.txt
@@ -211,8 +211,8 @@ defconfig -- This is a configuration file similar to the Linux
options configure the make system build a extra link object. This link object
is assumed to be an incremental (relative) link object, but could be a static
library (archive) (some modification to this Makefile would be required if
- CONFIG_PASS1_OBJECT is an archive). Pass 1 1ncremental (relative) link objects
- should be put into the processor-specific source directory (where other
+ CONFIG_PASS1_TARGET generates an archive). Pass 1 1ncremental (relative) link
+ objects should be put into the processor-specific source directory (where other
link objects will be created). If the pass1 obect is an archive, it could
go anywhere.
@@ -220,12 +220,18 @@ defconfig -- This is a configuration file similar to the Linux
When the two pass build option is enabled, the following also apply:
- CONFIG_PASS1_OBJECT - The name of the first pass object.
+ CONFIG_PASS1_TARGET - The name of the first pass build target. This
+ can be specific build target, a special build target (all, default, etc.)
+ or may just be left undefined.
CONFIG_PASS1_BUILDIR - The path, relative to the top NuttX build
directory to directory that contains the Makefile to build the
first pass object. The Makefile must support the following targets:
- - The special target arch/$(CONFIG_ARCH)/src/$(CONFIG_PASS1_OBJECT)
+ - The special target CONFIG_PASS1_TARGET (if defined)
- and the usual depend, clean, and distclean targets.
+ CONFIG_PASS1_OBJECT - May be used to include an extra, pass1 object
+ into the final link. This would probably be the object generated
+ from the CONFIG_PASS1_TARGET. It may be available at link time
+ in the arch/<architecture>/src directory.
General OS setup
diff --git a/nuttx/configs/demo9s12ne64/ostest/defconfig b/nuttx/configs/demo9s12ne64/ostest/defconfig
index 80cec002f..b5b432759 100755
--- a/nuttx/configs/demo9s12ne64/ostest/defconfig
+++ b/nuttx/configs/demo9s12ne64/ostest/defconfig
@@ -189,7 +189,8 @@ CONFIG_HAVE_LIBM=n
#
CONFIG_BUILD_2PASS=n
CONFIG_PASS1_BUILDIR=configs/demo9s12ne64/initrel
-CONFIG_PASS1_OBJECT=init.r
+CONFIG_PASS1_TARGET=init.r
+CONFIG_PASS1_OBJECT=
#
# General OS setup
diff --git a/nuttx/configs/ea3131/locked/Makefile b/nuttx/configs/ea3131/locked/Makefile
index 053781578..50c6c8a1d 100755
--- a/nuttx/configs/ea3131/locked/Makefile
+++ b/nuttx/configs/ea3131/locked/Makefile
@@ -77,7 +77,7 @@ PASS1_LIBGCC = "${shell $(CC) -print-libgcc-file-name}"
# Targets:
-all: locked.r
+all: $(PASS1_SRCDIR)/locked.r
.PHONY: depend clean distclean
diff --git a/nuttx/configs/ea3131/pgnsh/defconfig b/nuttx/configs/ea3131/pgnsh/defconfig
index 859b606be..aa18038b9 100755
--- a/nuttx/configs/ea3131/pgnsh/defconfig
+++ b/nuttx/configs/ea3131/pgnsh/defconfig
@@ -203,6 +203,7 @@ CONFIG_HAVE_LIBM=n
#
CONFIG_BUILD_2PASS=y
CONFIG_PASS1_BUILDIR=configs/ea3131/locked
+CONFIG_PASS1_TARGET=all
CONFIG_PASS1_OBJECT=locked.r
#
diff --git a/nuttx/configs/ne64badge/ostest/defconfig b/nuttx/configs/ne64badge/ostest/defconfig
index 47ce5e58b..61f09986d 100755
--- a/nuttx/configs/ne64badge/ostest/defconfig
+++ b/nuttx/configs/ne64badge/ostest/defconfig
@@ -200,7 +200,8 @@ CONFIG_HAVE_LIBM=n
#
CONFIG_BUILD_2PASS=n
CONFIG_PASS1_BUILDIR=configs/ne64badge/initrel
-CONFIG_PASS1_OBJECT=init.r
+CONFIG_PASS1_TARGET=init.r
+CONFIG_PASS1_OBJECT=
#
# General OS setup
diff --git a/nuttx/configs/sam3u-ek/README.txt b/nuttx/configs/sam3u-ek/README.txt
index e077cbfbc..2a10ddc70 100755
--- a/nuttx/configs/sam3u-ek/README.txt
+++ b/nuttx/configs/sam3u-ek/README.txt
@@ -306,12 +306,25 @@ can be selected as follow:
cd -
. ./setenv.sh
-Where <subdir> is one of the following:
+Before sourcing the setenv.sh file above, you should examine it and perform
+edits as necessary so that BUILDROOT_BIN is the correct path to the directory
+than holds your toolchain binaries.
+
+And then build NuttX by simply typing the following. At the conclusion of
+the make, the nuttx binary will reside in an ELF file called, simply, nuttx.
+
+ make
+
+The <subdir> that is provided above as an argument to the tools/configure.sh
+must be is one of the following:
knsh:
This is identical to the nsh configuration below except that NuttX
is built as a kernel-mode, monolithic module and the user applications
- are built separately.
+ are built separately. This build requires a special make command; not
+ just 'make' but make with the following two arguments:
+
+ make pass1 pass2
nsh:
Configures the NuttShell (nsh) located at examples/nsh. The
diff --git a/nuttx/configs/sam3u-ek/kernel/Makefile b/nuttx/configs/sam3u-ek/kernel/Makefile
index dd3e1892c..0bffda7c0 100755
--- a/nuttx/configs/sam3u-ek/kernel/Makefile
+++ b/nuttx/configs/sam3u-ek/kernel/Makefile
@@ -67,6 +67,8 @@ all: $(TOPDIR)/nuttx_user.elf $(TOPDIR)/User.map $(BOARD_INCLUDE)/user_map.h
nuttx_user.elf:
@echo "LD: nuttx_user.elf"
+ echo "USER_LDLIBS: $(USER_LDLIBS)"
+ echo "USER_LIBPATHS: $(USER_LIBPATHS)"
@$(LD) -o $@ $(USER_LDFLAGS) $(USER_LIBPATHS) --start-group $(USER_LDLIBS) --end-group $(USER_LIBGCC)
$(TOPDIR)/nuttx_user.elf: nuttx_user.elf
diff --git a/nuttx/configs/sam3u-ek/kernel/kernel.ld b/nuttx/configs/sam3u-ek/kernel/kernel.ld
index 88ec56000..72f79d9d7 100644
--- a/nuttx/configs/sam3u-ek/kernel/kernel.ld
+++ b/nuttx/configs/sam3u-ek/kernel/kernel.ld
@@ -64,6 +64,7 @@ MEMORY
OUTPUT_ARCH(arm)
ENTRY(user_start)
+EXTERN(user_start)
SECTIONS
{
.text : {
diff --git a/nuttx/configs/sam3u-ek/knsh/Make.defs b/nuttx/configs/sam3u-ek/knsh/Make.defs
index d735f887a..83e766d77 100755
--- a/nuttx/configs/sam3u-ek/knsh/Make.defs
+++ b/nuttx/configs/sam3u-ek/knsh/Make.defs
@@ -117,7 +117,7 @@ LDNXFLATFLAGS = -e main -s 2048
OBJEXT = .o
LIBEXT = .a
-EXEEXT = .elf
+EXEEXT =
ifneq ($(CROSSDEV),arm-elf-)
LDFLAGS += -nostartfiles -nodefaultlibs
diff --git a/nuttx/configs/sam3u-ek/knsh/defconfig b/nuttx/configs/sam3u-ek/knsh/defconfig
index b59ac08bf..b6aa4aba2 100755
--- a/nuttx/configs/sam3u-ek/knsh/defconfig
+++ b/nuttx/configs/sam3u-ek/knsh/defconfig
@@ -212,6 +212,7 @@ CONFIG_HAVE_LIBM=n
#
CONFIG_BUILD_2PASS=y
CONFIG_PASS1_BUILDIR=configs/sam3u-ek/kernel
+CONFIG_PASS1_TARGET=all
CONFIG_PASS1_OBJECT=
#
diff --git a/nuttx/configs/vsn/include/nsh_romfsimg.h b/nuttx/configs/vsn/include/nsh_romfsimg.h
index 2ac240ec8..7fa7c28ee 100755
--- a/nuttx/configs/vsn/include/nsh_romfsimg.h
+++ b/nuttx/configs/vsn/include/nsh_romfsimg.h
@@ -1,6 +1,6 @@
unsigned char romfs_img[] = {
- 0x2d, 0x72, 0x6f, 0x6d, 0x31, 0x66, 0x73, 0x2d, 0x00, 0x00, 0x02, 0x10,
- 0x85, 0xc5, 0xa3, 0x6a, 0x4e, 0x53, 0x48, 0x49, 0x6e, 0x69, 0x74, 0x56,
+ 0x2d, 0x72, 0x6f, 0x6d, 0x31, 0x66, 0x73, 0x2d, 0x00, 0x00, 0x02, 0x00,
+ 0x95, 0x7e, 0x5e, 0x1a, 0x4e, 0x53, 0x48, 0x49, 0x6e, 0x69, 0x74, 0x56,
0x6f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xff, 0xff, 0x97,
0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -15,12 +15,12 @@ unsigned char romfs_img[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x60,
0x00, 0x00, 0x00, 0x00, 0xd1, 0xff, 0xfe, 0xe0, 0x2e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30,
- 0x8d, 0x9c, 0xab, 0xc6, 0x72, 0x63, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1c,
+ 0x8d, 0x9c, 0xab, 0xda, 0x72, 0x63, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x63, 0x68, 0x6f,
- 0x20, 0x22, 0x56, 0x53, 0x4e, 0x20, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x20,
- 0x31, 0x2e, 0x32, 0x2c, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x6e, 0x65, 0x74,
- 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x22, 0x0a,
+ 0x20, 0x22, 0x56, 0x53, 0x4e, 0x20, 0x4e, 0x75, 0x74, 0x74, 0x58, 0x20,
+ 0x36, 0x2e, 0x31, 0x2c, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x6e, 0x65, 0x74,
+ 0x43, 0x6c, 0x61, 0x6d, 0x70, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x22, 0x0a,
0x0a, 0x23, 0x20, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20,
0x52, 0x41, 0x4d, 0x44, 0x49, 0x53, 0x4b, 0x20, 0x61, 0x6e, 0x64, 0x20,
0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x69, 0x74, 0x20, 0x61, 0x74, 0x20,
@@ -30,19 +30,19 @@ unsigned char romfs_img[] = {
0x64, 0x65, 0x76, 0x2f, 0x72, 0x61, 0x6d, 0x31, 0x0a, 0x23, 0x6d, 0x6f,
0x75, 0x6e, 0x74, 0x20, 0x2d, 0x74, 0x20, 0x76, 0x66, 0x61, 0x74, 0x20,
0x2f, 0x64, 0x65, 0x76, 0x2f, 0x72, 0x61, 0x6d, 0x31, 0x20, 0x2f, 0x74,
- 0x6d, 0x70, 0x0a, 0x0a, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x22, 0x4d, 0x6f,
- 0x75, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x46, 0x52, 0x41, 0x4d, 0x20,
- 0x74, 0x6f, 0x20, 0x2f, 0x75, 0x73, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20,
- 0x53, 0x44, 0x63, 0x61, 0x72, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x2f, 0x73,
- 0x64, 0x63, 0x61, 0x72, 0x64, 0x22, 0x0a, 0x0a, 0x72, 0x61, 0x6d, 0x74,
- 0x72, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x33, 0x0a,
- 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x2d, 0x74, 0x20, 0x76, 0x66, 0x61,
- 0x74, 0x20, 0x2f, 0x64, 0x65, 0x76, 0x2f, 0x6d, 0x74, 0x64, 0x62, 0x6c,
- 0x6f, 0x63, 0x6b, 0x30, 0x20, 0x2f, 0x75, 0x73, 0x72, 0x0a, 0x0a, 0x73,
- 0x64, 0x63, 0x61, 0x72, 0x64, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20,
- 0x30, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x2d, 0x74, 0x20, 0x76,
- 0x66, 0x61, 0x74, 0x20, 0x2f, 0x64, 0x65, 0x76, 0x2f, 0x6d, 0x6d, 0x63,
- 0x73, 0x64, 0x30, 0x20, 0x2f, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x0a,
+ 0x6d, 0x70, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x2d, 0x74,
+ 0x20, 0x62, 0x69, 0x6e, 0x66, 0x73, 0x20, 0x2f, 0x64, 0x65, 0x76, 0x2f,
+ 0x72, 0x61, 0x6d, 0x30, 0x20, 0x2f, 0x73, 0x62, 0x69, 0x6e, 0x0a, 0x0a,
+ 0x72, 0x61, 0x6d, 0x74, 0x72, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x61, 0x72,
+ 0x74, 0x20, 0x33, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x2d, 0x74,
+ 0x20, 0x76, 0x66, 0x61, 0x74, 0x20, 0x2f, 0x64, 0x65, 0x76, 0x2f, 0x6d,
+ 0x74, 0x64, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x30, 0x20, 0x2f, 0x75, 0x73,
+ 0x72, 0x0a, 0x0a, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x20, 0x73, 0x74,
+ 0x61, 0x72, 0x74, 0x20, 0x30, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20,
+ 0x2d, 0x74, 0x20, 0x76, 0x66, 0x61, 0x74, 0x20, 0x2f, 0x64, 0x65, 0x76,
+ 0x2f, 0x6d, 0x6d, 0x63, 0x73, 0x64, 0x30, 0x20, 0x2f, 0x73, 0x64, 0x63,
+ 0x61, 0x72, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
diff --git a/nuttx/configs/vsn/include/rcS.template b/nuttx/configs/vsn/include/rcS.template
index 32f0df4e1..c7cd93cd4 100755
--- a/nuttx/configs/vsn/include/rcS.template
+++ b/nuttx/configs/vsn/include/rcS.template
@@ -1,11 +1,11 @@
-echo "VSN Board 1.2, www.netclamps.com"
+echo "VSN NuttX 6.1, www.netClamps.com"
# Create a RAMDISK and mount it at XXXRDMOUNTPOUNTXXX
#mkrd -m XXXMKRDMINORXXX -s XXMKRDSECTORSIZEXXX XXMKRDBLOCKSXXX
#mkfatfs /dev/ramXXXMKRDMINORXXX
#mount -t vfat /dev/ramXXXMKRDMINORXXX XXXRDMOUNTPOUNTXXX
-echo "Mounting FRAM to /usr and SDcard to /sdcard"
+mount -t binfs /dev/ram0 /sbin
ramtron start 3
mount -t vfat /dev/mtdblock0 /usr
diff --git a/nuttx/configs/vsn/nsh/defconfig b/nuttx/configs/vsn/nsh/defconfig
index 1d2bbe0c9..b51342cb5 100755
--- a/nuttx/configs/vsn/nsh/defconfig
+++ b/nuttx/configs/vsn/nsh/defconfig
@@ -145,7 +145,7 @@ CONFIG_STM32_FSMC=n
CONFIG_STM32_SDIO=y
# APB1:
CONFIG_STM32_TIM2=n
-CONFIG_STM32_TIM3=n
+CONFIG_STM32_TIM3=y
CONFIG_STM32_TIM4=n
CONFIG_STM32_TIM5=n
CONFIG_STM32_TIM6=n
@@ -157,8 +157,8 @@ CONFIG_STM32_USART2=n
CONFIG_STM32_USART3=n
CONFIG_STM32_UART4=n
CONFIG_STM32_UART5=n
-CONFIG_STM32_I2C1=n
-CONFIG_STM32_I2C2=n
+CONFIG_STM32_I2C1=y
+CONFIG_STM32_I2C2=y
CONFIG_STM32_USB=n
CONFIG_STM32_CAN=n
CONFIG_STM32_BKP=n
@@ -169,7 +169,7 @@ CONFIG_STM32_ADC1=n
CONFIG_STM32_ADC2=n
CONFIG_STM32_TIM1=n
CONFIG_STM32_SPI1=n
-CONFIG_STM32_TIM8=n
+CONFIG_STM32_TIM8=y
CONFIG_STM32_USART1=y
CONFIG_STM32_ADC3=n
@@ -249,6 +249,11 @@ CONFIG_SSI_POLLWAIT=y
#CONFIG_SSI_TXLIMIT=4
#
+# OS support for I2C
+#
+CONFIG_I2C=y
+
+#
# General build options
#
# CONFIG_RRLOAD_BINARY - make the rrload binary format used with
diff --git a/nuttx/configs/vsn/src/sif.c b/nuttx/configs/vsn/src/sif.c
index c1813df83..a10072ac5 100644
--- a/nuttx/configs/vsn/src/sif.c
+++ b/nuttx/configs/vsn/src/sif.c
@@ -70,7 +70,7 @@
#include <nuttx/config.h>
#include <nuttx/fs.h>
-#include <nuttx/i2c.h>
+#include <nuttx/i2c/i2c.h>
#include <semaphore.h>
#include <stdio.h>
@@ -80,6 +80,7 @@
#include <errno.h>
#include "vsn.h"
+#include <nuttx/i2c/st_lis331dl.h>
/****************************************************************************
@@ -272,23 +273,6 @@ int sif_gpios_unlock(vsn_sif_state_t peripheral)
}
-/****************************************************************************
- * ST LIS331DL
- ****************************************************************************/
-
-void st_lis331dl_open(void)
-{
-}
-
-
-void st_lis331dl_config(void)
-{
-}
-
-
-void st_lis331dl_getreadings(void)
-{
-}
/****************************************************************************
@@ -518,7 +502,32 @@ int sif_main(int argc, char *argv[])
STM32_TIM_SETCOMPARE(vsn_sif.tim8, GPIO_OUT_PWRPWM_TIM8_CH, val);
return 0;
}
- else if (!strcmp(argv[1], "c")) {
+ else if (!strcmp(argv[1], "i2c") && argc == 3) {
+ int val = atoi(argv[2]);
+ struct st_lis331dl_dev_s * lis = st_lis331dl_init(vsn_sif.i2c1, val);
+
+ if (lis) {
+ struct st_lis331dl_vector_s * a;
+ int i;
+
+ /* Sample some values */
+
+ for (i=0; i<20; i++) {
+ if ( (a = st_lis331dl_getreadings(lis)) )
+ printf("%d %d %d\n", a->x, a->y, a->z);
+ else {
+ printf("Readings errno %d\n", errno);
+ break;
+ }
+ fflush(stdout);
+ usleep(100000);
+ }
+
+ st_lis331dl_deinit(lis);
+ }
+ else printf("Exit point: errno=%d\n", errno);
+
+ return 0;
}
}
diff --git a/nuttx/drivers/Makefile b/nuttx/drivers/Makefile
index 7c46280c5..01143a071 100644
--- a/nuttx/drivers/Makefile
+++ b/nuttx/drivers/Makefile
@@ -94,6 +94,13 @@ include mtd/Make.defs
ROOTDEPPATH = --dep-path .
MTDDEPPATH = --dep-path mtd
+ifeq ($(CONFIG_I2C),y)
+include i2c/Make.defs
+ROOTDEPPATH = --dep-path .
+I2CDEPPATH = --dep-path i2c
+CFLAGS += ${shell $(TOPDIR)/tools/incdir.sh $(INCDIROPT) "$(CC)" $(TOPDIR)/drivers/i2c}
+endif
+
ASRCS = $(SERIAL_ASRCS) $(NET_ASRCS) $(PIPE_ASRCS) $(USBDEV_ASRCS) \
$(USBHOST_ASRCS) $(MMCSD_ASRCS) $(LCD_ASRCS) $(BCH_ASRCS) \
$(MTD_ASRCS)
diff --git a/nuttx/drivers/i2c/Make.defs b/nuttx/drivers/i2c/Make.defs
new file mode 100644
index 000000000..2358d533b
--- /dev/null
+++ b/nuttx/drivers/i2c/Make.defs
@@ -0,0 +1,42 @@
+############################################################################
+# drivers/i2c/Make.defs
+#
+# Copyright (C) 2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+I2C_ASRCS =
+I2C_CSRCS =
+
+ifeq ($(CONFIG_I2C),y)
+I2C_CSRCS += st_lis331dl.c
+endif
+
diff --git a/nuttx/drivers/i2c/st_lis331dl.c b/nuttx/drivers/i2c/st_lis331dl.c
new file mode 100644
index 000000000..cb1d7f47d
--- /dev/null
+++ b/nuttx/drivers/i2c/st_lis331dl.c
@@ -0,0 +1,270 @@
+/****************************************************************************
+ * drivers/i2c/st_lis331dl.c
+ *
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ *
+ * Authors: Uros Platise <uros.platise@isotel.eu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/** \file
+ * \author Uros Platise
+ * \brief ST LIS331DL I2C Device Driver
+ **/
+
+#include <nuttx/config.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include <nuttx/i2c/st_lis331dl.h>
+
+/************************************************************************************
+ * Private Data Types
+ ************************************************************************************/
+
+struct st_lis331dl_dev_s {
+ struct i2c_dev_s * i2c;
+
+ uint8_t address;
+ struct st_lis331dl_vector_s a;
+ uint8_t cr1;
+ uint8_t cr2;
+ uint8_t cr3;
+};
+
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/** LIS331DL Access with range check
+ *
+ * \param dev LIS331 DL Private Structure
+ * \param subaddr LIS331 Sub Address
+ * \param buf Pointer to buffer, either for read or write access
+ * \param length when >0 it denotes read access, when <0 it denotes write access of -length
+ * \return OK on success or errno is set.
+ **/
+int st_lis331dl_access(struct st_lis331dl_dev_s * dev, uint8_t subaddr, uint8_t *buf, int length)
+{
+ uint16_t flags = 0;
+ int retval;
+
+ if (length > 0) {
+ flags = I2C_M_READ;
+ }
+ else {
+ flags = I2C_M_NORESTART;
+ length = -length;
+ }
+
+ /* Check valid address ranges and set auto address increment flag */
+
+ if (subaddr == 0x0F) {
+ if (length > 1) length = 1;
+ }
+ else if (subaddr >= 0x20 && subaddr < 0x24) {
+ if (length > (0x24 - subaddr) ) length = 0x24 - subaddr;
+ }
+ else if (subaddr >= 0x27 && subaddr < 0x2E) {
+ if (length > (0x2E - subaddr) ) length = 0x2E - subaddr;
+ }
+ else if (subaddr >= 0x30 && subaddr < 0x40) {
+ if (length > (0x40 - subaddr) ) length = 0x40 - subaddr;
+ }
+ else {
+ errno = EFAULT;
+ return ERROR;
+ }
+
+ subaddr |= 0x80;
+
+ /* Create message and send */
+
+ struct i2c_msg_s msgv[2] = {
+ {
+ .addr = dev->address,
+ .flags = 0,
+ .buffer = &subaddr,
+ .length = 1
+ },
+ {
+ .addr = dev->address,
+ .flags = flags,
+ .buffer = buf,
+ .length = length
+ }
+ };
+
+ if ( (retval = I2C_TRANSFER(dev->i2c, msgv, 2)) == OK )
+ return length;
+
+ return retval;
+}
+
+
+int st_lis331dl_readregs(struct st_lis331dl_dev_s * dev)
+{
+ if (st_lis331dl_access(dev, ST_LIS331DL_CTRL_REG1, &dev->cr1, 3) == ERROR) return ERROR;
+
+ printf("CR1=%2x, CR2=%2x, CR3=%2x\n", dev->cr1, dev->cr2, dev->cr3 );
+ return OK;
+}
+
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+struct st_lis331dl_dev_s * st_lis331dl_init(struct i2c_dev_s * i2c, uint16_t address)
+{
+ struct st_lis331dl_dev_s * dev;
+ uint8_t retval;
+
+ ASSERT(i2c);
+ ASSERT(address);
+
+ if ( (dev = malloc( sizeof(struct st_lis331dl_dev_s) )) == NULL )
+ return NULL;
+
+ memset(dev, 0, sizeof(struct st_lis331dl_dev_s));
+ dev->i2c = i2c;
+ dev->address = address;
+
+ /* Probe device */
+
+ if (st_lis331dl_access(dev, ST_LIS331DL_WHOAMI, &retval, 1) > 0) {
+
+ /* Check chip identification, in the future several more compatible parts
+ * may be added here.
+ */
+
+ if (retval == ST_LIS331DL_WHOAMI_VALUE) {
+
+ /* Copy LIS331DL registers to our private structure and power-up device */
+
+ if ( st_lis331dl_readregs(dev)==OK && st_lis331dl_powerup(dev)==OK) {
+
+ /* Normal exit point */
+ errno = 0;
+ return dev;
+ }
+ retval = errno;
+ }
+
+ /* Otherwise, we mark an invalid device found at given address */
+ retval = ENODEV;
+ }
+ else {
+ /* No response at given address is marked as */
+ retval = EFAULT;
+ }
+
+ /* Error exit */
+ free(dev);
+ errno = retval;
+ return NULL;
+}
+
+
+int st_lis331dl_deinit(struct st_lis331dl_dev_s * dev)
+{
+ ASSERT(dev);
+
+// st_lis331dl_powerdown(dev);
+ free(dev);
+
+ return OK;
+}
+
+
+int st_lis331dl_powerup(struct st_lis331dl_dev_s * dev)
+{
+ dev->cr1 = ST_LIS331DL_CR1_PD |
+ ST_LIS331DL_CR1_ZEN | ST_LIS331DL_CR1_YEN | ST_LIS331DL_CR1_XEN;
+
+ st_lis331dl_access(dev, ST_LIS331DL_CTRL_REG1, &dev->cr1, -1);
+ return OK;
+}
+
+
+int st_lis331dl_powerdown(struct st_lis331dl_dev_s * dev)
+{
+ dev->cr1 = ST_LIS331DL_CR1_ZEN | ST_LIS331DL_CR1_YEN | ST_LIS331DL_CR1_XEN;
+
+ return st_lis331dl_access(dev, ST_LIS331DL_CTRL_REG1, &dev->cr1, -1);
+}
+
+
+int st_lis331dl_setconversion(struct st_lis331dl_dev_s * dev, bool full, bool fast)
+{
+ dev->cr1 = ST_LIS331DL_CR1_PD |
+ (full ? ST_LIS331DL_CR1_FS : 0) | (fast ? ST_LIS331DL_CR1_DR : 0) |
+ ST_LIS331DL_CR1_ZEN | ST_LIS331DL_CR1_YEN | ST_LIS331DL_CR1_XEN;
+
+ st_lis331dl_access(dev, ST_LIS331DL_CTRL_REG1, &dev->cr1, -1);
+ return OK;
+}
+
+
+float st_lis331dl_getprecision(struct st_lis331dl_dev_s * dev)
+{
+ if (dev->cr1 & ST_LIS331DL_CR1_FS)
+ return 9.0/127.0; /* ~9g full scale */
+ return 2.0/127.0; /* ~2g full scale */
+}
+
+
+int st_lis331dl_getsamplerate(struct st_lis331dl_dev_s * dev)
+{
+ if (dev->cr1 & ST_LIS331DL_CR1_DR)
+ return 400;
+ return 100;
+}
+
+
+const struct st_lis331dl_vector_s * st_lis331dl_getreadings(struct st_lis331dl_dev_s * dev)
+{
+ uint8_t retval[5];
+
+ ASSERT(dev);
+
+ if (st_lis331dl_access(dev, ST_LIS331DL_OUT_X, retval, 5) == 5) {
+ dev->a.x = retval[0];
+ dev->a.y = retval[2];
+ dev->a.z = retval[4];
+ return &dev->a;
+ }
+
+ return NULL;
+}
diff --git a/nuttx/include/nuttx/i2c.h b/nuttx/include/nuttx/i2c/i2c.h
index 379105fc6..571c3c401 100644
--- a/nuttx/include/nuttx/i2c.h
+++ b/nuttx/include/nuttx/i2c/i2c.h
@@ -1,5 +1,5 @@
/****************************************************************************
- * include/nuttx/i2c.h
+ * include/nuttx/i2c/i2c.h
*
* Copyright(C) 2009-2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
@@ -33,8 +33,8 @@
*
****************************************************************************/
-#ifndef __NUTTX_I2C_H
-#define __NUTTX_I2C_H
+#ifndef __INCLUDE_NUTTX_I2C_I2C_H
+#define __INCLUDE_NUTTX_I2C_I2C_H
/****************************************************************************
* Included Files
@@ -75,6 +75,7 @@
#define I2C_M_READ 0x0001 /* read data, from slave to master */
#define I2C_M_TEN 0x0002 /* ten bit address */
+#define I2C_M_NORESTART 0x0080 /* message should not begin with (re-)start of transfer */
/* Access macros */
@@ -184,6 +185,28 @@
#define I2C_READ(d,b,l) ((d)->ops->read(d,b,l))
/****************************************************************************
+ * Name: I2C_WRITEREAD
+ *
+ * Description:
+ * Send a block of data on I2C using the previously selected I2C
+ * frequency and slave address, followed by restarted read access.
+ * It provides a convenient wrapper to the transfer function.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * wbuffer - A pointer to the read-only buffer of data to be written to device
+ * wbuflen - The number of bytes to send from the buffer
+ * rbuffer - A pointer to a buffer of data to receive the data from the device
+ * rbuflen - The requested number of bytes to be read
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+#define I2C_WRITEREAD(d,wb,wl,rb,rl) ((d)->ops->writeread(d,wb,wl,rb,rl))
+
+/****************************************************************************
* Name: I2C_TRANSFER
*
* Description:
@@ -307,4 +330,4 @@ EXTERN int up_i2cuninitialize(FAR struct i2c_dev_s * dev);
#if defined(__cplusplus)
}
#endif
-#endif /* __NUTTX_I2C_H */
+#endif /* __INCLUDE_NUTTX_I2C_I2C_H */
diff --git a/nuttx/include/nuttx/i2c/st_lis331dl.h b/nuttx/include/nuttx/i2c/st_lis331dl.h
new file mode 100644
index 000000000..f3f137391
--- /dev/null
+++ b/nuttx/include/nuttx/i2c/st_lis331dl.h
@@ -0,0 +1,170 @@
+/****************************************************************************
+ * include/nuttx/i2c/st_lis331dl.h
+ *
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ *
+ * Authors: Uros Platise <uros.platise@isotel.eu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/** \file
+ * \author Uros Platise
+ * \brief ST LIS331DL I2C Device Driver
+ **/
+
+#ifndef __INCLUDE_NUTTX_I2C_ST_LIS331DL_H
+#define __INCLUDE_NUTTX_I2C_ST_LIS331DL_H
+
+#include <nuttx/i2c/i2c.h>
+#include <stdbool.h>
+
+
+/************************************************************************************
+ * Pre-Processor Declarations
+ ************************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+/************************************************************************************
+ * LIS331DL Internal Registers
+ ************************************************************************************/
+
+#define ST_LIS331DL_WHOAMI 0x0F /* who am I register */
+#define ST_LIS331DL_WHOAMI_VALUE 0x3B /* Valid result is 0x3B */
+
+#define ST_LIS331DL_CTRL_REG1 0x20
+#define ST_LIS331DL_CR1_DR 0x80 /* Data-rate selection 0: 100 Hz, 1: 400 Hz */
+#define ST_LIS331DL_CR1_PD 0x40 /* Active Mode (1) / Power-down (0) */
+#define ST_LIS331DL_CR1_FS 0x20 /* Full Scale (1) +-9g or Normal Scale (0) +-2g */
+#define ST_LIS331DL_CR1_ST 0x18 /* Self test enable */
+#define ST_LIS331DL_CR1_ZEN 0x04 /* Z-Axis Enable */
+#define ST_LIS331DL_CR1_YEN 0x02 /* Y-Axis Enable */
+#define ST_LIS331DL_CR1_XEN 0x01 /* X-Axis Enable */
+
+#define ST_LIS331DL_CTRL_REG2 0x21
+#define ST_LIS331DL_CTRL_REG3 0x22
+
+#define ST_LIS331DL_HP_FILTER_RESET 0x23
+
+#define ST_LIS331DL_STATUS_REG 0x27
+
+#define ST_LIS331DL_OUT_X 0x29
+#define ST_LIS331DL_OUT_Y 0x2B
+#define ST_LIS331DL_OUT_Z 0x2D
+
+
+/************************************************************************************
+ * Public Data Types
+ ************************************************************************************/
+
+struct st_lis331dl_dev_s;
+
+struct st_lis331dl_vector_s {
+ int8_t x, y, z;
+};
+
+
+/************************************************************************************
+ * Public Function Prototypes
+ ************************************************************************************/
+
+/** Initialize ST LIS331DL Chip
+ *
+ * \param i2c I2C Device Structure
+ * \param address I2C Address of the proposed device
+ * \return Pointer to newly allocated ST LIS331DL structure or NULL on error with errno set.
+ *
+ * Possible errno as set by this function on error:
+ * - ENODEV: When device addressed on given address is not compatible or it is not a LIS331DL
+ * - EFAULT: When there is no device at given address.
+ * - EBUSY: When device is already addressed by other device driver (not yet supported by low-level driver)
+ **/
+EXTERN struct st_lis331dl_dev_s * st_lis331dl_init(struct i2c_dev_s * i2c, uint16_t address);
+
+/** Deinitialize ST LIS331DL Chip
+ *
+ * \param dev Device to LIS331DL device structure, as returned by the st_lis331dl_init()
+ * \return OK On success
+ *
+ **/
+EXTERN int st_lis331dl_deinit(struct st_lis331dl_dev_s * dev);
+
+/** Power up device, start conversion */
+EXTERN int st_lis331dl_powerup(struct st_lis331dl_dev_s * dev);
+
+/** Power down device, stop conversion */
+EXTERN int st_lis331dl_powerdown(struct st_lis331dl_dev_s * dev);
+
+/** Configure conversion
+ *
+ * \param dev Device to LIS331DL device structure
+ * \param full When set, range of [-9g, 9g] is selected, otherwise [-2g, +2g]
+ * \param fast When set, conversion operates at 400 Hz, otherwise at 100 Hz
+ * \return OK on success or errno is set
+ **/
+EXTERN int st_lis331dl_setconversion(struct st_lis331dl_dev_s * dev, bool full, bool fast);
+
+/** Get precision
+ *
+ * \return Precision of 1 LSB in terms of unit [g]
+ **/
+EXTERN float st_lis331dl_getprecision(struct st_lis331dl_dev_s * dev);
+
+/** Get sample rate
+ *
+ * \return Sample rate in unit of [Hz]
+ **/
+EXTERN int st_lis331dl_getsamplerate(struct st_lis331dl_dev_s * dev);
+
+/** Get readings, updates internal data structure
+ *
+ * \param dev Device to LIS331DL device structure
+ * \return Ptr to vector acceleration [x,y,z] on success, or NULL on error with errno set
+ */
+EXTERN const struct st_lis331dl_vector_s * st_lis331dl_getreadings(struct st_lis331dl_dev_s * dev);
+
+
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __INCLUDE_NUTTX_I2C_ST_LIS331DL_H */
+