paparazzi-commits
[Top][All Lists]
Advanced

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

[paparazzi-commits] [5415] new code for I2C2 - still doesn't work, but w


From: antoine drouin
Subject: [paparazzi-commits] [5415] new code for I2C2 - still doesn't work, but works better than before
Date: Tue, 17 Aug 2010 13:30:51 +0000

Revision: 5415
          http://svn.sv.gnu.org/viewvc/?view=rev&root=paparazzi&revision=5415
Author:   poine
Date:     2010-08-17 13:30:51 +0000 (Tue, 17 Aug 2010)
Log Message:
-----------
new code for I2C2 - still doesn't work, but works better than before

Modified Paths:
--------------
    paparazzi3/trunk/sw/airborne/stm32/i2c_hw.c

Modified: paparazzi3/trunk/sw/airborne/stm32/i2c_hw.c
===================================================================
--- paparazzi3/trunk/sw/airborne/stm32/i2c_hw.c 2010-08-17 13:08:43 UTC (rev 
5414)
+++ paparazzi3/trunk/sw/airborne/stm32/i2c_hw.c 2010-08-17 13:30:51 UTC (rev 
5415)
@@ -7,13 +7,25 @@
 
 #include "led.h"
 
+#define ZEROS_ERR_COUNTER(_i2c) {              \
+    _i2c.ack_fail_cnt = 0;                     \
+    _i2c.miss_start_stop_cnt = 0;              \
+    _i2c.arb_lost_cnt = 0;                     \
+    _i2c.over_under_cnt = 0;                   \
+    _i2c.pec_recep_cnt = 0;                    \
+    _i2c.timeout_tlow_cnt = 0;                 \
+    _i2c.smbus_alert_cnt = 0;                  \
+    _i2c.unexpected_event_cnt = 0;             \
+    _i2c.last_unexpected_event = 0;            \
+    _i2c.er_irq_cnt = 0;                       \
+  }
+
+
 #ifdef USE_I2C1
 
-#define I2C_TRANSMITTER             0x00
-#define I2C_RECEIVER                0x01
-static const uint8_t i2c2_direction = I2C_TRANSMITTER;
+struct i2c_errors i2c1_errors;
 
-//#include "my_debug_servo.h"
+#include "my_debug_servo.h"
 
 #define I2C1_APPLY_CONFIG() {                                          \
                                                                        \
@@ -41,15 +53,20 @@
                                                                        \
   }
 
-uint16_t i2c_errc_ack_fail = 0;
-uint16_t i2c_errc_miss_start_stop = 0;
-uint16_t i2c_errc_arb_lost = 0;
-uint16_t i2c_errc_over_under = 0;
-uint16_t i2c_errc_pec_recep = 0;
-uint16_t i2c_errc_timeout_tlow = 0;
-uint16_t i2c_errc_smbus_alert = 0;
+//
+// I2C1 base 0x40005400
+//
+//   I2C1 CR1 0x40005400
+//   I2C1 CR2 0x40005404
+//
+// I2C2 base 0x40005800
+//
 
+
 void i2c1_hw_init(void) {
+
+  /* zeros error counter */
+  ZEROS_ERR_COUNTER(i2c1_errors);
   
   I2C_DeInit(I2C1);
     
@@ -94,17 +111,16 @@
   /* Enable I2C1 error interrupts */
   I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);
 
- 
 }
 
 
 void i2c1_ev_irq_handler(void) {
-  //  DEBUG_S4_TOGGLE();
+
   uint32_t event = I2C_GetLastEvent(I2C1);
   switch (event) {
     /* EV5 */
   case I2C_EVENT_MASTER_MODE_SELECT:        
-    if(i2c2_direction == I2C_TRANSMITTER) {
+    if (i2c1.transaction == I2CTransTx || i2c1.transaction == I2CTransTxRx) {
       /* Master Transmitter : Send slave Address for write */
       I2C_Send7bitAddress(I2C1, (i2c1_slave_addr&0xFE), 
I2C_Direction_Transmitter);
     }
@@ -155,46 +171,10 @@
       //      while (I2C_GetFlagStatus(I2C1, I2C_FLAG_MSL));
       //      I2c1StopHandler();
     break;
-#if 0
-    /* Master Receiver 
-------------------------------------------------------*/
-    /* EV6 */
-  case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED:
-    break;
-    
-    /* Test on I2C1 EV7 and clear it */
-  case I2C_EVENT_MASTER_BYTE_RECEIVED:
-    break;
-    
-    /* EV1 */
-  case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:        /* TRA, BUSY, TXE 
and ADDR flags */
-  case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:           /* BUSY and ADDR 
flags */
-  case I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED:  /* DUALF, TRA, BUSY 
and TXE flags */
-  case I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED:     /* DUALF and BUSY 
flags */
-  case I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED:         /* GENCALL and BUSY 
flags */
-    //    DEBUG_S3_TOGGLE();
-    break;
-    
-    /* EV2 */
-  case I2C_EVENT_SLAVE_BYTE_RECEIVED:                      /* BUSY and RXNE 
flags */
-    break;
-    
-    /* EV3 */
-  case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:                   /* TRA, BUSY, TXE 
and BTF flags */
-    break;
 
-    /* EV4 */
-  case I2C_EVENT_SLAVE_STOP_DETECTED:                      /* STOPF flag */
-    break;
-
-    /* EV9 */
-  case I2C_EVENT_MASTER_MODE_ADDRESS10:                   /* BUSY, MSL and 
ADD10 flags */
-    break;
-    
-    /* EV3_2 */
-  case I2C_EVENT_SLAVE_ACK_FAILURE:                       /* AF flag */
-    break;
-#endif /* 0 */
   default:
+    i2c1_errors.unexpected_event_cnt++;
+    i2c1_errors.last_unexpected_event = event;
     // spurious Interrupt
     //    DEBUG_S2_TOGGLE();
     // I have already had I2C_EVENT_SLAVE_STOP_DETECTED ( 0x10 )
@@ -204,39 +184,39 @@
     I2C1_ABORT_AND_RESET();
     break;
   }
+
 }
 
 
-
 void i2c1_er_irq_handler(void) {
   
   if (I2C_GetITStatus(I2C1, I2C_IT_AF)) {   /* Acknowledge failure */
-    i2c_errc_ack_fail++;
+    i2c1_errors.ack_fail_cnt++;
     I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
     I2C_GenerateSTOP(I2C1, ENABLE);
   }
   if (I2C_GetITStatus(I2C1, I2C_IT_BERR)) {   /* Misplaced Start or Stop 
condition */
-    i2c_errc_miss_start_stop++;
+    i2c1_errors.miss_start_stop_cnt++;
     I2C_ClearITPendingBit(I2C1, I2C_IT_BERR);
   }
   if (I2C_GetITStatus(I2C1, I2C_IT_ARLO)) {   /* Arbitration lost */
-    i2c_errc_arb_lost++;
+    i2c1_errors.arb_lost_cnt++;
     I2C_ClearITPendingBit(I2C1, I2C_IT_ARLO);
   }
   if (I2C_GetITStatus(I2C1, I2C_IT_OVR)) {    /* Overrun/Underrun */
-    i2c_errc_over_under++;
+    i2c1_errors.over_under_cnt++;
     I2C_ClearITPendingBit(I2C1, I2C_IT_OVR);
   }
   if (I2C_GetITStatus(I2C1, I2C_IT_PECERR)) { /* PEC Error in reception */
-    i2c_errc_pec_recep++;
+    i2c1_errors.pec_recep_cnt++;
     I2C_ClearITPendingBit(I2C1, I2C_IT_PECERR);
   }
   if (I2C_GetITStatus(I2C1, I2C_IT_TIMEOUT)) { /* Timeout or Tlow error */
-    i2c_errc_timeout_tlow++;
+    i2c1_errors.timeout_tlow_cnt++;
     I2C_ClearITPendingBit(I2C1, I2C_IT_TIMEOUT);
   }
   if (I2C_GetITStatus(I2C1, I2C_IT_SMBALERT)) { /* SMBus alert */
-    i2c_errc_smbus_alert++;
+    i2c1_errors.smbus_alert_cnt++;
     I2C_ClearITPendingBit(I2C1, I2C_IT_SMBALERT);
   }
   
@@ -252,6 +232,20 @@
 
 #ifdef USE_I2C2
 
+//  dec      hex
+//  196609   30001        BUSY  MSL |                 SB
+//  458882   70082    TRA BUSY  MSL | TXE       ADDR
+//  458884   70084    TRA BUSY  MSL | TXE  BTF    
+//  196609   30001        BUSY  MSL |                 SB   
+//  196610   30002        BUSY  MSL |           ADDR
+//  
+
+
+
+struct i2c_errors i2c2_errors;
+
+#include "my_debug_servo.h"
+
 #define I2C2_APPLY_CONFIG() {                                          \
                                                                        \
     I2C_InitTypeDef  I2C_InitStructure= {                              \
@@ -260,7 +254,7 @@
       .I2C_OwnAddress1 = 0x00,                                         \
       .I2C_Ack = I2C_Ack_Enable,                                       \
       .I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit,         \
-      .I2C_ClockSpeed = 400000                                         \
+      .I2C_ClockSpeed = 300000                                         \
     };                                                                 \
     I2C_Init(I2C2, &I2C_InitStructure);                                        
\
                                                                        \
@@ -269,6 +263,9 @@
 
 void i2c2_hw_init(void) {
 
+  /* zeros error counter */
+  ZEROS_ERR_COUNTER(i2c2_errors);
+  
   /* reset periphearl to default state ( sometimes not achieved on reset :(  ) 
*/
   I2C_DeInit(I2C2);
 
@@ -278,14 +275,14 @@
   /* Configure and enable I2C2 event interrupt 
--------------------------------*/
   NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
-  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
 
   /* Configure and enable I2C2 err interrupt 
----------------------------------*/
   NVIC_InitStructure.NVIC_IRQChannel = I2C2_ER_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
-  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
 
@@ -298,7 +295,7 @@
   /* Configure I2C2 pins: SCL and SDA 
-----------------------------------------*/
   GPIO_InitTypeDef GPIO_InitStructure;
   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10 | GPIO_Pin_11;
-  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
   GPIO_Init(GPIOB, &GPIO_InitStructure);
 
@@ -311,96 +308,302 @@
   /* Enable I2C2 error interrupts 
---------------------------------------------*/
   I2C_ITConfig(I2C2, I2C_IT_ERR, ENABLE);
 
+  //  DEBUG_SERVO1_INIT();
+  //  DEBUG_SERVO2_INIT();
+
 }
 
-void i2c2_ev_irq_handler(void) {
-  uint32_t event = I2C_GetLastEvent(I2C2);
-  switch (event) {
-  case I2C_EVENT_MASTER_MODE_SELECT:                 /* EV5 */
-    if(i2c2.transaction == I2CTransTx || i2c2.transaction ==  I2CTransTxRx)  
/* for TxRx, we'll swap direction */
-      I2C_Send7bitAddress(I2C2, i2c2.slave_addr, I2C_Direction_Transmitter); 
/* to Rx after Tx is done         */
-    else
+
+
+
+static inline void on_status_start_requested(uint32_t event);
+static inline void on_status_addr_wr_sent(uint32_t event);
+static inline void on_status_sending_byte(uint32_t event);
+static inline void on_status_sending_last_byte(uint32_t event);
+static inline void on_status_stop_requested(uint32_t event);
+static inline void on_status_addr_rd_sent(uint32_t event);
+static inline void on_status_reading_byte(uint32_t event);
+static inline void on_status_reading_last_byte(uint32_t event);
+static inline void on_status_restart_requested(uint32_t event);
+
+#define SPURIOUS_INTERRUPT(_status, _event) { while(1); }
+#define OUT_OF_SYNC_STATE_MACHINE(_status, _event) { while(1); }
+
+/*
+ * Start Requested
+ *
+ */
+static inline void on_status_start_requested(uint32_t event) {
+  if (event & I2C_FLAG_SB) {
+    if(i2c2.transaction == I2CTransRx) {
       I2C_Send7bitAddress(I2C2, i2c2.slave_addr, I2C_Direction_Receiver);
-    break;
-    
-    /* Master Transmitter 
-----------------------------------------------------*/
-  case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: /* Test on I2C2 EV6 and 
first EV8 and clear them */
-    /* enable empty dr if we have more than one byte to send */
-    //    if (i2c2.len_w > 1)
-    I2C_ITConfig(I2C2, I2C_IT_BUF, ENABLE);
-    I2C_SendData(I2C2, i2c2.buf[0]);        /* Send the first data */
-    i2c2.index = 1;
-    break;
-    
-    /* Test on I2C2 EV8 and clear it */
-  case I2C_EVENT_MASTER_BYTE_TRANSMITTING:  /* Without BTF, EV8 */     
-    if(i2c2.index < i2c2.len_w) {
-      I2C_SendData(I2C2, i2c2.buf[i2c2.index]);
-      i2c2.index++;
+      i2c2.status = I2CAddrRdSent;
     }
+    else {                                             
+      I2C_Send7bitAddress(I2C2, i2c2.slave_addr, I2C_Direction_Transmitter);
+      i2c2.status = I2CAddrWrSent;             
+    }                                          
+  }                                            
+  else                                 
+    SPURIOUS_INTERRUPT(I2CStartRequested, event);      
+}
+
+/*
+ * Addr WR sent 
+ *
+ */
+static inline void on_status_addr_wr_sent(uint32_t event) {
+  if ((event & I2C_FLAG_ADDR) && (event & I2C_FLAG_TRA)) {
+    I2C_SendData(I2C2, i2c2.buf[0]);
+    if (i2c2.len_w > 1) {
+      I2C_SendData(I2C2, i2c2.buf[1]);
+      i2c2.index = 2;
+      I2C_ITConfig(I2C2, I2C_IT_BUF, ENABLE);
+      i2c2.status = I2CSendingByte;
+    }
     else {
-      I2C_GenerateSTOP(I2C2, ENABLE);
-      I2C_ITConfig(I2C2, I2C_IT_BUF, DISABLE);
+      i2c2.index = 1;
+      if (i2c2.transaction == I2CTransTx) {
+       I2C_GenerateSTOP(I2C2, ENABLE); 
+       i2c2.status = I2CStopRequested;
+      }
+      else {
+       I2C_GenerateSTART(I2C2, ENABLE);
+       i2c2.status = I2CRestartRequested;
+      }
     }
-    break;
-    
-  case I2C_EVENT_MASTER_BYTE_TRANSMITTED:   /* With BTF EV8-2 */
-    if(i2c2.index < i2c2.len_w) {
+  }
+  else
+    SPURIOUS_INTERRUPT(I2CAddrWrSent, event); 
+}
+
+/*
+ * Sending Byte 
+ *
+ */
+static inline void on_status_sending_byte(uint32_t event) {
+  if (event & I2C_FLAG_TXE) {
+    if (i2c2.index < i2c2.len_w) {                         
       I2C_SendData(I2C2, i2c2.buf[i2c2.index]);
       i2c2.index++;
     }
-    else {
-      I2C_ITConfig(I2C2, I2C_IT_EVT, DISABLE);
+    else { 
+      I2C_ITConfig(I2C2, I2C_IT_BUF, DISABLE);
       if (i2c2.transaction == I2CTransTx) {
-       if (i2c2.finished)
-         *i2c2.finished = TRUE;
-       i2c2.status = I2CComplete;
-       I2c2StopHandler();
+       I2C_GenerateSTOP(I2C2, ENABLE); 
+       i2c2.status = I2CStopRequested;
       }
       else {
-       i2c2.transaction = I2CTransRx;
-       I2c2SendStart();
+       I2C_GenerateSTART(I2C2, ENABLE);
+       i2c2.status = I2CRestartRequested;
       }
     }
-    break;
+  }
+  else
+    SPURIOUS_INTERRUPT(I2CSendingByte, event); 
+}
 
-    /* Master Receiver 
--------------------------------------------------------*/
-  case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED:
-    I2C_ITConfig(I2C2, I2C_IT_BUF, ENABLE);
-    i2c2.index = 0;                         /* Points to the start of buffer   
*/
-    if(i2c2.len_r == 1) {
-      I2C_AcknowledgeConfig(I2C2, DISABLE); /* Disable I2C2 acknowledgement    
*/
-      I2C_GenerateSTOP(I2C2, ENABLE);       /* Send I2C2 STOP Condition        
*/
+#if 0
+/*
+ * Sending last byte 
+ *
+ */
+static inline void on_status_sending_last_byte(uint32_t event) {
+  if (event & I2C_FLAG_TXE) {     // should really be BTF as we're supposed to 
have disabled buf it already
+    if (i2c2.transaction == I2CTransTx) {
+      I2C_GenerateSTOP(I2C2, ENABLE);
+      i2c2.status = I2CStopRequested;
     }
     else {
-      I2C_AcknowledgeConfig(I2C2, ENABLE);
+      I2C_GenerateSTART(I2C2, ENABLE);
+      i2c2.status = I2CRestartRequested;
     }
-    break;
-    
-    /* Test on I2C2 EV7 and clear it */
-  case I2C_EVENT_MASTER_BYTE_RECEIVED:      /* Store I2C2 received data        
*/
-  case 0x40:  /* only RXNE - misses BUSY and MSL */
-    i2c2.buf[i2c2.index] = I2C_ReceiveData(I2C2);
-    i2c2.index++;
-    /* Disable ACK and send I2C2 STOP condition before receiving last byte    
*/
-    if (i2c2.index == (i2c2.len_r - 1)) {
-      I2C_AcknowledgeConfig(I2C2, DISABLE); /* Disable I2C2 acknowledgement   
*/
-      I2C_GenerateSTOP(I2C2, ENABLE);       /* Send I2C2 STOP Condition       
*/
+    //    I2C_ITConfig(I2C2, I2C_IT_BUF, DISABLE);
+  }
+  else
+    SPURIOUS_INTERRUPT(I2CSendingLastByte, event); 
+}
+#endif
+
+
+/*
+ * Stop Requested 
+ *
+ */
+static inline void on_status_stop_requested(uint32_t event) {
+  /* bummer.... */
+  if (event & I2C_FLAG_RXNE) {     
+    uint8_t read_byte =  I2C_ReceiveData(I2C2);
+    if (i2c2.index < i2c2.len_r) {                               
+      i2c2.buf[i2c2.index] = read_byte;
     }
-    else if (i2c2.index == i2c2.len_r) {
-      I2C_ITConfig(I2C2, I2C_IT_EVT, DISABLE);
-      if (i2c2.finished)
-       *i2c2.finished = TRUE;
-      i2c2.status = I2CComplete;
-      I2c2StopHandler();
+  }
+  I2C_ITConfig(I2C2, I2C_IT_EVT|I2C_IT_BUF, DISABLE);  // should only need to 
disable evt, buf already disabled
+  if (i2c2.finished) *i2c2.finished = TRUE;
+  i2c2.status = I2CComplete;
+}
+
+/*
+ * Addr RD sent 
+ *
+ */
+static inline void on_status_addr_rd_sent(uint32_t event) {
+  if ((event & I2C_FLAG_ADDR) && !(event & I2C_FLAG_TRA)) {
+    i2c2.index = 0;  
+    if(i2c2.len_r == 1) {                                         // If we're 
going to read only one byte
+      I2C_AcknowledgeConfig(I2C2, DISABLE);                       // make sure 
it's gonna be nacked 
+      I2C_GenerateSTOP(I2C2, ENABLE);                             // and 
followed by a stop
+      i2c2.status = I2CReadingLastByte;                           // and 
remember we did
     }
+    else {
+      I2C_AcknowledgeConfig(I2C2, ENABLE);                        // if it's 
more than one byte, ack it
+      I2C_ITConfig(I2C2, I2C_IT_BUF, ENABLE);
+      i2c2.status = I2CReadingByte;                               // and 
remember we did
+    }
+  }
+  else
+    SPURIOUS_INTERRUPT(I2CAddrRdSent, event); 
+}
+
+
+/*
+ * Reading byte 
+ *
+ */
+static inline void on_status_reading_byte(uint32_t event) {
+  if (event & I2C_FLAG_RXNE) {          
+    uint8_t read_byte =  I2C_ReceiveData(I2C2);
+    if (i2c2.index < i2c2.len_r) {                               
+      i2c2.buf[i2c2.index] = read_byte;
+      i2c2.index++;
+      if (i2c2.index >= i2c2.len_r-1) {                        // We're 
reading our last byte
+       I2C_AcknowledgeConfig(I2C2, DISABLE);                  // give them a 
nack once it's done
+       I2C_GenerateSTOP(I2C2, ENABLE);                        // and follow 
with a stop
+       i2c2.status = I2CStopRequested;                        // remember we 
already trigered the stop
+      }
+    } // else { something very wrong has happened }
+  }
+  else
+    SPURIOUS_INTERRUPT(I2CReadingByte, event); 
+}
+
+/*
+ * Reading last byte 
+ *
+ */
+static inline void on_status_reading_last_byte(uint32_t event) {
+  if (event & I2C_FLAG_BTF) {
+    uint8_t read_byte =  I2C_ReceiveData(I2C2);
+    i2c2.buf[i2c2.index] = read_byte;
+    I2C_GenerateSTOP(I2C2, ENABLE);
+    i2c2.status = I2CStopRequested;   
+  }
+  else if (event & I2C_FLAG_RXNE) {       // should really be BTF ?   
+    uint8_t read_byte =  I2C_ReceiveData(I2C2);
+    i2c2.buf[i2c2.index] = read_byte;
+    i2c2.status = I2CStopRequested;   
+  }
+  else
+    SPURIOUS_INTERRUPT(I2CReadingLastByte, event); 
+}
+
+/*
+ * Restart requested 
+ *
+ */
+static inline void on_status_restart_requested(uint32_t event) {
+  //  DEBUG_S6_ON();
+  if (event & I2C_FLAG_SB) {
+    //    DEBUG_S2_ON();
+    I2C_Send7bitAddress(I2C2, i2c2.slave_addr, I2C_Direction_Receiver);
+    i2c2.status = I2CAddrRdSent;
+    //    DEBUG_S2_OFF();
+  }
+  
+  if (event & I2C_FLAG_BTF) {
+    //    DEBUG_S5_ON();
+    //    DEBUG_S5_OFF();
+  }
+
+  if (event & I2C_FLAG_TXE) {
+    //    DEBUG_S3_ON();
+    //    DEBUG_S3_OFF();
+  }
+
+  //  if (event & I2C_FLAG_TXE) {
+  //    DEBUG_S2_ON();
+  //    DEBUG_S2_OFF();
+  //  }
+
+
+  //  else if (event & I2C_FLAG_TXE) {
+    //    i2c2.status = I2CReadingByte;
+  //  }
+  //  else
+  //    SPURIOUS_INTERRUPT(I2CRestartRequested, event); 
+  //  DEBUG_S6_OFF();
+}
+
+void i2c2_ev_irq_handler(void) {
+  //  DEBUG_S4_ON();
+  uint32_t event = I2C_GetLastEvent(I2C2);
+  //#if 0
+  //  if (i2c2_errors.irq_cnt < 16) {
+    i2c2_errors.event_chain[i2c2_errors.irq_cnt] = event;
+    i2c2_errors.status_chain[i2c2_errors.irq_cnt] = i2c2.status;
+    i2c2_errors.irq_cnt++;
+    //  } else { while (1);}
+    //#endif
+  switch (i2c2.status) {
+  case I2CStartRequested:
+    on_status_start_requested(event);
     break;
-    
+  case I2CAddrWrSent:
+    on_status_addr_wr_sent(event);
+    break;
+  case I2CSendingByte:
+    //    DEBUG_S4_ON();
+    on_status_sending_byte(event);
+    //    DEBUG_S4_OFF();
+    break;
+#if 0
+  case I2CSendingLastByte:
+    //    DEBUG_S5_ON();
+    on_status_sending_last_byte(event);
+    //    DEBUG_S5_OFF();
+    break;
+#endif
+  case I2CStopRequested:
+    //    DEBUG_S1_ON();
+    on_status_stop_requested(event);
+    //    DEBUG_S1_OFF();
+    break;
+  case I2CAddrRdSent:
+    on_status_addr_rd_sent(event);
+    break;
+  case I2CReadingByte:
+    //    DEBUG_S2_ON();
+    on_status_reading_byte(event);
+    //    DEBUG_S2_OFF();
+    break;
+  case I2CReadingLastByte:
+    //    DEBUG_S5_ON();
+    on_status_reading_last_byte(event);
+    //    DEBUG_S5_OFF();
+    break;
+  case I2CRestartRequested:
+    //    DEBUG_S5_ON();
+    on_status_restart_requested(event);
+    //    DEBUG_S5_OFF();
+    break;
   default:
+    OUT_OF_SYNC_STATE_MACHINE(i2c2.status, event);
     break;
   }
+  //  DEBUG_S4_OFF();
 }
 
+
 #define I2C2_ABORT_AND_RESET() {                                       \
                                                                        \
     if (i2c2.finished)                                                 \
@@ -416,37 +619,172 @@
   }
 
 void i2c2_er_irq_handler(void) {
+  //  DEBUG_S5_ON();
+  i2c2_errors.er_irq_cnt;
   if (I2C_GetITStatus(I2C2, I2C_IT_AF)) {       /* Acknowledge failure */
-    i2c2.errc_ack_fail++;
+    i2c2_errors.ack_fail_cnt++;
     I2C_ClearITPendingBit(I2C2, I2C_IT_AF);
     I2C_GenerateSTOP(I2C2, ENABLE);
   }
   if (I2C_GetITStatus(I2C2, I2C_IT_BERR)) {     /* Misplaced Start or Stop 
condition */
-    i2c2.errc_miss_start_stop++;
+    i2c2_errors.miss_start_stop_cnt++;
     I2C_ClearITPendingBit(I2C2, I2C_IT_BERR);
   }
   if (I2C_GetITStatus(I2C2, I2C_IT_ARLO)) {     /* Arbitration lost */
-    i2c2.errc_arb_lost++;
+    i2c2_errors.arb_lost_cnt++;
     I2C_ClearITPendingBit(I2C2, I2C_IT_ARLO);
+    //    I2C_AcknowledgeConfig(I2C2, DISABLE);
+    //    uint8_t dummy __attribute__ ((unused)) = I2C_ReceiveData(I2C2);
+    //    I2C_GenerateSTOP(I2C2, ENABLE);
   }
   if (I2C_GetITStatus(I2C2, I2C_IT_OVR)) {      /* Overrun/Underrun */
-    i2c2.errc_over_under++;
+    i2c2_errors.over_under_cnt++;
     I2C_ClearITPendingBit(I2C2, I2C_IT_OVR);
   }
   if (I2C_GetITStatus(I2C2, I2C_IT_PECERR)) {   /* PEC Error in reception */
-    i2c2.errc_pec_recep++;
+    i2c2_errors.pec_recep_cnt++;
     I2C_ClearITPendingBit(I2C2, I2C_IT_PECERR);
   }
   if (I2C_GetITStatus(I2C2, I2C_IT_TIMEOUT)) {  /* Timeout or Tlow error */
-    i2c2.errc_timeout_tlow++;
+    i2c2_errors.timeout_tlow_cnt++;
     I2C_ClearITPendingBit(I2C2, I2C_IT_TIMEOUT);
   }
   if (I2C_GetITStatus(I2C2, I2C_IT_SMBALERT)) { /* SMBus alert */
-    i2c2.errc_smbus_alert++;
+    i2c2_errors.smbus_alert_cnt++;
     I2C_ClearITPendingBit(I2C2, I2C_IT_SMBALERT);
   }
   
   I2C2_ABORT_AND_RESET();
+  
+  //  DEBUG_S5_OFF();
+
 }
 
+
+
+
+/* old code, left just for reference. New should do the same */
+#if 0
+
+/* disable IRQ, notifiy caller, update status */
+#define TransactionComplete() {                                \
+    I2C_ITConfig(I2C2, I2C_IT_EVT|I2C_IT_BUF, DISABLE); \
+    //    DEBUG_S1_OFF();                              \
+    if (i2c2.finished) *i2c2.finished = TRUE;          \
+    i2c2.status = I2CComplete;                         \
+    I2c2StopHandler();                                 \
+  }
+
+
+void i2c2_ev_irq_handler(void) {
+  
+  //  DEBUG_S6_ON();
+  uint32_t event = I2C_GetLastEvent(I2C2);
+
+  if (event & I2C_FLAG_RXNE) {                                    // We're 
reading
+    //    DEBUG_S2_ON();
+    uint8_t read_byte =  I2C_ReceiveData(I2C2);
+    if (i2c2.index < i2c2.len_r) {                               
+      i2c2.buf[i2c2.index] = read_byte;
+      i2c2.index++;
+    } // else { something wrong happened }
+    if (i2c2.status == I2CStopRequested) {
+      TransactionComplete();
+    }
+    else if (i2c2.index >= i2c2.len_r-1) {                        // We're 
reading our last byte
+      I2C_AcknowledgeConfig(I2C2, DISABLE);                       // give them 
a nack once it's done
+      I2C_GenerateSTOP(I2C2, ENABLE);                             // and 
follow with a stop
+      i2c2.status = I2CStopRequested;                             // remember 
we already trigered the stop
+      //      I2C_ITConfig(I2C2, I2C_IT_BUF, DISABLE);
+      //      DEBUG_S1_OFF();
+    }
+    //    DEBUG_S2_OFF();
+  }
+  else if ((event & I2C_FLAG_ADDR) && !(event & I2C_FLAG_TRA)) {  // We got an 
address flag for reading
+    //    DEBUG_S4_ON();
+    i2c2.index = 0;                                               // zero our 
buffer index
+    if(i2c2.len_r == 1) {                                         // If we're 
going to read only one byte
+      I2C_AcknowledgeConfig(I2C2, DISABLE);                       // make sure 
it's gonna be nacked 
+      I2C_GenerateSTOP(I2C2, ENABLE);                             // and 
followed by a stop
+      i2c2.status = I2CStopRequested;                             // and 
remember we did
+    }
+    else {
+      I2C_AcknowledgeConfig(I2C2, ENABLE);                        // if it's 
more than one byte, ack it
+      I2C_ITConfig(I2C2, I2C_IT_BUF, ENABLE);
+      //      DEBUG_S1_ON();
+    }
+    //    DEBUG_S4_OFF();
+  }
+  else if (event & I2C_FLAG_TXE) {                                // TX empty  
                  
+    if (i2c2.status == I2CStopRequested) {                        // last byte 
already transfered 
+      TransactionComplete();                                      //   we're 
done
+    }
+    else if (i2c2.status == I2CRestartRequested) {                // we've  
+      i2c2.status = I2CReadingByte;
+    }
+    else if (i2c2.index < i2c2.len_w) {                           // 
transfering non last byte
+      I2C_SendData(I2C2, i2c2.buf[i2c2.index]);
+      i2c2.index++;
+      if (i2c2.index >= i2c2.len_w) {
+       I2C_ITConfig(I2C2, I2C_IT_BUF, DISABLE);
+       //      DEBUG_S1_OFF();
+      }
+    }
+    else {                                                        // 
transfering last byte       
+      if (i2c2.transaction == I2CTransTx) {
+       I2C_GenerateSTOP(I2C2, ENABLE);
+       i2c2.status = I2CStopRequested;
+      }
+      else {
+       I2C_GenerateSTART(I2C2, ENABLE);
+       i2c2.status = I2CRestartRequested;
+      }
+      I2C_ITConfig(I2C2, I2C_IT_BUF, DISABLE);
+      //      DEBUG_S1_OFF();
+    }
+  }
+  else if (event & I2C_FLAG_SB) {   // start
+    //    DEBUG_S5_TOGGLE();
+    /* in case we haven't had the TXempty it yet */
+    if((i2c2.transaction == I2CTransTxRx) && (i2c2.status == 
I2CRestartRequested)) {
+      i2c2.status = I2CReadingByte;
+    }
+    if(i2c2.transaction == I2CTransRx || 
+       (i2c2.transaction == I2CTransTxRx && i2c2.status == I2CReadingByte))
+      I2C_Send7bitAddress(I2C2, i2c2.slave_addr, I2C_Direction_Receiver);
+    else
+      I2C_Send7bitAddress(I2C2, i2c2.slave_addr, I2C_Direction_Transmitter);
+  }
+  else if ((event & I2C_FLAG_BUSY) && (event & I2C_FLAG_MSL)) { /* 0x30000 
196608 */
+  }
+  else if ((event & I2C_FLAG_BUSY)) { /* 0x20000 131072 */
+  }
+  else {
+    //    DEBUG_S2_ON();
+    //    I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_BUF, DISABLE);
+    i2c2_errors.unexpected_event_cnt++;
+    i2c2_errors.last_unexpected_event = event;
+    //    while (TRUE);
+    //    I2C_AcknowledgeConfig(I2C2, DISABLE);
+    //    uint8_t dummy __attribute__ ((unused)) = I2C_ReceiveData(I2C2);
+    //    I2C_GenerateSTOP(I2C2, ENABLE);
+    //    DEBUG_S2_OFF();
+  }
+  //  DEBUG_S6_OFF();
+}
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
 #endif /* USE_I2C2 */




reply via email to

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