9
0
Fork 0

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:
patacongo 2011-04-03 14:26:05 +00:00
parent 3466504a79
commit cd2f66d531
37 changed files with 1034 additions and 221 deletions

View File

@ -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

View File

@ -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" );

View File

@ -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++;
}
}

View File

@ -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);
}
}

View File

@ -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 */

View File

@ -152,7 +152,7 @@ static inline void cgi_semtake(void)
* awakened by a signal.
*/
ASSERT(*get_errno_ptr() == EINTR);
ASSERT(errno == EINTR);
}
}

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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>

View File

@ -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)

View File

@ -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/)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -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>

View File

@ -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 */

View File

@ -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;
}

View File

@ -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"

View File

@ -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>

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
#

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -64,6 +64,7 @@ MEMORY
OUTPUT_ARCH(arm)
ENTRY(user_start)
EXTERN(user_start)
SECTIONS
{
.text : {

View File

@ -117,7 +117,7 @@ LDNXFLATFLAGS = -e main -s 2048
OBJEXT = .o
LIBEXT = .a
EXEEXT = .elf
EXEEXT =
ifneq ($(CROSSDEV),arm-elf-)
LDFLAGS += -nostartfiles -nodefaultlibs

View File

@ -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=
#

View File

@ -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,

View File

@ -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

View File

@ -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
#

View File

@ -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;
}
}

View File

@ -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)

View File

@ -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

View File

@ -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;
}

View File

@ -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 */

View File

@ -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 */