]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - embedded/libs4c/i2c/i2c_c552.c
Update of system-less architecture and board support code to actual uLAN.sf.net version.
[lincan.git] / embedded / libs4c / i2c / i2c_c552.c
index 7cede723be3f117763588223b4c26abe154dd70b..f38b931b962c5710fa1b0f7ad3f13772bf569b51 100644 (file)
 
 
 #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 */
@@ -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: