1 /*******************************************************************
2 Components for embedded applications builded for
3 laboratory and medical instruments firmware
5 i2c_mx1.c - I2C communication automata for M9328 MX1 microcontroller
7 Copyright holders and project originators
8 (C) 2001-2004 by Pavel Pisa pisa@cmp.felk.cvut.cz
9 (C) 2002-2004 by PiKRON Ltd. http://www.pikron.com
10 (C) 2007-2008 by Petr Smolik
12 The COLAMI components can be used and copied under next licenses
13 - MPL - Mozilla Public License
14 - GPL - GNU Public License
15 - LGPL - Lesser GNU Public License
16 - and other licenses added by project originators
17 Code can be modified and re-distributed under any combination
18 of the above listed licenses. If contributor does not agree with
19 some of the licenses, he can delete appropriate line.
20 Warning, if you delete all lines, you are not allowed to
21 distribute code or build project.
22 *******************************************************************/
25 #include <system_def.h>
27 #include "i2c_drv_config.h"
30 /***************************************************************************/
32 i2c_drv_init(i2c_drv_t *drv, int port, int irq, int bitrate,int sladr)
35 memset(drv,0,sizeof(i2c_drv_t));
36 drv->magic=I2C_DRV_MAGIC;
37 #ifdef CONFIG_OC_I2C_CHIP_C552
38 r=c552_init_start(drv,port,irq,bitrate,sladr);
39 #endif /* CONFIG_OC_I2C_CHIP_C552 */
44 /********************************************************************/
45 /* Generic I2C functions */
47 void i2c_drv_queue_msg(i2c_msg_head_t **queue, i2c_msg_head_t *msg)
50 i2c_msg_head_t *prev, *next;
54 if(*msg->on_queue==msg)
57 msg->next->prev=msg->prev;
58 msg->prev->next=msg->next;
59 if(*msg->on_queue==msg)
60 *msg->on_queue=msg->next;
63 if((msg->on_queue=queue)!=NULL){
64 if((next=*queue)!=NULL){
65 msg->prev=prev=next->prev;
70 *queue=msg->prev=msg->next=msg;
77 int i2c_drv_master_msg_ins(i2c_drv_t *drv, i2c_msg_head_t *msg)
80 if(!(drv->flags&I2C_DRV_ON)) return -1;
81 if(!msg->tx_buf) msg->flags&=~I2C_MSG_MS_TX;
82 if(!msg->rx_buf) msg->flags&=~I2C_MSG_MS_RX;
83 i2c_drv_queue_msg(&drv->master_queue,msg);
84 drv->ctrl_fnc(drv,I2C_CTRL_MS_RQ,NULL);
88 int i2c_drv_master_msg_rem(i2c_drv_t *drv, i2c_msg_head_t *msg)
93 i2c_drv_queue_msg(NULL,msg);
95 act = (msg==drv->msg_act);
100 } while(msg->on_queue || act);
104 int i2c_drv_flush_all(i2c_drv_t *drv)
107 i2c_msg_head_t *msg, *next;
108 i2c_msg_head_t *queue[3];
112 queue[0]=drv->master_queue;
113 queue[1]=drv->slave_queue;
114 queue[2]=drv->proc_queue;
115 drv->master_queue=NULL;
116 drv->slave_queue=NULL;
117 drv->proc_queue=NULL;
120 for(quenum=0;quenum<3;quenum++){
123 msg->prev->next=NULL;
126 msg->flags|=I2C_MSG_FAIL;
128 if((msg->flags&I2C_MSG_CB_PROC) && (msg->callback))
129 msg->callback(drv,I2C_MSG_CB_PROC,msg);
135 int i2c_drv_master_transfer_callback(struct i2c_drv *drv, int code, struct i2c_msg_head *msg)
137 if(code!=I2C_MSG_CB_PROC) return 0;
138 set_bit(0,&(msg->private));
143 int i2c_drv_master_transfer(i2c_drv_t *drv, int addr, int tx_rq, int rx_rq,
144 void *tx_buf, void *rx_buf, int *ptx_len, int *prx_len)
148 msg.flags = I2C_MSG_CB_PROC;
155 msg.callback = i2c_drv_master_transfer_callback;
159 msg.flags |= I2C_MSG_MS_TX;
161 if(msg.rx_buf && (msg.rx_rq>=1))
162 msg.flags |= I2C_MSG_MS_RX;
164 if(!(msg.flags & (I2C_MSG_MS_TX | I2C_MSG_MS_RX)))
167 if(i2c_drv_master_msg_ins(drv, &msg)<0)
170 /* wait for message process */
171 while(test_bit(0,&(msg.private))==0)
174 if(ptx_len) *ptx_len = msg.tx_len;
175 if(prx_len) *prx_len = msg.rx_len;
177 if(msg.flags & I2C_MSG_FAIL)
180 return msg.tx_len+msg.rx_len;