Split long function. Add comments.
authorasterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Tue, 27 Jul 2010 16:13:01 +0000 (16:13 +0000)
committerasterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Tue, 27 Jul 2010 16:13:01 +0000 (16:13 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/branches/i2c@4082 38d2e660-2303-0410-9eaa-f027e97ec537

bertos/cpu/cortex-m3/drv/i2c_stm32.c

index 9807de1194fef81a0c39d16eb3d3381994ecdbca..24c3e185a437067d27db742ce5938cd1b329ae3e 100644 (file)
@@ -81,7 +81,11 @@ INLINE uint32_t get_status(struct stm32_i2c *base)
        return ((base->SR1 | (base->SR2 << 16)) & 0x00FFFFFF);
 }
 
-
+/*
+ * This fuction read the status registers of the i2c device
+ * and waint until the selec event happen. If occur one error
+ * the funtions return false.
+ */
 INLINE bool wait_event(I2c *i2c, uint32_t event)
 {
        while (true)
@@ -101,126 +105,136 @@ INLINE bool wait_event(I2c *i2c, uint32_t event)
        return true;
 }
 
-static void i2c_stm32_start(struct I2c *i2c, uint16_t slave_addr)
-{
-       i2c->hw->cached = false;
-
-       if (I2C_TEST_START(i2c->flags) == I2C_START_W)
-       {
-               /*
-                * Loop on the select write sequence: when the eeprom is busy
-                * writing previously sent data it will reply to the SLA_W
-                * control byte with a NACK.  In this case, we must
-                * keep trying until the eeprom responds with an ACK.
-                */
-               ticks_t start = timer_clock();
-               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(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_START_TIMEOUT;
-                               i2c->hw->base->CR1 |= CR1_STOP_SET;
-                               break;
-                       }
-               }
 
-       }
-       else /* (I2C_TEST_START(i2c->flags) == I2C_START_R) */
+INLINE void start_w(struct I2c *i2c, uint16_t slave_addr)
+{
+       /*
+        * Loop on the select write sequence: when the eeprom is busy
+        * writing previously sent data it will reply to the SLA_W
+        * control byte with a NACK.  In this case, we must
+        * keep trying until the eeprom responds with an ACK.
+        */
+       ticks_t start = timer_clock();
+       while (true)
        {
-               i2c->hw->base->CR1 |= CR1_START_SET;
+               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;
-                       i2c->hw->base->CR1 |= CR1_STOP_SET;
-                       return;
+                       break;
                }
 
-               i2c->hw->base->DR = (slave_addr | OAR1_ADD0_SET);
+               i2c->hw->base->DR = slave_addr & OAR1_ADD0_RESET;
 
-               if (i2c->xfer_size == 2)
-                       i2c->hw->base->CR1 |= CR1_ACK_SET | CR1_POS_SET;
+               if(wait_event(i2c, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
+                       break;
 
-               if(!wait_event(i2c, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
+               if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT))
                {
-                       LOG_ERR("SLAR NACK:%08lx\n", get_status(i2c->hw->base));
-                       i2c->errors |= I2C_NO_ACK;
+                       LOG_ERR("Timeout on I2C START\n");
+                       i2c->errors |= I2C_START_TIMEOUT;
                        i2c->hw->base->CR1 |= CR1_STOP_SET;
-                       return;
+                       break;
                }
+       }
+}
 
-               if (i2c->xfer_size == 1)
-               {
-                       i2c->hw->base->CR1 &= CR1_ACK_RESET;
-
-                       cpu_flags_t irq;
-                       IRQ_SAVE_DISABLE(irq);
+INLINE bool start_and_addr(struct I2c *i2c, uint16_t slave_addr)
+{
+       i2c->hw->base->CR1 |= CR1_START_SET;
+       if(!wait_event(i2c, I2C_EVENT_MASTER_MODE_SELECT))
+       {
+               LOG_ERR("ARBIT lost\n");
+               i2c->errors |= I2C_ARB_LOST;
+               i2c->hw->base->CR1 |= CR1_STOP_SET;
+               return false;
+       }
 
-                       (void)i2c->hw->base->SR2;
+       i2c->hw->base->DR = (slave_addr | OAR1_ADD0_SET);
 
-                       if (I2C_TEST_STOP(i2c->flags) == I2C_STOP)
-                               i2c->hw->base->CR1 |= CR1_STOP_SET;
+       if (i2c->xfer_size == 2)
+               i2c->hw->base->CR1 |= CR1_ACK_SET | CR1_POS_SET;
 
-                       IRQ_RESTORE(irq);
+       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->base->CR1 |= CR1_STOP_SET;
+               return false;
+       }
 
-                       WAIT_RXNE(i2c->hw->base);
+       return true;
+}
 
-                       i2c->hw->cache[0] = i2c->hw->base->DR;
-                       i2c->hw->cached = true;
+INLINE void start_r(struct I2c *i2c, uint16_t slave_addr)
+{
+       if (!start_and_addr(i2c, slave_addr))
+               return;
+       /*
+        * Due to the hardware receive bytes from slave in automatically mode
+        * we should manage contextually all cases that we want to read one, two or more
+        * than two bytes. To comply this behaviour to our api we shoul bufferd some byte
+        * to hide all special case that needs to use this device.
+        */
+       if (i2c->xfer_size == 1)
+       {
+               i2c->hw->base->CR1 &= CR1_ACK_RESET;
 
-                       if (I2C_TEST_STOP(i2c->flags) == I2C_STOP)
-                               while (i2c->hw->base->CR1 & CR1_STOP_SET);
+               cpu_flags_t irq;
 
-                       i2c->hw->base->CR1 |= CR1_ACK_SET;
+               IRQ_SAVE_DISABLE(irq);
+               (void)i2c->hw->base->SR2;
+               if (I2C_TEST_STOP(i2c->flags) == I2C_STOP)
+                       i2c->hw->base->CR1 |= CR1_STOP_SET;
+               IRQ_RESTORE(irq);
 
-               }
-               else if (i2c->xfer_size == 2)
-               {
-                       cpu_flags_t irq;
-                       IRQ_SAVE_DISABLE(irq);
+               WAIT_RXNE(i2c->hw->base);
 
-                       (void)i2c->hw->base->SR2;
+               i2c->hw->cache[0] = i2c->hw->base->DR;
+               i2c->hw->cached = true;
 
-                       i2c->hw->base->CR1 &= CR1_ACK_RESET;
+               if (I2C_TEST_STOP(i2c->flags) == I2C_STOP)
+                       while (i2c->hw->base->CR1 & CR1_STOP_SET);
 
-                       IRQ_RESTORE(irq);
+               i2c->hw->base->CR1 |= CR1_ACK_SET;
+       }
+       else if (i2c->xfer_size == 2)
+       {
+               cpu_flags_t irq;
 
-                       WAIT_BTF(i2c->hw->base);
+               IRQ_SAVE_DISABLE(irq);
+               (void)i2c->hw->base->SR2;
+               i2c->hw->base->CR1 &= CR1_ACK_RESET;
+               IRQ_RESTORE(irq);
 
-                       IRQ_SAVE_DISABLE(irq);
+               WAIT_BTF(i2c->hw->base);
 
-                       if (I2C_TEST_STOP(i2c->flags) == I2C_STOP)
-                               i2c->hw->base->CR1 |= CR1_STOP_SET;
+               IRQ_SAVE_DISABLE(irq);
+               if (I2C_TEST_STOP(i2c->flags) == I2C_STOP)
+                       i2c->hw->base->CR1 |= CR1_STOP_SET;
+               /*
+                * We store read bytes like a fifo..
+                */
+               i2c->hw->cache[1] = i2c->hw->base->DR;
+               i2c->hw->cache[0] = i2c->hw->base->DR;
+               i2c->hw->cached = true;
+               IRQ_RESTORE(irq);
 
-                       /*
-                        * We store read bytes like a fifo..
-                        */
-                       i2c->hw->cache[1] = i2c->hw->base->DR;
-                       i2c->hw->cache[0] = i2c->hw->base->DR;
-                       i2c->hw->cached = true;
+               i2c->hw->base->CR1 &= CR1_POS_RESET;
+               i2c->hw->base->CR1 |= CR1_ACK_SET;
+       }
+}
 
-                       IRQ_RESTORE(irq);
+static void i2c_stm32_start(struct I2c *i2c, uint16_t slave_addr)
+{
+       i2c->hw->cached = false;
 
-                       i2c->hw->base->CR1 &= CR1_POS_RESET;
-                       i2c->hw->base->CR1 |= CR1_ACK_SET;
-               }
-       }
+       if (I2C_TEST_START(i2c->flags) == I2C_START_W)
+               start_w(i2c, slave_addr);
+       else /* (I2C_TEST_START(i2c->flags) == I2C_START_R) */
+               start_r(i2c, slave_addr);
 }
 
 static void i2c_stm32_put(I2c *i2c, const uint8_t data)