2 * Copyright Droids Corporation, Microb Technology, Eirbot (2005)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include <aversive/wait.h>
32 #include <util/delay.h>
40 volatile i2cm_state g_i2cm_state = NOT_INIT;
41 volatile uint8_t g_i2cm_byte;
43 void (*g_i2cm_event)(i2cm_state state);
52 #define I2CM_SCL_PORT PORTD
53 #define I2CM_SCL_BIT 6
55 #define I2CM_SDA_PORT PORTD
56 #define I2CM_SDA_BIT 5
58 #define I2CM_SCL I2CM_SCL_PORT, I2CM_SCL_BIT
59 #define I2CM_SDA I2CM_SDA_PORT, I2CM_SDA_BIT
67 - port SCL/SDA is set to 0
68 - i2c is then driven using DDR 0 (Hi-Z) or 1 (For Low)
72 cbi(DDR(I2CM_SCL_PORT),I2CM_SCL_BIT);
73 I2C_HIGH(I2CM_SCL_PORT, I2CM_SCL_BIT);
76 cbi(DDR(I2CM_SDA_PORT),I2CM_SDA_BIT);
77 I2C_HIGH(I2CM_SDA_PORT, I2CM_SDA_BIT);
80 g_i2cm_state = I2CM_READY;
84 void i2cm_manage(void)
86 if ( (g_i2cm_event != NULL) && (g_i2cm_state != I2CM_READY) ) {
87 g_i2cm_event( g_i2cm_state );
89 if (g_i2cm_state != I2CM_BUSY)
90 g_i2cm_state = I2CM_READY;
94 uint8_t i2cm_get_state(void)
100 uint8_t i2cm_get_received_byte(void)
102 g_i2cm_state = I2CM_READY;
106 void i2cm_register_event(void (*func)(i2cm_state state))
115 static uint8_t i2cm_send_byte(uint8_t byte)
121 g_i2cm_state = I2CM_BUSY;
123 // SCL should already be low
124 // I2C_LOW(I2CM_SCL_PORT, I2CM_SCL_BIT);
133 I2C_HIGH(I2CM_SDA_PORT, I2CM_SDA_BIT);
135 I2C_LOW(I2CM_SDA_PORT, I2CM_SDA_BIT);
140 I2C_HIGH(I2CM_SCL_PORT, I2CM_SCL_BIT);
142 while ( bit_is_clear(PIN(I2CM_SCL_PORT), I2CM_SCL_BIT) );// slave handshake
145 I2C_LOW(I2CM_SCL_PORT, I2CM_SCL_BIT);
152 I2C_HIGH(I2CM_SDA_PORT, I2CM_SDA_BIT);
156 I2C_HIGH(I2CM_SCL_PORT, I2CM_SCL_BIT);
158 while ( bit_is_clear(PIN(I2CM_SCL_PORT), I2CM_SCL_BIT) );// slave handshake
160 // we should receive ACK
161 if (bit_is_set(PIN(I2CM_SDA_PORT), I2CM_SDA_BIT))
162 err = I2CM_SENT_NO_ACK;
165 I2C_LOW(I2CM_SCL_PORT, I2CM_SCL_BIT);
172 uint8_t i2cm_send_start(uint8_t sla_w)
176 g_i2cm_state = I2CM_BUSY;
178 I2C_HIGH(I2CM_SCL_PORT, I2CM_SCL_BIT);
179 I2C_HIGH(I2CM_SDA_PORT, I2CM_SDA_BIT);
183 /* wait for bus realese */
184 for (i=0;i<0x8000; i++){
185 if( bit_is_set(PIN(I2CM_SCL_PORT), I2CM_SCL_BIT) && \
186 bit_is_set(PIN(I2CM_SDA_PORT), I2CM_SDA_BIT) )
190 // while ( bit_is_clear(PIN(I2CM_SCL_PORT), I2CM_SCL_BIT) );// slave handshake
193 I2C_LOW(I2CM_SDA_PORT, I2CM_SDA_BIT);
195 I2C_LOW(I2CM_SCL_PORT, I2CM_SCL_BIT);
198 err = i2cm_send_byte(sla_w);
204 uint8_t i2cm_send_stop(void)
206 g_i2cm_state = I2CM_BUSY;
209 I2C_LOW(I2CM_SCL_PORT, I2CM_SCL_BIT);
210 I2C_LOW(I2CM_SDA_PORT, I2CM_SDA_BIT);
214 I2C_HIGH(I2CM_SCL_PORT, I2CM_SCL_BIT);
216 I2C_HIGH(I2CM_SDA_PORT, I2CM_SDA_BIT);
219 g_i2cm_state = I2CM_SENT_STOP;
224 uint8_t i2cm_receive_byte(uint8_t last)
228 g_i2cm_state = I2CM_BUSY;
230 I2C_HIGH(I2CM_SDA_PORT, I2CM_SDA_BIT);
238 I2C_HIGH(I2CM_SCL_PORT, I2CM_SCL_BIT);
240 while ( bit_is_clear(PIN(I2CM_SCL_PORT), I2CM_SCL_BIT) );// slave handshake
242 if (bit_is_set(PIN(I2CM_SDA_PORT),I2CM_SDA_BIT))
246 I2C_LOW(I2CM_SCL_PORT, I2CM_SCL_BIT);
254 I2C_LOW(I2CM_SDA_PORT, I2CM_SDA_BIT);
259 I2C_HIGH(I2CM_SCL_PORT, I2CM_SCL_BIT);
261 while ( bit_is_clear(PIN(I2CM_SCL_PORT), I2CM_SCL_BIT) );// slave handshake
264 I2C_LOW(I2CM_SCL_PORT, I2CM_SCL_BIT);
269 I2C_HIGH(I2CM_SDA_PORT, I2CM_SDA_BIT);
274 g_i2cm_state = I2CM_RECEIVED_BYTE;
276 I2C_HIGH(I2CM_SCL_PORT, I2CM_SCL_BIT);
282 uint8_t i2cm_send(uint8_t addr, uint8_t* data, uint8_t len)
287 err = i2cm_send_start((addr<<1) | 0);
291 for (i=0; i<len; i++) {
292 err = i2cm_send_byte(data[i]);
302 uint8_t i2c_buf[0x20]; /* XXX */
304 uint8_t i2cm_recv(uint8_t addr, uint8_t len)
309 err = i2cm_send_start((addr<<1) | 1);
315 for (i=0; i<len; i++){
316 err =i2cm_receive_byte(i == len-1);
317 i2c_buf[i] = g_i2cm_byte;
326 uint8_t i2cm_get_recv_buffer(uint8_t* buf, uint8_t len)
329 for (i=0; i<len; i++)