[Top][All Lists]
[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 */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [paparazzi-commits] [5415] new code for I2C2 - still doesn't work, but works better than before,
antoine drouin <=