From 98eb98b118f4274745b41ad99833c3f08938e60c Mon Sep 17 00:00:00 2001
From: asterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Date: Tue, 27 Jul 2010 15:45:00 +0000
Subject: [PATCH] Clean up. Use cpu_relax for while loop. Rename
 check_i2cStatus to wait_event.

git-svn-id: https://src.develer.com/svnoss/bertos/branches/i2c@4081 38d2e660-2303-0410-9eaa-f027e97ec537
---
 bertos/cpu/cortex-m3/drv/i2c_stm32.c | 84 ++++++++++++----------------
 1 file changed, 35 insertions(+), 49 deletions(-)

diff --git a/bertos/cpu/cortex-m3/drv/i2c_stm32.c b/bertos/cpu/cortex-m3/drv/i2c_stm32.c
index b48d2512..9807de11 100644
--- a/bertos/cpu/cortex-m3/drv/i2c_stm32.c
+++ b/bertos/cpu/cortex-m3/drv/i2c_stm32.c
@@ -45,6 +45,7 @@
 #include <cfg/macros.h> // BV()
 #include <cfg/module.h>
 
+#include <cpu/power.h>
 #include <drv/gpio_stm32.h>
 #include <drv/irq_cm3.h>
 #include <drv/clock_stm32.h>
@@ -63,8 +64,17 @@ struct I2cHardware
 	bool cached;
 };
 
-#define WAIT_BTF(base)        while( !(base->SR1 & BV(SR1_BTF)) )
-#define WAIT_RXNE(base)        while( !(base->SR1 & BV(SR1_RXNE)) )
+#define WAIT_BTF(base) \
+	do { \
+		while (!(base->SR1 & BV(SR1_BTF))) \
+			cpu_relax(); \
+	} while (0)
+
+#define WAIT_RXNE(base) \
+	do { \
+		while (!(base->SR1 & BV(SR1_RXNE))) \
+			cpu_relax(); \
+	} while (0)
 
 INLINE uint32_t get_status(struct stm32_i2c *base)
 {
@@ -72,7 +82,7 @@ INLINE uint32_t get_status(struct stm32_i2c *base)
 }
 
 
-INLINE bool check_i2cStatus(I2c *i2c, uint32_t event)
+INLINE bool wait_event(I2c *i2c, uint32_t event)
 {
 	while (true)
 	{
@@ -84,39 +94,13 @@ INLINE bool check_i2cStatus(I2c *i2c, uint32_t event)
 		if (stat & SR1_ERR_MASK)
 		{
 			i2c->hw->base->SR1 &= ~SR1_ERR_MASK;
-			i2c->hw->base->CR1 |= CR1_START_SET;
 			return false;
 		}
-
+		cpu_relax();
 	}
-
 	return true;
 }
 
-/**
- * Send START condition on the bus.
- *
- * \return true on success, false otherwise.
- */
-INLINE bool i2c_hw_restart(I2c *i2c)
-{
-
-	i2c->hw->base->CR1 |= CR1_ACK_SET | CR1_START_SET;
-
-	if(check_i2cStatus(i2c, I2C_EVENT_MASTER_MODE_SELECT))
-		return true;
-
-	return false;
-}
-
-/**
- * Send STOP condition.
- */
-static void i2c_hw_stop(I2c *i2c)
-{
-	i2c->hw->base->CR1 |= CR1_STOP_SET;
-}
-
 static void i2c_stm32_start(struct I2c *i2c, uint16_t slave_addr)
 {
 	i2c->hw->cached = false;
@@ -130,32 +114,41 @@ static void i2c_stm32_start(struct I2c *i2c, uint16_t slave_addr)
 		 * keep trying until the eeprom responds with an ACK.
 		 */
 		ticks_t start = timer_clock();
-		while (i2c_hw_restart(i2c))
+		while (true)
 		{
+			i2c->hw->base->CR1 |= CR1_ACK_SET | CR1_START_SET;
+
+			if(!wait_event(i2c, I2C_EVENT_MASTER_MODE_SELECT))
+			{
+				LOG_ERR("ARBIT lost\n");
+				i2c->errors |= I2C_ARB_LOST;
+				break;
+			}
+
 			i2c->hw->base->DR = slave_addr & OAR1_ADD0_RESET;
 
-			if(check_i2cStatus(i2c, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
+			if(wait_event(i2c, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
 				break;
 
 			if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT))
 			{
 				LOG_ERR("Timeout on I2C START\n");
-				i2c->errors |= I2C_NO_ACK;
-				i2c_hw_stop(i2c);
+				i2c->errors |= I2C_START_TIMEOUT;
+				i2c->hw->base->CR1 |= CR1_STOP_SET;
 				break;
 			}
 		}
 
 	}
-	else if (I2C_TEST_START(i2c->flags) == I2C_START_R)
+	else /* (I2C_TEST_START(i2c->flags) == I2C_START_R) */
 	{
 		i2c->hw->base->CR1 |= CR1_START_SET;
 
-		if(!check_i2cStatus(i2c, I2C_EVENT_MASTER_MODE_SELECT))
+		if(!wait_event(i2c, I2C_EVENT_MASTER_MODE_SELECT))
 		{
 			LOG_ERR("ARBIT lost\n");
 			i2c->errors |= I2C_ARB_LOST;
-			i2c_hw_stop(i2c);
+			i2c->hw->base->CR1 |= CR1_STOP_SET;
 			return;
 		}
 
@@ -164,15 +157,14 @@ static void i2c_stm32_start(struct I2c *i2c, uint16_t slave_addr)
 		if (i2c->xfer_size == 2)
 			i2c->hw->base->CR1 |= CR1_ACK_SET | CR1_POS_SET;
 
-		if(!check_i2cStatus(i2c, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
+		if(!wait_event(i2c, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
 		{
 			LOG_ERR("SLAR NACK:%08lx\n", get_status(i2c->hw->base));
 			i2c->errors |= I2C_NO_ACK;
-			i2c_hw_stop(i2c);
+			i2c->hw->base->CR1 |= CR1_STOP_SET;
 			return;
 		}
 
-
 		if (i2c->xfer_size == 1)
 		{
 			i2c->hw->base->CR1 &= CR1_ACK_RESET;
@@ -229,11 +221,6 @@ static void i2c_stm32_start(struct I2c *i2c, uint16_t slave_addr)
 			i2c->hw->base->CR1 |= CR1_ACK_SET;
 		}
 	}
-	else
-	{
-		ASSERT(0);
-	}
-
 }
 
 static void i2c_stm32_put(I2c *i2c, const uint8_t data)
@@ -242,12 +229,11 @@ static void i2c_stm32_put(I2c *i2c, const uint8_t data)
 
 	WAIT_BTF(i2c->hw->base);
 
-
 	/* Generate the stop if we finish to send all programmed bytes */
-	if ((i2c->xfer_size == 1) &&(I2C_TEST_STOP(i2c->flags) == I2C_STOP))
+	if ((i2c->xfer_size == 1) && (I2C_TEST_STOP(i2c->flags) == I2C_STOP))
 	{
-			check_i2cStatus(i2c, I2C_EVENT_MASTER_BYTE_TRANSMITTED);
-			i2c_hw_stop(i2c);
+			wait_event(i2c, I2C_EVENT_MASTER_BYTE_TRANSMITTED);
+			i2c->hw->base->CR1 |= CR1_STOP_SET;
 	}
 }
 
-- 
2.34.1