#include <system_def.h>
-#include <hal_intr.h>
+#include <cpu_def.h>
+#include <hal_machperiph.h> /* for PCLK on LPC17xx */
#include "i2c_drv_config.h"
#include "i2c_drv.h"
int c552_poll(i2c_drv_t *drv);
-void c552_irq_handler(int intno, void *dev_id);
+IRQ_HANDLER_FNC(c552_irq_handler);
static int c552_ctrl_fnc(struct i2c_drv *drv, int ctrl, void *p);
+int c552_stroke(i2c_drv_t *drv);
// I2C Registers
+
+#ifdef __LPC17xx_H__
+
+#define C552_CONSET(port) (((I2C_TypeDef *)(port))->I2CONSET) /* Control Set Register */
+#define C552_STAT(port) (((I2C_TypeDef *)(port))->I2STAT) /* Status Register */
+#define C552_DAT(port) (((I2C_TypeDef *)(port))->I2DAT) /* Data Register */
+#define C552_ADR(port) (((I2C_TypeDef *)(port))->I2ADR0) /* Slave Address Register */
+#define C552_SCLH(port) (((I2C_TypeDef *)(port))->I2SCLH) /* SCL Duty Cycle Register (high half word) */
+#define C552_SCLL(port) (((I2C_TypeDef *)(port))->I2SCLL) /* SCL Duty Cycle Register (low half word) */
+#define C552_CONCLR(port) (((I2C_TypeDef *)(port))->I2CONCLR) /* Control Clear Register */
+#define C552_MMCTRL(port) (((I2C_TypeDef *)(port))->MMCTRL) /* Monitor Mode Control */
+
+#else /*__LPC17xx_H__*/
+
#define C552_CONSET(port) (((i2cRegs_t *)(port))->conset) /* Control Set Register */
#define C552_STAT(port) (((i2cRegs_t *)(port))->stat) /* Status Register */
#define C552_DAT(port) (((i2cRegs_t *)(port))->dat) /* Data Register */
#define C552_SCLL(port) (((i2cRegs_t *)(port))->scll) /* SCL Duty Cycle Register (low half word) */
#define C552_CONCLR(port) (((i2cRegs_t *)(port))->conclr) /* Control Clear Register */
+#endif /*__LPC17xx_H__*/
+
#define C552CON_AA (1 << 2)
#define C552CON_SI (1 << 3)
#define C552CON_STO (1 << 4)
/***************************************************************************/
int c552_init_start(struct i2c_drv *drv, int port, int irq, int bitrate, int sladr)
{
+ unsigned long clock_base;
+
+ clock_base=PCLK/2;
+
C552_ADR(port)=sladr;
- C552_SCLH(port)=((PCLK/2)/bitrate); //minimal value
- C552_SCLL(port)=((PCLK/2)/bitrate);
+ C552_SCLH(port)=clock_base/bitrate; //minimal value
+ C552_SCLL(port)=clock_base/bitrate;
drv->irq=irq;
drv->port=port;
drv->sfnc_act=NULL;
drv->ctrl_fnc=c552_ctrl_fnc;
drv->poll_fnc=c552_poll;
+ drv->stroke_fnc=c552_stroke;
drv->flags=I2C_DRV_ON; /* todo - use atomic operation */
C552_CONCLR(port)=0x6C; /* clearing all flags */
C552_CONSET(port)=C552CON_EN;
- HAL_INTERRUPT_ATTACH(irq,c552_irq_handler,drv);
- HAL_INTERRUPT_UNMASK(irq);
+ request_irq(irq, c552_irq_handler, 0, "i2c", drv);
return 0;
}
i2c_msg_head_t *msg=drv->msg_act;
if(msg) {
- if((msg->flags&I2C_MSG_CB_END) && (msg->callback))
- msg->callback(drv,I2C_MSG_CB_END,msg);
if(msg->flags&I2C_MSG_REPEAT){
drv->master_queue=msg->next;
}else{
i2c_drv_queue_msg(msg->flags&I2C_MSG_NOPROC?NULL:&drv->proc_queue,msg);
}
msg->flags|=I2C_MSG_FINISHED;
+ if((msg->flags&I2C_MSG_CB_END) && (msg->callback))
+ msg->callback(drv,I2C_MSG_CB_END,msg);
}
if(drv->master_queue) {
return 0;
}
+int c552_stroke(i2c_drv_t *drv)
+{
+ int port;
+ volatile int d;
+ port=drv->port;
+
+ C552_CONSET(port)=C552CON_STO;
+ C552_CONSET(port)=C552CON_STA;
+ for(d=0;d<10;d++);
+ C552_CONSET(port)=C552CON_STA;
+ return 0;
+}
+
+
int i2c_irq_seq_num=0;
/***************************************************************************/
-void c552_irq_handler(int intno, void *dev_id)
+IRQ_HANDLER_FNC(c552_irq_handler)
{
i2c_drv_t *drv;
i2c_msg_head_t *msg;
int port;
int stat;
- drv=(i2c_drv_t*)dev_id;
+ drv=(i2c_drv_t*)irq_handler_get_context();
if(drv->magic!=I2C_DRV_MAGIC)
{
#ifdef FOR_LINUX_KERNEL
/* received DATA sent ACK */
msg->rx_buf[msg->rx_len]= C552_DAT(port);
msg->rx_len++;
- if (msg->rx_rq==msg->rx_len)
+ if (msg->rx_len+1>=msg->rx_rq)
C552_CONCLR(port)=C552CON_AAC;
break;
case 0x58: