From b1fde66b00840e9fb6738774e1e9bcd0b3065b1d Mon Sep 17 00:00:00 2001 From: asterix Date: Tue, 27 Jul 2010 16:13:01 +0000 Subject: [PATCH] Split long function. Add comments. 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 | 192 ++++++++++++++------------- 1 file changed, 103 insertions(+), 89 deletions(-) diff --git a/bertos/cpu/cortex-m3/drv/i2c_stm32.c b/bertos/cpu/cortex-m3/drv/i2c_stm32.c index 9807de11..24c3e185 100644 --- a/bertos/cpu/cortex-m3/drv/i2c_stm32.c +++ b/bertos/cpu/cortex-m3/drv/i2c_stm32.c @@ -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) -- 2.25.1