X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/cc1afb21bdc089426652f21769164645cae062fd..243fec4450d3a3246f3f0d92751a95daef7c1503:/embedded/libs4c/i2c/i2c_c552.c diff --git a/embedded/libs4c/i2c/i2c_c552.c b/embedded/libs4c/i2c/i2c_c552.c index 7cede72..f38b931 100644 --- a/embedded/libs4c/i2c/i2c_c552.c +++ b/embedded/libs4c/i2c/i2c_c552.c @@ -23,15 +23,31 @@ #include -#include +#include +#include /* 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 */ @@ -40,6 +56,8 @@ static int c552_ctrl_fnc(struct i2c_drv *drv, int ctrl, void *p); #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) @@ -54,19 +72,23 @@ static int c552_ctrl_fnc(struct i2c_drv *drv, int ctrl, void *p); /***************************************************************************/ 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; } @@ -153,17 +175,31 @@ int c552_poll(i2c_drv_t *drv) 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 @@ -272,7 +308,7 @@ void c552_irq_handler(int intno, void *dev_id) /* 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: