mbed w/ spi bug fig
Fork of mbed-src by
Revision 202:bd6461c07541, committed 2014-05-21
- Comitter:
- mbed_official
- Date:
- Wed May 21 15:00:07 2014 +0100
- Parent:
- 201:fa203361dc70
- Child:
- 203:0f54f988aa69
- Commit message:
- Synchronized with git revision b94c8a221b8b7db227cfd749fb637c0ee27e986b
Full URL: https://github.com/mbedmicro/mbed/commit/b94c8a221b8b7db227cfd749fb637c0ee27e986b/
[NUCLEO_L053R8] enhance I2C master (stop) and add I2C slave
Changed in this revision
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_L053R8/device.h Wed May 21 10:30:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_L053R8/device.h Wed May 21 15:00:07 2014 +0100 @@ -42,7 +42,7 @@ #define DEVICE_SERIAL 1 #define DEVICE_I2C 1 -#define DEVICE_I2CSLAVE 0 // Not supported yet +#define DEVICE_I2CSLAVE 1 #define DEVICE_SPI 1 #define DEVICE_SPISLAVE 0 // Not supported yet
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_L053R8/i2c_api.c Wed May 21 10:30:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_L053R8/i2c_api.c Wed May 21 15:00:07 2014 +0100 @@ -154,43 +154,102 @@ } int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); + I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); + int timeout; + int count; + int value; + if (length == 0) return 0; - I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); + /* update CR2 register */ + i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP))) + | (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16 ) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_READ); + + // Read all bytes + for (count = 0; count < length; count++) { + value = i2c_byte_read(obj, 0); + data[count] = (char)value; + } - // Reception process with 5 seconds timeout - if (HAL_I2C_Master_Receive(&I2cHandle, (uint16_t)address, (uint8_t *)data, length, 5000) != HAL_OK) { - return 0; // Error + // Wait transfer complete + timeout = FLAG_TIMEOUT; + while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) { + timeout--; + if (timeout == 0) { + return 0; + } + } + __HAL_I2C_CLEAR_FLAG(&I2cHandle,I2C_FLAG_TC); + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + /* Wait until STOPF flag is set */ + timeout = FLAG_TIMEOUT; + while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) { + timeout--; + if (timeout == 0) { + return 0; + } + } + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF); } return length; } int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); + I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); + int timeout; + int count; + if (length == 0) return 0; - I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); + /* update CR2 register */ + i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP))) + | (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16 ) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_WRITE); + - // Transmission process with 5 seconds timeout - if (HAL_I2C_Master_Transmit(&I2cHandle, (uint16_t)address, (uint8_t *)data, length, 5000) != HAL_OK) { - return 0; // Error + + for (count = 0; count < length; count++) { + i2c_byte_write(obj, data[count]); } - return length; + // Wait transfer complete + timeout = FLAG_TIMEOUT; + while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) { + timeout--; + if (timeout == 0) { + return 0; + } + } + __HAL_I2C_CLEAR_FLAG(&I2cHandle,I2C_FLAG_TC); + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + /* Wait until STOPF flag is set */ + timeout = FLAG_TIMEOUT; + while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) { + timeout--; + if (timeout == 0) { + return 0; + } + } + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF); + } + + return count; } int i2c_byte_read(i2c_t *obj, int last) { I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); int timeout; - if (last) { - // Don't acknowledge the last byte - i2c->CR2 &= ~I2C_CR2_NACK; - } else { - // Acknowledge the byte - i2c->CR2 |= I2C_CR2_NACK; - } - // Wait until the byte is received timeout = FLAG_TIMEOUT; while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) { @@ -206,16 +265,16 @@ I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); int timeout; - i2c->TXDR = (uint8_t)data; - - // Wait until the byte is transmitted + // Wait until the previous byte is transmitted timeout = FLAG_TIMEOUT; - while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) { + while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXIS) == RESET) { if ((timeout--) == 0) { return 0; } } + i2c->TXDR = (uint8_t)data; + return 1; } @@ -237,7 +296,7 @@ uint16_t tmpreg; // disable - i2c->OAR1 &= (uin32_t)(~I2C_OAR1_OA1EN); + i2c->OAR1 &= (uint32_t)(~I2C_OAR1_OA1EN); // Get the old register value tmpreg = i2c->OAR1; // Reset address bits @@ -262,7 +321,7 @@ if (enable_slave == 1) { tmpreg |= I2C_OAR1_OA1EN; } else { - tmpreg &= (uin32_t)(~I2C_OAR1_OA1EN); + tmpreg &= (uint32_t)(~I2C_OAR1_OA1EN); } // Set new mode @@ -277,8 +336,7 @@ #define WriteAddressed 3 // the master is writing to this slave (slave = receiver) int i2c_slave_receive(i2c_t *obj) { - I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); - char address; + I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); int retValue = NoData; if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) { @@ -295,25 +353,21 @@ } int i2c_slave_read(i2c_t *obj, char *data, int length) { + char size = 0; + if (length == 0) return 0; - I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); + while (size < length) data[size++] = (char)i2c_byte_read(obj, 0); - // Reception process with 5 seconds timeout - if (HAL_I2C_Slave_Receive(&I2cHandle, (uint8_t *)data, length, 5000) != HAL_OK) { - return 0; // Error - } - - return length; + return size; } int i2c_slave_write(i2c_t *obj, const char *data, int length) { char size = 0; + I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); if (length == 0) return 0; - I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); - do { i2c_byte_write(obj, data[size]); size++;