]> rtime.felk.cvut.cz Git - sysless.git/commitdiff
I2C_DRV: added protection against deadlock at bus error state -> call stroke function
authorsmolik <smolik>
Sat, 24 Oct 2009 23:07:16 +0000 (23:07 +0000)
committersmolik <smolik>
Sat, 24 Oct 2009 23:07:16 +0000 (23:07 +0000)
board/arm/ul_usb1/libs/bspbase/bsp0hwinit.c
libs4c/i2c/i2c_c552.c
libs4c/i2c/i2c_drv.h

index e47b799e8047fce3fa4b90b2b38693e16c016441..408e59171f13eee4496542d709111d221700c759 100644 (file)
 /* timers */
 volatile lt_ticks_t sys_timer_ticks;
 
+#ifdef CONFIG_OC_I2C_DRV_SYSLESS
+#define I2C_DRV_NA_MSTIMEOUT    10
+i2c_drv_t i2c_drv;
+int i2c_drv_na_timer=0;
+#endif /* CONFIG_OC_I2C_DRV_SYSLESS */
+
 static void sysInit(void) 
 {
 
@@ -74,6 +80,21 @@ void timer0_isr(void)
      #endif
      #ifdef CONFIG_OC_PBM_DRV
       pbm_jiffies++;
+     #endif
+     #ifdef CONFIG_OC_I2C_DRV_SYSLESS
+      if (i2c_drv.flags&I2C_DRV_MS_INPR) {
+        if (i2c_drv.flags&I2C_DRV_NA)
+          i2c_drv_na_timer++;
+          if (i2c_drv_na_timer>I2C_DRV_NA_MSTIMEOUT) {
+             if (i2c_drv.stroke_fnc) 
+              i2c_drv.stroke_fnc(&i2c_drv);
+            i2c_drv_na_timer=0;
+          }
+        else {
+          i2c_drv_na_timer=0;
+        }
+        i2c_drv.flags|=I2C_DRV_NA;
+      }
      #endif
       sys_timer_ticks++;
     } while (((int32_t)(T0MR0-T0TC))<0);
@@ -308,8 +329,6 @@ int uLanInit()
 
 #ifdef CONFIG_OC_I2C_DRV_SYSLESS
 
-i2c_drv_t i2c_drv;
-
 int
 i2cInit(void)
 {
index 7cede723be3f117763588223b4c26abe154dd70b..bc1036f8612fe89055f9d9692272c81e04f0e854 100644 (file)
@@ -30,6 +30,7 @@
 int c552_poll(i2c_drv_t *drv);
 void c552_irq_handler(int intno, void *dev_id);
 static int c552_ctrl_fnc(struct i2c_drv *drv, int ctrl, void *p);
+int c552_stroke(i2c_drv_t *drv);
 
 // I2C Registers
 #define C552_CONSET(port)  (((i2cRegs_t *)(port))->conset)     /* Control Set Register */
@@ -62,6 +63,7 @@ int c552_init_start(struct i2c_drv *drv, int port, int irq, int bitrate, int sla
   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;
@@ -153,6 +155,20 @@ 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;
 
 /***************************************************************************/
index 50725d1d0c86e8ee638194161debab092a8702e4..f1cca85d1382839dab476ffcf857b88208501e74 100644 (file)
@@ -73,6 +73,7 @@ typedef struct i2c_msg_head {
 
 typedef int (i2c_sfnc_t)(struct i2c_drv *drv, int code);
 typedef int (i2c_ctrl_fnc_t)(struct i2c_drv *drv, int ctrl, void *p);
+typedef int (i2c_stroke_fnc_t)(struct i2c_drv *drv);
 
 #define I2C_DRV_ON      1 /* flag indicating that driver is ready to operate */
 #define I2C_DRV_MS_INPR 2 /* master request in in progress */
@@ -96,6 +97,7 @@ typedef struct i2c_drv {
     void *failed;
     i2c_ctrl_fnc_t *ctrl_fnc;
     int (*poll_fnc)(struct i2c_drv *drv);
+    i2c_stroke_fnc_t *stroke_fnc;
     uint8_t sl_last_cmd; /* last received slave command */
   } i2c_drv_t;