New LIS331DL driver and VSN updates from Uros
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@3457 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
parent
3466504a79
commit
cd2f66d531
|
@ -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
|
||||
|
|
|
@ -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" );
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -152,7 +152,7 @@ static inline void cgi_semtake(void)
|
|||
* awakened by a signal.
|
||||
*/
|
||||
|
||||
ASSERT(*get_errno_ptr() == EINTR);
|
||||
ASSERT(errno == EINTR);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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 <spudmonkey@racsa.co.cr>
|
|||
* 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 <spudmonkey@racsa.co.cr>
|
||||
|
||||
* 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 <spudmonkey@racsa.co.cr>
|
||||
|
||||
|
|
|
@ -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/<architecture>/src</code> directory.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>General OS setup</h2>
|
||||
|
|
|
@ -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)
|
||||
|
|
12
nuttx/TODO
12
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/)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
static int stm32_i2c1_isr(int irq, void *context)
|
||||
{
|
||||
return stm32_i2c_event_isr(&stm32_i2c1_priv);
|
||||
}
|
||||
|
||||
static int stm32_i2c1_error_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)
|
||||
static int stm32_i2c2_isr(int irq, void *context)
|
||||
{
|
||||
return stm32_i2c_event_isr(&stm32_i2c2_priv);
|
||||
}
|
||||
|
||||
static int stm32_i2c2_error_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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -64,6 +64,7 @@ MEMORY
|
|||
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(user_start)
|
||||
EXTERN(user_start)
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
|
|
|
@ -117,7 +117,7 @@ LDNXFLATFLAGS = -e main -s 2048
|
|||
|
||||
OBJEXT = .o
|
||||
LIBEXT = .a
|
||||
EXEEXT = .elf
|
||||
EXEEXT =
|
||||
|
||||
ifneq ($(CROSSDEV),arm-elf-)
|
||||
LDFLAGS += -nostartfiles -nodefaultlibs
|
||||
|
|
|
@ -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=
|
||||
|
||||
#
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -248,6 +248,11 @@ CONFIG_SSI1_DISABLE=y
|
|||
CONFIG_SSI_POLLWAIT=y
|
||||
#CONFIG_SSI_TXLIMIT=4
|
||||
|
||||
#
|
||||
# OS support for I2C
|
||||
#
|
||||
CONFIG_I2C=y
|
||||
|
||||
#
|
||||
# General build options
|
||||
#
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
||||
|
||||
|
@ -183,6 +184,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
|
||||
*
|
||||
|
@ -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 */
|
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue