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 Avr-list@droids-corp.org 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