From 0d83749922dea610ff1a422bc3904d4c54754831 Mon Sep 17 00:00:00 2001 From: aleph Date: Thu, 9 Jun 2011 15:51:49 +0000 Subject: [PATCH 1/1] sam3 i2c: change stop function name, and read before set is not needed. Move set stop bit before reading a byte, and wait transfer bit complete when reading last byte. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4944 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cpu/cortex-m3/drv/i2c_sam3.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/bertos/cpu/cortex-m3/drv/i2c_sam3.c b/bertos/cpu/cortex-m3/drv/i2c_sam3.c index 23ebb3d2..bdd0b5ce 100644 --- a/bertos/cpu/cortex-m3/drv/i2c_sam3.c +++ b/bertos/cpu/cortex-m3/drv/i2c_sam3.c @@ -99,11 +99,11 @@ INLINE void waitXferComplete(I2c *i2c) } /* - * Send STOP condition. + * Set STOP condition bit, to send stop after next sent byte. */ -INLINE void sendStop(I2c *i2c) +INLINE void setStop(I2c *i2c) { - HWREG(i2c->hw->base + TWI_CR_OFF) |= TWI_CR_STOP; + HWREG(i2c->hw->base + TWI_CR_OFF) = TWI_CR_STOP; } /* @@ -142,7 +142,7 @@ static void i2c_sam3_putc(I2c *i2c, const uint8_t data) { LOG_ERR("i2c: write start timeout\n"); i2c->errors |= I2C_START_TIMEOUT; - sendStop(i2c); + setStop(i2c); waitXferComplete(i2c); return; } @@ -150,22 +150,24 @@ static void i2c_sam3_putc(I2c *i2c, const uint8_t data) if ((i2c->xfer_size == 1) && (I2C_TEST_STOP(i2c->flags) == I2C_STOP)) { - sendStop(i2c); + setStop(i2c); waitXferComplete(i2c); } } static uint8_t i2c_sam3_getc(I2c *i2c) { + uint8_t data; + + if ((i2c->xfer_size == 1) && (I2C_TEST_STOP(i2c->flags) == I2C_STOP)) + setStop(i2c); + if (i2c->hw->first_xtranf) { HWREG(i2c->hw->base + TWI_CR_OFF) = TWI_CR_START; i2c->hw->first_xtranf = false; } - if ((i2c->xfer_size == 1) && (I2C_TEST_STOP(i2c->flags) == I2C_STOP)) - sendStop(i2c); - if (!waitRxRdy(i2c, CONFIG_I2C_START_TIMEOUT)) { LOG_ERR("i2c: read start timeout\n"); @@ -173,7 +175,12 @@ static uint8_t i2c_sam3_getc(I2c *i2c) return 0xFF; } - return HWREG(i2c->hw->base + TWI_RHR_OFF); + data = HWREG(i2c->hw->base + TWI_RHR_OFF); + + if ((i2c->xfer_size == 1) && (I2C_TEST_STOP(i2c->flags) == I2C_STOP)) + waitXferComplete(i2c); + + return data; } static void i2c_setClock(I2c *i2c, int clock) -- 2.25.1