paparazzi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[paparazzi-commits] [5797] new i2c support for lpc on I2C2, working with


From: Gautier Hattenberger
Subject: [paparazzi-commits] [5797] new i2c support for lpc on I2C2, working with infrared_i2c
Date: Fri, 03 Sep 2010 14:24:36 +0000

Revision: 5797
          http://svn.sv.gnu.org/viewvc/?view=rev&root=paparazzi&revision=5797
Author:   gautier
Date:     2010-09-03 14:24:35 +0000 (Fri, 03 Sep 2010)
Log Message:
-----------
new i2c support for lpc on I2C2, working with infrared_i2c

Modified Paths:
--------------
    paparazzi3/trunk/sw/airborne/arm7/i2c_hw.c
    paparazzi3/trunk/sw/airborne/arm7/i2c_hw.h
    paparazzi3/trunk/sw/airborne/i2c.h
    paparazzi3/trunk/sw/airborne/main_ap.c
    paparazzi3/trunk/sw/airborne/modules/sensors/infrared_i2c.c
    paparazzi3/trunk/sw/airborne/modules/sensors/infrared_i2c.h

Modified: paparazzi3/trunk/sw/airborne/arm7/i2c_hw.c
===================================================================
--- paparazzi3/trunk/sw/airborne/arm7/i2c_hw.c  2010-09-03 11:59:41 UTC (rev 
5796)
+++ paparazzi3/trunk/sw/airborne/arm7/i2c_hw.c  2010-09-03 14:24:35 UTC (rev 
5797)
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *  
- * Copyright (C) 2008  Pascal Brisset, Antoine Drouin
+ * Copyright (C) 2010 The Paparazzi Team
  *
  * This file is part of paparazzi.
  *
@@ -32,6 +32,142 @@
 #include "interrupt_hw.h"
 
 
+///////////////////
+// I2C Automaton //
+///////////////////
+
+static inline void I2cSendStart(struct i2c_periph* p) {
+  p->status = I2CStartRequested;
+  ((i2cRegs_t *)(p->reg_addr))->conset = _BV(STA);
+}
+
+static inline void I2cSendAck(void* reg) {
+  ((i2cRegs_t *)reg)->conset = _BV(AA);
+}
+
+static inline void I2cEndOfTransaction(struct i2c_periph* p) {
+  // handle fifo here
+  p->trans_extract_idx++;
+  if (p->trans_extract_idx >= I2C_TRANSACTION_QUEUE_LEN)
+    p->trans_extract_idx = 0;
+  // if no more transaction to process, stop here, else start next transaction
+  if (p->trans_extract_idx == p->trans_insert_idx) {
+    p->status = I2CIdle;
+  }
+  else {
+    I2cSendStart(p);
+  }
+}
+
+static inline void I2cFinished(struct i2c_periph* p, struct i2c_transaction* 
t) {
+  // transaction finished with success
+  t->status = I2CTransSuccess;
+  I2cEndOfTransaction(p);
+}
+
+static inline void I2cSendStop(struct i2c_periph* p, struct i2c_transaction* 
t) {
+  ((i2cRegs_t *)(p->reg_addr))->conset = _BV(STO);
+  I2cFinished(p,t); 
+}
+
+static inline void I2cFail(struct i2c_periph* p, struct i2c_transaction* t) {
+  ((i2cRegs_t *)(p->reg_addr))->conset = _BV(STO);
+  t->status = I2CTransFailed;
+  p->status = I2CFailed;
+  // FIXME I2C should be reseted here
+  I2cEndOfTransaction(p);
+}
+
+static inline void I2cSendByte(void* reg, uint8_t b) {
+  ((i2cRegs_t *)reg)->dat = b;
+}
+
+static inline void I2cReceive(void* reg, bool_t ack) {
+  if (ack) ((i2cRegs_t *)reg)->conset = _BV(AA);
+  else ((i2cRegs_t *)reg)->conclr = _BV(AAC);
+}
+
+static inline void I2cClearStart(void* reg) {
+  ((i2cRegs_t *)reg)->conclr = _BV(STAC);
+}
+
+static inline void I2cClearIT(void* reg) {
+  ((i2cRegs_t *)reg)->conclr = _BV(SIC);
+}
+
+static inline void I2cAutomaton(int32_t state, struct i2c_periph* p) {
+  struct i2c_transaction* trans = p->trans[p->trans_extract_idx];
+  switch (state) {
+    case I2C_START:
+    case I2C_RESTART:
+      // Set R/W flag
+      switch (trans->type) {
+        case I2CTransRx :
+          SetBit(trans->slave_addr,0);
+          break;
+        case I2CTransTx: 
+        case I2CTransTxRx: 
+          ClearBit(trans->slave_addr,0);
+          break;
+      }
+      I2cSendByte(p->reg_addr,trans->slave_addr);
+      I2cClearStart(p->reg_addr);
+      p->idx_buf = 0;
+      break;
+    case I2C_MR_DATA_ACK:
+      if (p->idx_buf < trans->len_r) {
+        trans->buf[p->idx_buf] = ((i2cRegs_t *)(p->reg_addr))->dat;
+        p->idx_buf++;
+        I2cReceive(p->reg_addr,p->idx_buf < trans->len_r - 1);
+      }
+      else {
+        /* error , we should have got NACK */
+        I2cSendStop(p,trans);
+      }
+      break;
+    case I2C_MR_SLA_ACK: /* At least one char */
+      /* Wait and reply with ACK or NACK */
+      I2cReceive(p->reg_addr,p->idx_buf < trans->len_r - 1);
+      break;
+    case I2C_MR_SLA_NACK:
+    case I2C_MT_SLA_NACK:
+      I2cSendStart(p);
+      break;
+    case I2C_MT_SLA_ACK:
+    case I2C_MT_DATA_ACK:
+      if (p->idx_buf < trans->len_w) {
+        I2cSendByte(p->reg_addr,trans->buf[p->idx_buf]);
+        p->idx_buf++;
+      } else {
+        if (trans->type == I2CTransTxRx) {
+          trans->type = I2CTransRx;    /* FIXME should not change type */
+          p->idx_buf = 0;
+          trans->slave_addr |= 1;
+          I2cSendStart(p);
+        } else {
+          if (trans->stop_after_transmit) {
+            I2cSendStop(p,trans);
+          } else {
+            I2cFinished(p,trans);
+          }
+        }
+      }
+      break;
+    case I2C_MR_DATA_NACK:
+      if (p->idx_buf < trans->len_r) {
+        trans->buf[p->idx_buf] = ((i2cRegs_t *)(p->reg_addr))->dat;
+      }
+      I2cSendStop(p,trans);
+      break;
+    default:
+      I2cSendStop(p,trans);
+      //I2cFail(p,trans);
+      /* FIXME log error */
+      break;
+  }
+}
+
+
 #ifdef USE_I2C0
 
 /* default clock speed 37.5KHz with our 15MHz PCLK 
@@ -189,3 +325,109 @@
 
 #endif /* USE_I2C1 */
 
+#ifdef USE_I2C2
+
+
+/* default clock speed 37.5KHz with our 15MHz PCLK 
+   I2C0_CLOCK = PCLK / (I2C0_SCLL + I2C0_SCLH)     */
+#ifndef I2C0_SCLL
+#define I2C0_SCLL 200
+#endif
+
+#ifndef I2C0_SCLH
+#define I2C0_SCLH 200
+#endif
+
+/* adjust for other PCLKs */
+
+#if (PCLK == 15000000)
+#define I2C0_SCLL_D I2C0_SCLL
+#define I2C0_SCLH_D I2C0_SCLH
+#else
+
+#if (PCLK == 30000000)
+#define I2C0_SCLL_D (2*I2C0_SCLL)
+#define I2C0_SCLH_D (2*I2C0_SCLH)
+#else
+
+#if (PCLK == 60000000)
+#define I2C0_SCLL_D (4*I2C0_SCLL)
+#define I2C0_SCLH_D (4*I2C0_SCLH)
+#else
+
+#error unknown PCLK frequency
+#endif
+#endif
+#endif
+
+#ifndef I2C0_VIC_SLOT
+#define I2C0_VIC_SLOT 9
+#endif
+
+void i2c0_ISR(void) __attribute__((naked));
+
+
+/* SDA0 on P0.3 */
+/* SCL0 on P0.2 */
+void i2c2_hw_init ( void ) {
+
+  i2c2.reg_addr = I2C0;
+
+  /* set P0.2 and P0.3 to I2C0 */
+  PINSEL0 |= 1 << 4 | 1 << 6;
+  /* clear all flags */
+  I2C0CONCLR = _BV(AAC) | _BV(SIC) | _BV(STAC) | _BV(I2ENC);
+  /* enable I2C */
+  I2C0CONSET = _BV(I2EN);
+  /* set bitrate */
+  I2C0SCLL = I2C0_SCLL_D;  
+  I2C0SCLH = I2C0_SCLH_D;  
+  
+  // initialize the interrupt vector
+  VICIntSelect &= ~VIC_BIT(VIC_I2C0);              // I2C0 selected as IRQ
+  VICIntEnable = VIC_BIT(VIC_I2C0);                // I2C0 interrupt enabled
+  _VIC_CNTL(I2C0_VIC_SLOT) = VIC_ENABLE | VIC_I2C0;
+  _VIC_ADDR(I2C0_VIC_SLOT) = (uint32_t)i2c0_ISR;    // address of the ISR
+}
+
+#define I2C_STATUS_REG I2C0STAT
+
+void i2c0_ISR(void)
+{
+  ISR_ENTRY();
+
+  uint32_t state = I2C_STATUS_REG;
+  I2cAutomaton(state,&i2c2);
+  I2cClearIT(i2c2.reg_addr);
+  
+  VICVectAddr = 0x00000000;             // clear this interrupt from the VIC
+  ISR_EXIT();                           // recover registers and return
+}
+
+
+bool_t i2c_submit(struct i2c_periph* p, struct i2c_transaction* t) {
+
+  uint8_t idx;
+  idx = p->trans_insert_idx + 1;
+  if (idx >= I2C_TRANSACTION_QUEUE_LEN) idx = 0;
+  if (idx == p->trans_extract_idx)
+    return FALSE;                          // queue full
+
+  t->status = I2CTransPending;
+
+  // disable irq
+  int_disable();
+  p->trans[p->trans_insert_idx] = t;
+  p->trans_insert_idx = idx;
+  /* if peripheral is idle, start the transaction */
+  if (p->status == I2CIdle)
+    I2cSendStart(p);
+  /* else it will be started by the interrupt handler when the previous 
transactions completes */
+  // enable irq
+  int_enable();
+  return TRUE;
+}
+
+#endif /* USE_I2C2 */
+
+

Modified: paparazzi3/trunk/sw/airborne/arm7/i2c_hw.h
===================================================================
--- paparazzi3/trunk/sw/airborne/arm7/i2c_hw.h  2010-09-03 11:59:41 UTC (rev 
5796)
+++ paparazzi3/trunk/sw/airborne/arm7/i2c_hw.h  2010-09-03 14:24:35 UTC (rev 
5797)
@@ -199,29 +199,8 @@
 
 #ifdef USE_I2C2
 
+extern void i2c2_hw_init(void);
 
-extern void i2c0_hw_init(void);
-
-#define I2c0SendAck()   { I2C0CONSET = _BV(AA); }
-#define I2c0Finished()  {                                               \
-    if (i2c0_finished) *i2c0_finished = TRUE;                          \
-    i2c0_status = I2C_IDLE;                                            \
-}
-#define I2c0SendStop()  {                                              \
-    I2C0CONSET = _BV(STO);                                             \
-    I2c0Finished();                                                     \
-  }
-#define I2c0SendStart() { I2C0CONSET = _BV(STA); }
-#define I2c0SendByte(b) { I2C_DATA_REG = b; }
-
-#define I2c0Receive(_ack) {        \
-    if (_ack) I2C0CONSET = _BV(AA); \
-    else I2C0CONCLR = _BV(AAC);            \
-  }
-
-#define I2c0ClearStart() { I2C0CONCLR = _BV(STAC); }
-#define I2c0ClearIT() { I2C0CONCLR = _BV(SIC); }
-
 #endif
 
 #endif /* I2C_HW_H */

Modified: paparazzi3/trunk/sw/airborne/i2c.h
===================================================================
--- paparazzi3/trunk/sw/airborne/i2c.h  2010-09-03 11:59:41 UTC (rev 5796)
+++ paparazzi3/trunk/sw/airborne/i2c.h  2010-09-03 14:24:35 UTC (rev 5797)
@@ -15,7 +15,8 @@
   I2CTransPending, 
   I2CTransRunning, 
   I2CTransSuccess, 
-  I2CTransFailed
+  I2CTransFailed,
+  I2CTransDone
 };
 
 enum I2CStatus { 
@@ -145,4 +146,41 @@
 extern void   i2c_init(struct i2c_periph* p);
 extern bool_t i2c_submit(struct i2c_periph* p, struct i2c_transaction* t);
 
+#define I2CReceive(_p, _t, _s_addr, _len) { \
+  _t.type = I2CTransRx; \
+  _t.slave_addr = _s_addr; \
+  _t.len_r = _len; \
+  _t.len_w = 0; \
+  _t.stop_after_transmit = TRUE; \
+  i2c_submit(&(_p),&(_t)); \
+}
+
+#define I2CTransmit(_p, _t, _s_addr, _len) { \
+  _t.type = I2CTransTx; \
+  _t.slave_addr = _s_addr; \
+  _t.len_r = 0; \
+  _t.len_w = _len; \
+  _t.stop_after_transmit = TRUE; \
+  i2c_submit(&(_p),&(_t)); \
+}
+
+#define I2CTransmitNoStop(_p, _t, _s_addr, _len) { \
+  _t.type = I2CTransTx; \
+  _t.slave_addr = _s_addr; \
+  _t.len_r = 0; \
+  _t.len_w = _len; \
+  _t.stop_after_transmit = FALSE; \
+  i2c_submit(&(_p),&(_t)); \
+}
+
+#define I2CTransceive(_p, _t, _s_addr, _len_w, _len_r) { \
+  _t.type = I2CTransTxRx; \
+  _t.slave_addr = _s_addr; \
+  _t.len_r = _len_r; \
+  _t.len_w = _len_w; \
+  _t.stop_after_transmit = TRUE; \
+  i2c_submit(&(_p),&(_t)); \
+}
+
+
 #endif /* I2C_H */

Modified: paparazzi3/trunk/sw/airborne/main_ap.c
===================================================================
--- paparazzi3/trunk/sw/airborne/main_ap.c      2010-09-03 11:59:41 UTC (rev 
5796)
+++ paparazzi3/trunk/sw/airborne/main_ap.c      2010-09-03 14:24:35 UTC (rev 
5797)
@@ -79,7 +79,7 @@
 #include "srf08.h"
 #endif
 
-#if defined USE_I2C0 || USE_I2C1
+#if defined USE_I2C0 || USE_I2C1 || USE_I2C2
 #include "i2c.h"
 #endif
 
@@ -741,6 +741,10 @@
   i2c1_init();
 #endif
 
+#ifdef USE_I2C2
+  i2c2_init();
+#endif
+
 #ifdef USE_AIRSPEED_ETS
   airspeed_ets_init();
 #endif

Modified: paparazzi3/trunk/sw/airborne/modules/sensors/infrared_i2c.c
===================================================================
--- paparazzi3/trunk/sw/airborne/modules/sensors/infrared_i2c.c 2010-09-03 
11:59:41 UTC (rev 5796)
+++ paparazzi3/trunk/sw/airborne/modules/sensors/infrared_i2c.c 2010-09-03 
14:24:35 UTC (rev 5797)
@@ -21,7 +21,6 @@
  */
 
 #include "sensors/infrared_i2c.h"
-#include "i2c.h"
 #include "estimator.h"
 
 // IR I2C definitions
@@ -34,15 +33,6 @@
 #define IR_HOR_I2C_SELECT_IR1 (0 << 5)
 #define IR_HOR_I2C_SELECT_IR2 (1 << 5)
 
-#define IR_I2C_IDLE             0
-#define IR_I2C_READ_IR1         1
-#define IR_I2C_IR2_SELECTED     2
-#define IR_I2C_READ_TOP         3
-#define IR_I2C_READ_IR2         4
-#define IR_I2C_IR1_SELECTED     5
-#define IR_I2C_CONFIGURE_HOR    6
-#define IR_I2C_CONFIGURE_VER    7
-
 #ifndef IR_I2C_IR1_NEUTRAL
 #define IR_I2C_IR1_NEUTRAL 0
 #endif
@@ -138,28 +128,39 @@
 
 float ir_i2c_phi, ir_i2c_theta;
 
-volatile bool_t ir_i2c_done;
 bool_t ir_i2c_data_available;
 uint8_t ir_i2c_conf_word;
-bool_t ir_i2c_conf_done;
+bool_t ir_i2c_conf_hor_done, ir_i2c_conf_ver_done;
 
 // Local variables
-static uint8_t ir_i2c_status;
+#define IR_I2C_IDLE             0
+#define IR_I2C_READ_IR1         1
+#define IR_I2C_IR2_SELECTED     2
+#define IR_I2C_READ_IR2         3
+#define IR_I2C_IR1_SELECTED     4
+#define IR_I2C_CONFIGURE_HOR    5
 
+static uint8_t ir_i2c_hor_status;
+
 #define NO_CONF_WORD 0xff
 #define ValidConfWord(_x) (_x < 0x4)
 
+// I2C structure
+struct i2c_transaction irh_trans, irv_trans;
+
 //FIXME standard infrared should not ba ADC-dependent
 void ir_init(void) {}
 
 /** Initialisation
  */
 void infrared_i2c_init( void ) {
-  ir_i2c_done = TRUE;
   ir_i2c_data_available = FALSE;
-  ir_i2c_status = IR_I2C_IDLE;
+  ir_i2c_hor_status = IR_I2C_IDLE;
   ir_i2c_conf_word = IR_I2C_DEFAULT_CONF;
-  ir_i2c_conf_done = FALSE;
+  ir_i2c_conf_hor_done = FALSE;
+  ir_i2c_conf_ver_done = FALSE;
+  irh_trans.status = I2CTransDone;
+  irv_trans.status = I2CTransDone;
 
   // Initialisation of standard infrared interface
   ir_roll_neutral  = RadOfDeg(IR_ROLL_NEUTRAL_DEFAULT);
@@ -175,102 +176,107 @@
   ir_vertical_correction = IR_VERTICAL_CORRECTION;
 }
 
+#include "led.h"
 void infrared_i2c_update( void ) {
 #if ! (defined SITL || defined HITL)
-  if (ir_i2c_done && ir_i2c_status == IR_I2C_IDLE) {
-    if (ValidConfWord(ir_i2c_conf_word) && !ir_i2c_conf_done) {
-      i2c0_buf[0] = 0;
-      i2c0_buf[0] = ir_i2c_conf_word | IR_HOR_OC_BIT | IR_START_CONV;
-      i2c0_transmit(IR_HOR_I2C_ADDR, 1, &ir_i2c_done);
-      ir_i2c_done = FALSE;
-      ir_i2c_status = IR_I2C_CONFIGURE_HOR;
+  // IR horizontal
+  if (irh_trans.status == I2CTransDone && ir_i2c_hor_status == IR_I2C_IDLE) {
+    if (ValidConfWord(ir_i2c_conf_word) && !ir_i2c_conf_hor_done) {
+      irh_trans.buf[0] = ir_i2c_conf_word | IR_HOR_OC_BIT | IR_START_CONV ;
+      I2CTransmit(i2c2, irh_trans, IR_HOR_I2C_ADDR, 1);
+      ir_i2c_hor_status = IR_I2C_CONFIGURE_HOR;
     } else {
       // Read next values
-      i2c0_receive(IR_HOR_I2C_ADDR, 3, &ir_i2c_done);
-      ir_i2c_done = FALSE;
+      I2CReceive(i2c2, irh_trans, IR_HOR_I2C_ADDR, 3);
       ir_i2c_data_available = FALSE;
-      ir_i2c_status = IR_I2C_READ_IR1;
+      ir_i2c_hor_status = IR_I2C_READ_IR1;
     }
   }
+  // IR vertical
+  if (irv_trans.status == I2CTransDone) {
+    if (ValidConfWord(ir_i2c_conf_word) && !ir_i2c_conf_ver_done) {
+      irv_trans.buf[0] = ir_i2c_conf_word | IR_VER_OC_BIT;
+      I2CTransmit(i2c2, irv_trans, IR_VER_I2C_ADDR, 1);
+    } else {
+      // Read next values
+      I2CReceive(i2c2, irv_trans, IR_VER_I2C_ADDR, 2);
+      ir_i2c_data_available = FALSE;
+    }
+  }
 #else /* SITL || HITL */
 /** ir_roll and ir_pitch set by simulator in sim_ir.c */
   estimator_update_state_infrared();
 #endif
 }
 
-void infrared_i2c_event( void ) {
+void infrared_i2c_hor_event( void ) {
 #if ! (defined SITL || defined HITL)
-  switch (ir_i2c_status) {
+  irh_trans.status = I2CTransDone;
+  switch (ir_i2c_hor_status) {
     case IR_I2C_IDLE :
       break;
     case IR_I2C_READ_IR1 :
-      if (bit_is_set(i2c0_buf[2],7)) {
-        i2c0_receive(IR_HOR_I2C_ADDR, 3, &ir_i2c_done);
-        ir_i2c_done = FALSE;
+      if (bit_is_set(irh_trans.buf[2],7)) {
+        I2CReceive(i2c2, irh_trans, IR_HOR_I2C_ADDR, 3);
         break;
       }
       // Read IR1 value
-      ir_i2c_ir1 = (i2c0_buf[0]<<8) | i2c0_buf[1];
+      ir_i2c_ir1 = (irh_trans.buf[0]<<8) | irh_trans.buf[1];
       // Select IR2 channel
-      i2c0_buf[0] = 0;
-      i2c0_buf[0] = IR_HOR_I2C_SELECT_IR2 | IR_HOR_OC_BIT | ir_i2c_conf_word | 
IR_START_CONV;
-      i2c0_transmit(IR_HOR_I2C_ADDR, 1, &ir_i2c_done);
-      ir_i2c_done = FALSE;
-      ir_i2c_status = IR_I2C_IR2_SELECTED;
+      irh_trans.buf[0] = IR_HOR_I2C_SELECT_IR2 | IR_HOR_OC_BIT | 
ir_i2c_conf_word | IR_START_CONV;
+      I2CTransmit(i2c2, irh_trans, IR_HOR_I2C_ADDR, 1);
+      ir_i2c_hor_status = IR_I2C_IR2_SELECTED;
       break;
     case IR_I2C_IR2_SELECTED :
-      // IR2 selected, asking for TOP value
-      i2c0_receive(IR_VER_I2C_ADDR, 2, &ir_i2c_done);
-      ir_i2c_done = FALSE;
-      ir_i2c_status = IR_I2C_READ_TOP;
+      // IR2 selected, asking for IR2 value
+      I2CReceive(i2c2, irh_trans, IR_HOR_I2C_ADDR, 3);
+      ir_i2c_hor_status = IR_I2C_READ_IR2;
       break;
-    case IR_I2C_READ_TOP :
-      // Read TOP value
-      ir_i2c_top = (i2c0_buf[0]<<8) | i2c0_buf[1];
-      // Asking for IR2 value
-      i2c0_receive(IR_HOR_I2C_ADDR, 3, &ir_i2c_done);
-      ir_i2c_done = FALSE;
-      ir_i2c_status = IR_I2C_READ_IR2;
-      break;
     case IR_I2C_READ_IR2 :
       // Read IR2 value
-      if (bit_is_set(i2c0_buf[2],7)) {
-        i2c0_receive(IR_HOR_I2C_ADDR, 3, &ir_i2c_done);
-        ir_i2c_done = FALSE;
+      if (bit_is_set(irh_trans.buf[2],7)) {
+        I2CReceive(i2c2, irh_trans, IR_HOR_I2C_ADDR, 3);
         break;
       }
-      ir_i2c_ir2 = (i2c0_buf[0]<<8) | i2c0_buf[1];
+      ir_i2c_ir2 = (irh_trans.buf[0]<<8) | irh_trans.buf[1];
+      // Update estimator
       ir_i2c_data_available = TRUE;
+      ir_update();
+      estimator_update_state_infrared();
       // Select IR1 channel
-      i2c0_buf[0] = 0;
-      i2c0_buf[0] = IR_HOR_I2C_SELECT_IR1 | IR_HOR_OC_BIT | ir_i2c_conf_word | 
IR_START_CONV;
-      i2c0_transmit(IR_HOR_I2C_ADDR, 1, &ir_i2c_done);
-      ir_i2c_done = FALSE;
-      ir_i2c_status = IR_I2C_IR1_SELECTED;
+      irh_trans.buf[0] = IR_HOR_I2C_SELECT_IR1 | IR_HOR_OC_BIT | 
ir_i2c_conf_word | IR_START_CONV;
+      I2CTransmit(i2c2, irh_trans, IR_HOR_I2C_ADDR, 1);
+      ir_i2c_hor_status = IR_I2C_IR1_SELECTED;
       break;
     case IR_I2C_IR1_SELECTED :
       // End reading cycle
-      ir_update();
-      estimator_update_state_infrared();
-      ir_i2c_status = IR_I2C_IDLE;
+      ir_i2c_hor_status = IR_I2C_IDLE;
       break;
     case IR_I2C_CONFIGURE_HOR :
-      // HOR configured, now configuring TOP
-      i2c0_buf[0] = 0;
-      i2c0_buf[0] = ir_i2c_conf_word | IR_VER_OC_BIT;
-      i2c0_transmit(IR_VER_I2C_ADDR, 1, &ir_i2c_done);
-      ir_i2c_done = FALSE;
-      ir_i2c_status = IR_I2C_CONFIGURE_VER;
+      // End conf cycle
+      ir_i2c_conf_hor_done = TRUE;
+      ir_i2c_hor_status = IR_I2C_IDLE;
       break;
-    case IR_I2C_CONFIGURE_VER :
-      // VER configured, end conf cycle
-      ir_i2c_conf_done = TRUE;
-      ir_i2c_status = IR_I2C_IDLE;
-      break;
   }
 #endif /* !SITL && !HITL */
 }
 
+void infrared_i2c_ver_event( void ) {
+#if ! (defined SITL || defined HITL)
+  irv_trans.status = I2CTransDone;
+  // Read TOP value
+  if (irv_trans.type == I2CTransRx) {
+    ir_i2c_top = (irv_trans.buf[0]<<8) | irv_trans.buf[1];
+    ir_i2c_data_available = TRUE;
+    ir_update();
+    estimator_update_state_infrared();
+  }
+  if (irv_trans.type == I2CTransTx) {
+    ir_i2c_conf_ver_done = TRUE;
+  }
+#endif /* !SITL && !HITL */
+}
+
 #include "stdio.h"
 
 void ir_update(void) {

Modified: paparazzi3/trunk/sw/airborne/modules/sensors/infrared_i2c.h
===================================================================
--- paparazzi3/trunk/sw/airborne/modules/sensors/infrared_i2c.h 2010-09-03 
11:59:41 UTC (rev 5796)
+++ paparazzi3/trunk/sw/airborne/modules/sensors/infrared_i2c.h 2010-09-03 
14:24:35 UTC (rev 5797)
@@ -30,6 +30,7 @@
 #include "std.h"
 #include "airframe.h"
 #include "infrared.h"
+#include "i2c.h"
 
 extern int16_t ir_i2c_ir1;
 extern int16_t ir_i2c_ir2;
@@ -37,13 +38,26 @@
 extern volatile bool_t ir_i2c_done;
 extern bool_t ir_i2c_data_available;
 extern uint8_t ir_i2c_conf_word;
+extern bool_t ir_i2c_conf_hor_done, ir_i2c_conf_ver_done;
 
+extern struct i2c_transaction irh_trans, irv_trans;
+
 extern void infrared_i2c_init( void );
 extern void infrared_i2c_update( void );
-extern void infrared_i2c_event( void );
+extern void infrared_i2c_hor_event( void );
+extern void infrared_i2c_ver_event( void );
 
-#define infrared_i2cEvent() { if (ir_i2c_done) infrared_i2c_event();   }
+#define infrared_i2cEvent() { \
+  if (irh_trans.status == I2CTransSuccess) infrared_i2c_hor_event(); \
+  if (irv_trans.status == I2CTransSuccess) infrared_i2c_ver_event(); \
+}
 
 #define infrared_i2cDownlink() DOWNLINK_SEND_DEBUG_IR_I2C(DefaultChannel, 
&ir_i2c_ir1, &ir_i2c_ir2, &ir_i2c_top)
 
+#define infrared_i2c_SetConfWord(_v) { \
+  ir_i2c_conf_hor_done = FALSE; \
+  ir_i2c_conf_ver_done = FALSE; \
+  ir_i2c_conf_word = _v; \
+}
+
 #endif // INFRARED_I2C_H




reply via email to

[Prev in Thread] Current Thread [Next in Thread]