Commit from zer0 on branch b_zer0 (2007-06-24 19:30 CEST)
---------------------------------
SCHEDULER_UNIT was not correct when using timer0 without timer module.
aversive modules/base/scheduler/scheduler.h 1.8.4.6
aversive modules/base/scheduler/scheduler_private.h 1.1.2.6
-------------------------------------------
aversive/modules/base/scheduler/scheduler.h (1.8.4.5 -> 1.8.4.6)
-------------------------------------------
***************
*** 15,21 ****
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
! * Revision : $Id: scheduler.h,v 1.8.4.5 2007-06-17 19:34:57 zer0 Exp $
*
*/
--- 15,21 ----
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
! * Revision : $Id: scheduler.h,v 1.8.4.6 2007-06-24 17:30:13 zer0 Exp $
*
*/
***************
*** 47,55 ****
--- 47,57 ----
#define _SCHEDULER_H_
#include <aversive.h>
+
#ifdef CONFIG_MODULE_SCHEDULER_USE_TIMERS
#include <timer.h>
#endif /* CONFIG_MODULE_SCHEDULER_USE_TIMERS */
+
#include <scheduler_config.h>
#ifdef CONFIG_MODULE_SCHEDULER_USE_TIMERS
***************
*** 92,97 ****
--- 94,101 ----
#else
#error "Bad SCHEDULER_TIMER_NUM value in config file"
#endif
+ #else /* CONFIG_MODULE_SCHEDULER_USE_TIMERS */
+ #define SCHEDULER_TIMER_BITS 8
#endif /* CONFIG_MODULE_SCHEDULER_USE_TIMERS */
/** TIME_UNIT is the number of microseconds between each interruption
---------------------------------------------------
aversive/modules/base/scheduler/scheduler_private.h (1.1.2.5 -> 1.1.2.6)
---------------------------------------------------
***************
*** 15,21 ****
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
! * Revision : $Id: scheduler_private.h,v 1.1.2.5 2007-06-14 16:29:51 zer0
Exp $
*
*/
--- 15,21 ----
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
! * Revision : $Id: scheduler_private.h,v 1.1.2.6 2007-06-24 17:30:13 zer0
Exp $
*
*/
***************
*** 30,43 ****
#warning "You should define SCHEDULER_NB_STACKING_MAX and SCHEDULER_CK"
#endif
- #ifdef CONFIG_MODULE_SCHEDULER_USE_TIMERS
- #if defined SCHEDULER_TIMER_REGISTER || defined SCHEDULER_CLOCK_PRESCALER
- #warning "SCHEDULER_TIMER_REGISTER or SCHEDULER_CLOCK_PRESCALER is already"
- #warning "defined in your scheduler config file, and you are using the"
- #warning "timer module."
- #endif
- #endif
-
#include <stdint.h>
#include <aversive/queue.h>
--- 30,35 ----
Commit from zer0 on branch b_zer0 (2007-06-24 19:31 CEST)
---------------------------------
fix incorrect path in include
aversive modules/devices/control_system/filters/ramp/ramp.c 1.5.4.4
-----------------------------------------------------------
aversive/modules/devices/control_system/filters/ramp/ramp.c (1.5.4.3 ->
1.5.4.4)
-----------------------------------------------------------
***************
*** 19,25 ****
*/
! #include <base/utils/aversive.h>
#include "ramp.h"
--- 19,25 ----
*/
! #include <aversive.h>
#include "ramp.h"
Commit from zer0 on branch b_zer0 (2007-06-24 21:55 CEST)
---------------------------------
Update i2c driver.
There are some debug garbage in files, but now it works !!
It still needs some enhancements.
+ aversive modules/comm/i2c/config/i2c_config.h 1.1.2.1
aversive modules/comm/i2c/i2c.h 1.1.2.4
aversive modules/comm/i2c/i2c.c 1.1.2.3
---------------------------------------------
aversive/modules/comm/i2c/config/i2c_config.h (1.1.2.1)
---------------------------------------------
***************
*** 0 ****
--- 1,30 ----
+ /*
+ * Copyright Droids Corporation, Microb Technology, Eirbot (2005)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Revision : $Id: i2c_config.h,v 1.1.2.1 2007-06-24 19:55:54 zer0 Exp $
+ *
+ */
+
+
+ #define I2C_BITRATE 1 // divider dor i2c baudrate, see TWBR in doc
+ #define I2C_PRESCALER 3 // prescaler config, rate = 2^(n*2)
+
+ /* Size of transmission buffer */
+ #define I2C_SEND_BUFFER_SIZE 16
+
+ /* Size of reception buffer */
+ #define I2C_RECV_BUFFER_SIZE 16
-------------------------------
aversive/modules/comm/i2c/i2c.h (1.1.2.3 -> 1.1.2.4)
-------------------------------
***************
*** 15,21 ****
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
! * Revision : $Id: i2c.h,v 1.1.2.3 2007-05-23 17:18:11 zer0 Exp $
*
*/
--- 15,21 ----
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
! * Revision : $Id: i2c.h,v 1.1.2.4 2007-06-24 19:55:54 zer0 Exp $
*
*/
***************
*** 70,81 ****
#endif
} i2c_mode_t ;
! /* I2C master mode status */
! typedef enum { I2C_STATUS_READY,
! I2C_STATUS_MASTER_XMIT,
! I2C_STATUS_MASTER_RECV,
! I2C_STATUS_SLAVE_XMIT_WAIT,
! I2C_STATUS_SLAVE_XMIT,
! I2C_STATUS_SLAVE_RECV,
! I2C_STATUS_OP_FINISHED,
! } i2c_status_t ;
--- 70,208 ----
#endif
} i2c_mode_t ;
!
! /* status flags */
! #define I2C_STATUS_READY 0x00
! #define I2C_STATUS_MASTER_XMIT 0x01
! #define I2C_STATUS_MASTER_RECV 0x02
! #define I2C_STATUS_SLAVE_XMIT_WAIT 0x04
! #define I2C_STATUS_SLAVE_XMIT 0x08
! #define I2C_STATUS_SLAVE_RECV 0x10
! #define I2C_STATUS_OP_FINISHED 0x20
!
! /**
! * mode is I2C_MODE_UNINIT, I2C_MODE_MASTER, I2C_MODE_MULTIMASTER or
! * I2C_MODE_SLAVE. Parameter add is the address in slave mode, it is
! * composed from:
! * b7 : true if the uC can be addressed with GENCALL
! * b0-6: slave address
! */
! void i2c_init(i2c_mode_t mode, uint8_t add);
!
!
! /**
! * Register a function that is called when a buffer is received. The
! * user application is always notified when data frame is received.
! * Arguments of the callback are:
! * - (recv_buf, n>0) if transmission succedded. The first parameter
! * contains the address of the reception buffer and
! * the second contains the number of received bytes.
! * - (NULL, err<0) if the transmission failed (slave not answering
! * or arbiteration lost). The first parameter is
! * NULL and the second contains the error code.
! */
! void i2c_register_recv_event(void (*event)(uint8_t *, int8_t));
!
! /**
! * Register a function that is called when a byte is received.
! * Arguments of the callback are: (hwstatus, numbyte, byte). The user
! * app can modify the g_size value, which is the number of bytes to be
! * received in the frame: this can be done by calling
! * i2c_set_recv_size().
! */
! void i2c_register_recv_byte_event(void (*event)(uint8_t, uint8_t, uint8_t));
!
!
! /**
! * register a function that is called when a buffer is sent (or an
! * error occured while sending) on the i2c bus. The event function is
! * always called by software if the i2c_send() function returned 0.
! * The parameter of the event function is the error code:
! * - 0 if the number of transmitted bytes is equal to the size
! * of the original send buffer, without NACK.
! * - <0 if 0 byte has been transmitted (slave not answering or
! * arbiteration lost)
! * - Else, the number of transmitted bytes is given, including the
! * one that was not acked.
! */
! void i2c_register_send_event(void (*event)(int8_t));
!
!
! /**
! * Send a buffer. Return 0 if xmit starts correctly.
! * On error, return != 0.
! * - If mode is slave, dest_add should be I2C_ADD_MASTER, and transmission
! * starts when the master transmits a clk.
! * - If mode is master and if dest_add != I2C_ADD_MASTER, it will transmit
! * a START condition if bus is available (the uc will act as a
! * master)
! * - If mode is master and if dest_add == I2C_ADD_MASTER, the uC will
! * act as a slave, and data will be sent when the uC will be
! * addressed.
! * The transmission will be processed with these params until a
! * i2c_flush() is called.
! */
! int8_t i2c_send(uint8_t dest_add, uint8_t *buf, uint8_t size);
!
! /**
! * Resend the same buffer. This call is equivalent to i2c_send() with
! * the same parameters as the last call.
! */
! int8_t i2c_resend(void);
!
!
! /**
! * Same than send, but error code is returned instead of beeing sent
! * as a callback. Note that the send_event callback is called anyway
! * if it is registered. This functions waits and only returns when the
! * transmission is finished or if it failed. Note that there is no
! * timeout, so it can loop forever...
! * WARNING : irq MUST be enabled !
! */
! int8_t i2c_send_sync(uint8_t dest_add, uint8_t *buf, uint8_t size);
!
! /**
! * In slave mode, it returns error and is useless. In master mode, if
! * dest_add is between 0 and 127, it will start to read the addressed
! * slave. The size of the buffer to read must be specified. Return 0
! * on success.
! */
! int8_t i2c_recv(uint8_t dest_add, uint8_t size);
!
!
! /**
! * Try to flush the current operation, before it is started. The
! * i2c module is then tagged as ready. If it returns 0, the flush was
! * a success, and i2c_send() can be called. Else, it means that
! * a transmission was running.
! */
! int8_t i2c_flush(void);
!
! /**
! * In MASTER RECEIVER mode, it is possible that the user application
! * does not know the size of the buffer. You can adjust this size
! * during transmission (generally the size can be specified at the
! * beginning of received data, so the user app can be notified thanks
! * to recv_byte_event(). Note that i2c_set_recv_size() function has to
! * be used with careful, making sure you understand i2c protocol and
! * this code. Return 0 on success. Note than in SLAVE RECEIVER mode,
! * you don't have to use this function, because the master can end the
! * transmission by sending a stop condition on the bus.
! */
! uint8_t i2c_set_recv_size(uint8_t size);
!
! /**
! * return the current mode of the i2c module.
! */
! i2c_mode_t i2c_mode(void);
!
! /**
! * return the status of the i2c module.
! */
! uint8_t i2c_status(void);
!
! /**
! * Copy the received buffer in the buffer given as parameter. Return
! * number of copied bytes or -1 on error.
! */
! uint8_t i2c_get_recv_buffer(uint8_t *buf, uint8_t size);
-------------------------------
aversive/modules/comm/i2c/i2c.c (1.1.2.2 -> 1.1.2.3)
-------------------------------
***************
*** 15,21 ****
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
! * Revision : $Id: i2c.c,v 1.1.2.2 2007-01-15 21:42:38 zer0 Exp $
*
*/
--- 15,21 ----
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
! * Revision : $Id: i2c.c,v 1.1.2.3 2007-06-24 19:55:54 zer0 Exp $
*
*/
***************
*** 26,32 ****
#include <util/twi.h>
#include <autoconf.h>
! #include <utils_errno.h>
#include <i2c.h>
--- 26,32 ----
#include <util/twi.h>
#include <autoconf.h>
! #include <aversive/errno.h>
#include <i2c.h>
***************
*** 38,43 ****
--- 38,93 ----
#error "I2C_RECV_BUFFER_SIZE must be at least 1"
#endif
+ /* to remove XXX */
+ #ifdef _AVR_IOM128_H_
+ #define LED1_ON() sbi(PORTE, 2)
+ #define LED1_OFF() cbi(PORTE, 2)
+
+ #define LED2_ON() sbi(PORTE, 3)
+ #define LED2_OFF() cbi(PORTE, 3)
+
+ #define LED3_ON() sbi(PORTB, 3)
+ #define LED3_OFF() cbi(PORTB, 3)
+
+ #define LED4_ON() sbi(PORTB, 4)
+ #define LED4_OFF() cbi(PORTB, 4)
+
+ #define LED5_ON() do {} while(0)
+ #define LED5_OFF() do {} while(0)
+
+ #define LED6_ON() do {} while(0)
+ #define LED6_OFF() do {} while(0)
+
+ #define LED7_ON() do {} while(0)
+ #define LED7_OFF() do {} while(0)
+ #else
+ /* to remove XXX */
+ #define LED5BIT 2
+ #define LED6BIT 3
+ #define LED7BIT 4
+
+ /* to remove XXX */
+ #define LED1_ON() do {} while(0)
+ #define LED1_OFF() do {} while(0)
+
+ #define LED2_ON() do {} while(0)
+ #define LED2_OFF() do {} while(0)
+
+ #define LED3_ON() do {} while(0)
+ #define LED3_OFF() do {} while(0)
+
+ #define LED4_ON() do {} while(0)
+ #define LED4_OFF() do {} while(0)
+
+ #define LED5_ON() sbi(PORTB, LED5BIT)
+ #define LED5_OFF() cbi(PORTB, LED5BIT)
+
+ #define LED6_ON() sbi(PORTB, LED6BIT)
+ #define LED6_OFF() cbi(PORTB, LED6BIT)
+
+ #define LED7_ON() sbi(PORTB, LED7BIT)
+ #define LED7_OFF() cbi(PORTB, LED7BIT)
+ #endif
/** recv event, called when we receive a frame
* params are : data buffer and size */
***************
*** 52,65 ****
static void (*g_send_event)(int8_t) = NULL;
static volatile i2c_mode_t g_mode = I2C_MODE_UNINIT;
! static volatile i2c_status_t g_status = I2C_STATUS_READY;
! static volatile uint8_t g_is_sync = 0; /* set to 1 during a synchronous op */
static volatile uint8_t g_sync_res = 0; /* result of sync send */
static uint8_t g_send_buf[I2C_SEND_BUFFER_SIZE];
static uint8_t g_recv_buf[I2C_RECV_BUFFER_SIZE];
static volatile uint8_t g_dest = 0; /* destination slave in master mode */
! static volatile uint8_t g_nbytes = 0; /* number of transmitted bytes */
! static volatile uint8_t g_size = 0; /* size of buffer to be transmitted */
--- 102,117 ----
static void (*g_send_event)(int8_t) = NULL;
static volatile i2c_mode_t g_mode = I2C_MODE_UNINIT;
! static volatile uint8_t g_status = I2C_STATUS_READY;
static volatile uint8_t g_sync_res = 0; /* result of sync send */
static uint8_t g_send_buf[I2C_SEND_BUFFER_SIZE];
static uint8_t g_recv_buf[I2C_RECV_BUFFER_SIZE];
static volatile uint8_t g_dest = 0; /* destination slave in master mode */
!
! static volatile uint8_t g_send_nbytes = 0; /* number of transmitted bytes */
! static volatile uint8_t g_send_size = 0; /* size of buffer to be transmitted
*/
! static volatile uint8_t g_recv_nbytes = 0; /* number of received bytes */
! static volatile uint8_t g_recv_size = 0; /* size of buffer to be received */
***************
*** 71,77 ****
* b0-6: slave address
*/
void
! i2cm_init(i2c_mode_t mode, uint8_t add)
{
uint8_t flags;
--- 123,129 ----
* b0-6: slave address
*/
void
! i2c_init(i2c_mode_t mode, uint8_t add)
{
uint8_t flags;
***************
*** 110,119 ****
sbi(TWAR, TWGCE);
/* init vars */
g_status = I2C_STATUS_READY;
g_dest = 0;
! g_nbytes = 0;
! g_size = 0;
IRQ_UNLOCK(flags);
}
--- 162,174 ----
sbi(TWAR, TWGCE);
/* init vars */
+ g_mode = mode;
g_status = I2C_STATUS_READY;
g_dest = 0;
! g_recv_nbytes = 0;
! g_recv_size = 0;
! g_send_nbytes = 0;
! g_send_size = 0;
IRQ_UNLOCK(flags);
}
***************
*** 142,149 ****
/**
* Register a function that is called when a byte is received.
* Arguments of the callback are: (hwstatus, numbyte, byte). The user
! * app can modify the g_size value, which is the number of bytes to be
! * received in the frame: this can be done by calling
* i2c_set_recv_size().
*/
void
--- 197,204 ----
/**
* Register a function that is called when a byte is received.
* Arguments of the callback are: (hwstatus, numbyte, byte). The user
! * app can modify the g_recv_size value, which is the number of bytes
! * to be received in the frame: this can be done by calling
* i2c_set_recv_size().
*/
void
***************
*** 160,169 ****
* error occured while sending) on the i2c bus. The event function is
* always called by software if the i2c_send() function returned 0.
* The parameter of the event function is the error code:
! * - 0 if the number of transmitted bytes is equal to the size
! * of the original send buffer, without NACK.
! * - <0 if 0 byte has been transmitted (slave not answering or
! * arbiteration lost)
* - Else, the number of transmitted bytes is given, including the
* one that was not acked.
*/
--- 215,221 ----
* error occured while sending) on the i2c bus. The event function is
* always called by software if the i2c_send() function returned 0.
* The parameter of the event function is the error code:
! * - <0 if 0 byte has been transmitted (arbiteration lost)
* - Else, the number of transmitted bytes is given, including the
* one that was not acked.
*/
***************
*** 202,208 ****
return ENXIO;
}
! if (g_status != I2C_STATUS_READY) {
IRQ_UNLOCK(flags);
return EBUSY;
}
--- 254,263 ----
return ENXIO;
}
! if (g_status & (I2C_STATUS_MASTER_XMIT |
! I2C_STATUS_MASTER_RECV |
! I2C_STATUS_SLAVE_XMIT_WAIT |
! I2C_STATUS_SLAVE_XMIT)) {
IRQ_UNLOCK(flags);
return EBUSY;
}
***************
*** 213,241 ****
}
/* bad dest_address */
! if ( ((dest_add == I2C_ADD_MASTER) && (g_mode == I2C_MODE_SLAVE)) ||
! (dest_add > I2C_ADD_MASTER) ) {
! IRQ_UNLOCK(flags);
! return EINVAL;
}
/* if g_send_buf == buf, it is a resend, so don't update
* parameters */
if ( g_send_buf != buf ) {
g_dest = dest_add;
! g_size = size;
memcpy(g_send_buf, buf, size);
}
/* if destination is not the master, IT MEANS THAT WE ARE THE
* MASTER, so we should initiate the transmission */
if (dest_add != I2C_ADD_MASTER) {
! g_status = I2C_STATUS_MASTER_XMIT;
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWSTA);
}
else {
/* else we are a slave */
! g_status = I2C_STATUS_SLAVE_XMIT_WAIT;
}
IRQ_UNLOCK(flags);
--- 268,303 ----
}
/* bad dest_address */
! if (g_mode == I2C_MODE_SLAVE) {
! if (dest_add != I2C_ADD_MASTER) {
! IRQ_UNLOCK(flags);
! return EINVAL;
! }
! }
! else {
! if (dest_add >= I2C_ADD_MASTER) {
! IRQ_UNLOCK(flags);
! return EINVAL;
! }
}
/* if g_send_buf == buf, it is a resend, so don't update
* parameters */
if ( g_send_buf != buf ) {
g_dest = dest_add;
! g_send_size = size;
memcpy(g_send_buf, buf, size);
}
/* if destination is not the master, IT MEANS THAT WE ARE THE
* MASTER, so we should initiate the transmission */
if (dest_add != I2C_ADD_MASTER) {
! g_status |= I2C_STATUS_MASTER_XMIT;
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWSTA);
}
else {
/* else we are a slave */
! g_status |= I2C_STATUS_SLAVE_XMIT_WAIT;
}
IRQ_UNLOCK(flags);
***************
*** 250,256 ****
int8_t
i2c_resend(void)
{
! return i2c_send(g_dest, g_send_buf, g_size);
}
/* called as event when using sync send */
--- 312,318 ----
int8_t
i2c_resend(void)
{
! return i2c_send(g_dest, g_send_buf, g_send_size);
}
/* called as event when using sync send */
***************
*** 266,271 ****
--- 328,334 ----
* if it is registered. This functions waits and only returns when the
* transmission is finished or if it failed. Note that there is no
* timeout, so it can loop forever...
+ * WARNING : irq MUST be enabled !
*/
int8_t
i2c_send_sync(uint8_t dest_add, uint8_t *buf, uint8_t size)
***************
*** 282,292 ****
IRQ_UNLOCK(flags);
return ret;
}
- g_is_sync = 1;
IRQ_UNLOCK(flags);
! while(g_status != I2C_STATUS_OP_FINISHED);
! g_is_sync = 0;
return g_sync_res;
}
--- 345,360 ----
IRQ_UNLOCK(flags);
return ret;
}
IRQ_UNLOCK(flags);
! /* wait the end of transmission (slave) */
! if (dest_add == I2C_ADD_MASTER) {
! while(g_status & (I2C_STATUS_SLAVE_XMIT |
! I2C_STATUS_SLAVE_XMIT_WAIT));
! }
! else { /* master */
! while(g_status & I2C_STATUS_MASTER_XMIT);
! }
return g_sync_res;
}
***************
*** 299,333 ****
*/
int8_t i2c_recv(uint8_t dest_add, uint8_t size)
{
- uint8_t flags;
-
#ifndef CONFIG_MODULE_I2C_MASTER
return EINVAL;
#else
IRQ_LOCK(flags);
if (g_mode == I2C_MODE_UNINIT) {
IRQ_UNLOCK(flags);
return ENXIO;
}
if (g_status != I2C_STATUS_READY) {
IRQ_UNLOCK(flags);
return EBUSY;
}
if (size > I2C_SEND_BUFFER_SIZE) { /* XXX is size=0 ok ? */
IRQ_UNLOCK(flags);
return EINVAL;
}
if (g_mode == I2C_MODE_SLAVE || dest_add >= I2C_ADD_MASTER) {
IRQ_UNLOCK(flags);
return EINVAL;
}
! g_size = size;
! g_status = I2C_STATUS_MASTER_RECV;
! g_dest = dest_add;
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWSTA);
IRQ_UNLOCK(flags);
--- 367,404 ----
*/
int8_t i2c_recv(uint8_t dest_add, uint8_t size)
{
#ifndef CONFIG_MODULE_I2C_MASTER
return EINVAL;
#else
+ uint8_t flags;
+
IRQ_LOCK(flags);
if (g_mode == I2C_MODE_UNINIT) {
IRQ_UNLOCK(flags);
return ENXIO;
}
+ LED2_ON();
if (g_status != I2C_STATUS_READY) {
IRQ_UNLOCK(flags);
return EBUSY;
}
+ LED3_ON();
if (size > I2C_SEND_BUFFER_SIZE) { /* XXX is size=0 ok ? */
IRQ_UNLOCK(flags);
return EINVAL;
}
+ LED4_ON();
if (g_mode == I2C_MODE_SLAVE || dest_add >= I2C_ADD_MASTER) {
IRQ_UNLOCK(flags);
return EINVAL;
}
! g_recv_size = size;
! g_status |= I2C_STATUS_MASTER_RECV;
! g_dest = dest_add ;
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWSTA);
IRQ_UNLOCK(flags);
***************
*** 347,358 ****
{
uint8_t flags;
IRQ_LOCK(flags);
! if (g_status != I2C_STATUS_SLAVE_XMIT_WAIT) {
IRQ_UNLOCK(flags);
return EBUSY;
}
! g_status = I2C_STATUS_READY;
IRQ_UNLOCK(flags);
return ESUCCESS;
--- 418,429 ----
{
uint8_t flags;
IRQ_LOCK(flags);
! if ( ! (g_status & I2C_STATUS_SLAVE_XMIT_WAIT) ) {
IRQ_UNLOCK(flags);
return EBUSY;
}
! g_status &= ~(I2C_STATUS_SLAVE_XMIT_WAIT);
IRQ_UNLOCK(flags);
return ESUCCESS;
***************
*** 361,372 ****
/**
* In MASTER RECEIVER mode, it is possible that the user application
! * does not know the size of the buffer. It is possible to adjust this
! * size during transmission (generally size can be specified at the
! * beginning of received data, the user app can be notified of this
! * with a recv_byte_event(). Note that i2c_set_recv_size() function
! * has to be used with careful, making sure you understand i2c
! * protocol and this code. Return 0 on success.
*/
uint8_t i2c_set_recv_size(uint8_t size)
{
--- 432,445 ----
/**
* In MASTER RECEIVER mode, it is possible that the user application
! * does not know the size of the buffer. You can adjust this size
! * during transmission (generally the size can be specified at the
! * beginning of received data, so the user app can be notified thanks
! * to recv_byte_event(). Note that i2c_set_recv_size() function has to
! * be used with careful, making sure you understand i2c protocol and
! * this code. Return 0 on success. Note than in SLAVE RECEIVER mode,
! * you don't have to use this function, because the master can end the
! * transmission by sending a stop condition on the bus.
*/
uint8_t i2c_set_recv_size(uint8_t size)
{
***************
*** 374,381 ****
IRQ_LOCK(flags);
! /* check that we are transmitting in master reveiver mode */
! if (g_status != I2C_STATUS_MASTER_RECV) {
IRQ_UNLOCK(flags);
return EBUSY;
}
--- 447,454 ----
IRQ_LOCK(flags);
! /* check that we are in reveiver mode */
! if (! (g_status & I2C_STATUS_MASTER_RECV)) {
IRQ_UNLOCK(flags);
return EBUSY;
}
***************
*** 383,393 ****
/* check that specified size is not greater than
* I2C_SEND_BUFFER_SIZE. But it must be greater than current
* number of received bytes. */
! if (size > I2C_SEND_BUFFER_SIZE || size <= g_nbytes) {
IRQ_UNLOCK(flags);
return EINVAL;
}
IRQ_UNLOCK(flags);
return ESUCCESS;
}
--- 456,469 ----
/* check that specified size is not greater than
* I2C_SEND_BUFFER_SIZE. But it must be greater than current
* number of received bytes. */
! /* XXX ? +1 ? */
! if (size > I2C_SEND_BUFFER_SIZE || size <= g_recv_nbytes) {
IRQ_UNLOCK(flags);
return EINVAL;
}
+ g_recv_size = size;
+
IRQ_UNLOCK(flags);
return ESUCCESS;
}
***************
*** 404,414 ****
/**
* return the status of the i2c module.
*/
! i2c_status_t i2c_status(void)
{
return g_status;
}
--- 480,515 ----
/**
* return the status of the i2c module.
*/
! uint8_t i2c_status(void)
{
return g_status;
}
+ /**
+ * Copy the received buffer in the buffer given as parameter. Return
+ * number of copied bytes or -1 on error.
+ */
+ uint8_t i2c_get_recv_buffer(uint8_t *buf, uint8_t size)
+ {
+ uint8_t flags;
+
+ IRQ_LOCK(flags);
+ /* check that reception is finished */
+ if ( g_status & (I2C_STATUS_MASTER_RECV |
+ I2C_STATUS_SLAVE_RECV) ) {
+ IRQ_UNLOCK(flags);
+ return -EBUSY;
+ }
+
+ if (size > g_recv_nbytes)
+ size = g_recv_nbytes;
+ memcpy(buf, g_recv_buf, size);
+
+ IRQ_UNLOCK(flags);
+
+ return size;
+ }
+
***************
*** 431,440 ****
case TW_START:
case TW_REP_START:
/* a start has been transmitted, transmit SLA+W which is :
! * b7: 0 (write operation)
! * b0-6: slave address */
! TWDR = g_dest;
! g_nbytes = 0;
break;
--- 532,547 ----
case TW_START:
case TW_REP_START:
/* a start has been transmitted, transmit SLA+W which is :
! * b7-1: slave address
! * b0 : 0 (write operation) or 1 (read) */
! if (g_status & I2C_STATUS_MASTER_RECV) {
! TWDR = (g_dest << 1) | (0x01);
! g_recv_nbytes = 0;
! }
! else {
! TWDR = (g_dest << 1);
! g_send_nbytes = 0;
! }
break;
***************
*** 442,448 ****
case TW_MT_SLA_ACK:
/* the slave is there. start sending data */
! TWDR = g_send_buf[g_nbytes++];
break;
case TW_MT_SLA_NACK:
--- 549,555 ----
case TW_MT_SLA_ACK:
/* the slave is there. start sending data */
! TWDR = g_send_buf[g_send_nbytes++];
break;
case TW_MT_SLA_NACK:
***************
*** 450,469 ****
if(g_send_event)
g_send_event(-1);
command |= (1<<TWSTO);
! g_status = I2C_STATUS_OP_FINISHED;
break;
case TW_MT_DATA_ACK:
/* we transmitted data with success, send next one or
* stop condition if there is no more data */
! if (g_nbytes >= g_size) {
if(g_send_event)
! g_send_event(0);
command |= (1<<TWSTO);
! g_status = I2C_STATUS_OP_FINISHED;
}
else {
! TWDR = g_send_buf[g_nbytes++];
}
break;
--- 557,576 ----
if(g_send_event)
g_send_event(-1);
command |= (1<<TWSTO);
! g_status |= I2C_STATUS_OP_FINISHED;
break;
case TW_MT_DATA_ACK:
/* we transmitted data with success, send next one or
* stop condition if there is no more data */
! if (g_send_nbytes >= g_send_size) {
if(g_send_event)
! g_send_event(g_send_nbytes);
command |= (1<<TWSTO);
! g_status |= I2C_STATUS_OP_FINISHED;
}
else {
! TWDR = g_send_buf[g_send_nbytes++];
}
break;
***************
*** 472,480 ****
* Notify the number of bytes sent, including the one
* that were not acked, and send a stop condition */
if(g_send_event)
! g_send_event(g_nbytes);
command |= (1<<TWSTO);
! g_status = I2C_STATUS_OP_FINISHED;
break;
--- 579,587 ----
* Notify the number of bytes sent, including the one
* that were not acked, and send a stop condition */
if(g_send_event)
! g_send_event(g_send_nbytes);
command |= (1<<TWSTO);
! g_status |= I2C_STATUS_OP_FINISHED;
break;
***************
*** 484,522 ****
/* the slave is there, we know that we have enough
* room in buffer because it is the 1st byte. If
* there's only 1 byte to receive, don't set TWEA */
! if (g_size > 1)
command |= (1<<TWEA);
break;
case TW_MR_SLA_NACK:
/* the slave does not answer, send a stop condition */
if(g_recv_event)
! g_recv_event(NULL, -1);
command |= (1<<TWSTO);
! g_status = I2C_STATUS_OP_FINISHED;
break;
case TW_MR_DATA_ACK:
/* receive data */
! if (g_nbytes < g_size)
! g_recv_buf[g_nbytes] = TWDR;
! if(g_recv_byte_event)
! g_recv_byte_event(hard_status, g_nbytes,
g_recv_buf[g_nbytes]);
/* More than one byte remaining -> set TWEA */
! if (g_size > g_nbytes + 1) {
command |= (1<<TWEA);
}
- g_nbytes++;
break;
case TW_MR_DATA_NACK:
/* we received the last byte */
! if (g_nbytes < g_size)
! g_recv_buf[g_nbytes++] = TWDR;
! if(g_recv_event)
! g_recv_event(g_recv_buf, g_nbytes);
! g_status = I2C_STATUS_OP_FINISHED;
break;
--- 591,638 ----
/* the slave is there, we know that we have enough
* room in buffer because it is the 1st byte. If
* there's only 1 byte to receive, don't set TWEA */
! if (g_recv_size > 1)
command |= (1<<TWEA);
break;
case TW_MR_SLA_NACK:
/* the slave does not answer, send a stop condition */
if(g_recv_event)
! g_recv_event(g_recv_buf, -1);
command |= (1<<TWSTO);
! g_status |= I2C_STATUS_OP_FINISHED;
break;
case TW_MR_DATA_ACK:
/* receive data */
! if (g_recv_nbytes < g_recv_size) {
! g_recv_buf[g_recv_nbytes] = TWDR;
+ if(g_recv_byte_event)
+ g_recv_byte_event(hard_status, g_recv_nbytes,
g_recv_buf[g_recv_nbytes]);
+
+ g_recv_nbytes++;
+ }
/* More than one byte remaining -> set TWEA */
! if (g_recv_nbytes < g_recv_size) {
command |= (1<<TWEA);
}
break;
case TW_MR_DATA_NACK:
/* we received the last byte */
! if (g_recv_nbytes < g_recv_size) {
! g_recv_buf[g_recv_nbytes] = TWDR;
!
! if(g_recv_byte_event)
! g_recv_byte_event(hard_status, g_recv_nbytes,
g_recv_buf[g_recv_nbytes]);
! g_recv_nbytes ++;
! }
! if(g_recv_event) {
! g_recv_event(g_recv_buf, g_recv_nbytes);
! }
! command |= (1<<TWSTO);
! g_status |= I2C_STATUS_OP_FINISHED;
break;
***************
*** 524,537 ****
case TW_MT_ARB_LOST:
/* arbitration lost, notify application */
! if (g_status == I2C_STATUS_MASTER_XMIT) {
if(g_recv_event)
! g_recv_event(NULL, -2);
}
! else if (g_status == I2C_STATUS_MASTER_RECV) {
if(g_send_event)
g_send_event(-2);
- g_status = I2C_STATUS_OP_FINISHED;
}
break;
--- 640,652 ----
case TW_MT_ARB_LOST:
/* arbitration lost, notify application */
! if (g_status & I2C_STATUS_MASTER_XMIT) {
if(g_recv_event)
! g_recv_event(g_recv_buf, -2);
}
! else if (g_status & I2C_STATUS_MASTER_RECV) {
if(g_send_event)
g_send_event(-2);
}
break;
***************
*** 546,553 ****
case TW_SR_ARB_LOST_GCALL_ACK:
/* slave is addressed (in general call or not, and
* after arbiteration lost or not) */
! g_nbytes = 0;
! g_status = I2C_STATUS_SLAVE_RECV;
command |= (1<<TWEA);
break;
--- 661,669 ----
case TW_SR_ARB_LOST_GCALL_ACK:
/* slave is addressed (in general call or not, and
* after arbiteration lost or not) */
! g_recv_nbytes = 0;
! g_recv_size = I2C_RECV_BUFFER_SIZE;
! g_status |= I2C_STATUS_SLAVE_RECV;
command |= (1<<TWEA);
break;
***************
*** 555,568 ****
case TW_SR_GCALL_DATA_ACK:
/* receive data, the following test should always be
* true */
! if (g_nbytes < I2C_RECV_BUFFER_SIZE)
! g_recv_buf[g_nbytes] = TWDR;
! if(g_recv_byte_event)
! g_recv_byte_event(hard_status, g_nbytes,
g_recv_buf[g_nbytes]);
! g_nbytes++;
/* if there's more than one byte left in buffer, send
* TWEA */
! if (I2C_RECV_BUFFER_SIZE < g_nbytes + 1) {
command |= (1<<TWEA);
}
break;
--- 671,685 ----
case TW_SR_GCALL_DATA_ACK:
/* receive data, the following test should always be
* true */
! if (g_recv_nbytes < g_recv_size) {
! g_recv_buf[g_recv_nbytes] = TWDR;
! if(g_recv_byte_event)
! g_recv_byte_event(hard_status, g_recv_nbytes,
g_recv_buf[g_recv_nbytes]);
! g_recv_nbytes++;
! }
/* if there's more than one byte left in buffer, send
* TWEA */
! if (g_recv_nbytes < g_recv_size) {
command |= (1<<TWEA);
}
break;
***************
*** 570,590 ****
case TW_SR_GCALL_DATA_NACK:
case TW_SR_DATA_NACK:
/* receive last data byte (our buffer is full) */
! if (g_nbytes < I2C_RECV_BUFFER_SIZE)
! g_recv_buf[g_nbytes] = TWDR;
! if(g_recv_byte_event)
! g_recv_byte_event(hard_status, g_nbytes,
g_recv_buf[g_nbytes]);
! g_nbytes++;
! if (g_recv_event)
! g_recv_event(g_recv_buf, g_nbytes);
! g_status = I2C_STATUS_OP_FINISHED;
break;
case TW_SR_STOP:
/* the master sent a stop condition, notify app */
if (g_recv_event)
! g_recv_event(g_recv_buf, g_nbytes);
! g_status = I2C_STATUS_OP_FINISHED;
break;
--- 687,706 ----
case TW_SR_GCALL_DATA_NACK:
case TW_SR_DATA_NACK:
/* receive last data byte (our buffer is full) */
! if (g_recv_nbytes < g_recv_size) {
! g_recv_buf[g_recv_nbytes] = TWDR;
!
! if(g_recv_byte_event)
! g_recv_byte_event(hard_status, g_recv_nbytes,
g_recv_buf[g_recv_nbytes]);
! g_recv_nbytes++;
! }
break;
case TW_SR_STOP:
/* the master sent a stop condition, notify app */
if (g_recv_event)
! g_recv_event(g_recv_buf, g_recv_nbytes);
! g_status |= I2C_STATUS_OP_FINISHED;
break;
***************
*** 592,636 ****
case TW_ST_SLA_ACK:
case TW_ST_ARB_LOST_SLA_ACK:
/* slave is addressed. If it is not ready, send a 0 as
* last byte. */
! g_nbytes = 0;
! if (g_status != I2C_STATUS_SLAVE_XMIT_WAIT) {
TWDR = 0;
! g_size=0;
}
/* else:
* if there is only 1 byte to transmit, we don't
* need to send ack, else set TWEA. */
else {
! if (g_size > 1)
command |= (1<<TWEA);
! TWDR = g_send_buf[g_nbytes++];
}
! g_status = I2C_STATUS_SLAVE_XMIT;
break;
case TW_ST_DATA_ACK:
/* transmitting data, if there is more than one byte
* to send, send ack */
! if (g_size > g_nbytes + 1)
command |= (1<<TWEA);
! TWDR = g_send_buf[g_nbytes++];
break;
case TW_ST_DATA_NACK:
! /* g_nbytes should be different than g_size here ? */
! if(g_send_event)
! g_send_event(g_nbytes);
! g_status = I2C_STATUS_OP_FINISHED;
break;
case TW_ST_LAST_DATA:
! /* last data transmitted, notify app */
if(g_send_event)
! g_send_event(0);
! g_status = I2C_STATUS_OP_FINISHED;
break;
--- 708,756 ----
case TW_ST_SLA_ACK:
case TW_ST_ARB_LOST_SLA_ACK:
+ LED5_ON();
/* slave is addressed. If it is not ready, send a 0 as
* last byte. */
! g_send_nbytes = 0;
! if (! (g_status & I2C_STATUS_SLAVE_XMIT_WAIT)) {
TWDR = 0;
! g_send_size=0;
}
/* else:
* if there is only 1 byte to transmit, we don't
* need to send ack, else set TWEA. */
else {
! if (g_send_size > 1) {
command |= (1<<TWEA);
! }
! TWDR = g_send_buf[g_send_nbytes++];
}
! g_status &= ~(I2C_STATUS_SLAVE_XMIT_WAIT);
! g_status |= I2C_STATUS_SLAVE_XMIT;
break;
case TW_ST_DATA_ACK:
/* transmitting data, if there is more than one byte
* to send, send ack */
! if (g_send_size > g_send_nbytes + 1)
command |= (1<<TWEA);
! TWDR = g_send_buf[g_send_nbytes++];
break;
case TW_ST_DATA_NACK:
! /* notify app that we send the frame */
! if(g_send_event) {
! g_send_event(g_send_nbytes);
! }
! g_status |= I2C_STATUS_OP_FINISHED;
break;
case TW_ST_LAST_DATA:
! /* last data transmitted, notify app XXX (not very sure) */
if(g_send_event)
! g_send_event(g_send_nbytes);
! g_status |= I2C_STATUS_OP_FINISHED;
break;
***************
*** 650,665 ****
/* atomic MT + MR, see page 226 atm128 XXX */
/* transmission finished */
! if (g_status == I2C_STATUS_OP_FINISHED) {
/* if it is not a synchronous op, we should be aware
* of next SLA+RW if we are a slave or multimaster */
#ifdef CONFIG_MODULE_I2C_MASTER
! if (! g_is_sync && g_mode != I2C_MODE_MASTER)
command |= (1<<TWEA);
#else
! if (! g_is_sync)
! command |= (1<<TWEA);
#endif
}
TWCR = command;
--- 770,790 ----
/* atomic MT + MR, see page 226 atm128 XXX */
/* transmission finished */
! if (g_status & I2C_STATUS_OP_FINISHED) {
/* if it is not a synchronous op, we should be aware
* of next SLA+RW if we are a slave or multimaster */
#ifdef CONFIG_MODULE_I2C_MASTER
! if (g_mode != I2C_MODE_MASTER)
command |= (1<<TWEA);
#else
! command |= (1<<TWEA);
#endif
+ /* remove current op */
+ g_status &= ~(I2C_STATUS_MASTER_XMIT |
+ I2C_STATUS_MASTER_RECV |
+ I2C_STATUS_SLAVE_XMIT |
+ I2C_STATUS_SLAVE_RECV |
+ I2C_STATUS_OP_FINISHED);
}
TWCR = command;
_______________________________________________
Avr-list mailing list
[email protected]
CVSWEB : http://cvsweb.droids-corp.org/cgi-bin/viewcvs.cgi/aversive
WIKI : http://wiki.droids-corp.org/index.php/Aversive
DOXYGEN : http://zer0.droids-corp.org/doxygen_aversive/html/
BUGZILLA : http://bugzilla.droids-corp.org
COMMIT LOGS : http://zer0.droids-corp.org/aversive_commitlog