mbed
Fork of mbed-dev by
Diff: targets/TARGET_STM/i2c_api.c
- Revision:
- 154:37f96f9d4de2
- Parent:
- 153:fa9ff456f731
- Child:
- 156:95d6b41a828b
--- a/targets/TARGET_STM/i2c_api.c Tue Dec 20 17:27:56 2016 +0000 +++ b/targets/TARGET_STM/i2c_api.c Wed Jan 04 16:58:05 2017 +0000 @@ -38,8 +38,6 @@ #include "cmsis.h" #include "pinmap.h" #include "PeripheralPins.h" -/* F1 HAL not ready to move to I2C common code - this is ongoing */ -#if !defined(__STM32F1xx_HAL_H) #include "i2c_device.h" // family specific defines #ifndef DEBUG_STDIO @@ -442,60 +440,6 @@ return (obj); } -/* SYNCHRONOUS API FUNCTIONS */ - -int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { - struct i2c_s *obj_s = I2C_S(obj); - I2C_HandleTypeDef *handle = &(obj_s->handle); - int count = 0, ret = 0; - uint32_t timeout = 0; - - if ((obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) || - (obj_s->XferOperation == I2C_LAST_FRAME)) { - if (stop) - obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME; - else - obj_s->XferOperation = I2C_FIRST_FRAME; - } else if ((obj_s->XferOperation == I2C_FIRST_FRAME) || - (obj_s->XferOperation == I2C_NEXT_FRAME)) { - if (stop) - obj_s->XferOperation = I2C_LAST_FRAME; - else - obj_s->XferOperation = I2C_NEXT_FRAME; - } - - obj_s->event = 0; - - /* Activate default IRQ handlers for sync mode - * which would be overwritten in async mode - */ - i2c_ev_err_enable(obj, i2c_get_irq_handler(obj)); - - ret = HAL_I2C_Master_Sequential_Receive_IT(handle, address, (uint8_t *) data, length, obj_s->XferOperation); - - if(ret == HAL_OK) { - timeout = BYTE_TIMEOUT_US * length; - /* transfer started : wait completion or timeout */ - while(!(obj_s->event & I2C_EVENT_ALL) && (--timeout != 0)) { - wait_us(1); - } - - i2c_ev_err_disable(obj); - - if((timeout == 0) || (obj_s->event != I2C_EVENT_TRANSFER_COMPLETE)) { - DEBUG_PRINTF(" TIMEOUT or error in i2c_read\r\n"); - /* re-init IP to try and get back in a working state */ - i2c_init(obj, obj_s->sda, obj_s->scl); - } else { - count = length; - } - } else { - DEBUG_PRINTF("ERROR in i2c_read\r\n"); - } - - return count; -} - /* * UNITARY APIS. * For very basic operations, direct registers access is needed @@ -537,10 +481,18 @@ int i2c_stop(i2c_t *obj) { struct i2c_s *obj_s = I2C_S(obj); I2C_TypeDef *i2c = (I2C_TypeDef *)obj_s->i2c; + I2C_HandleTypeDef *handle = &(obj_s->handle); + int timeout; // Generate the STOP condition i2c->CR1 |= I2C_CR1_STOP; + /* In case of mixed usage of the APIs (unitary + SYNC) + * re-inti HAL state + */ + if(obj_s->XferOperation != I2C_FIRST_AND_LAST_FRAME) + i2c_init(obj, obj_s->sda, obj_s->scl); + return 0; } @@ -685,12 +637,78 @@ /* * SYNC APIS */ +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + struct i2c_s *obj_s = I2C_S(obj); + I2C_HandleTypeDef *handle = &(obj_s->handle); + int count = I2C_ERROR_BUS_BUSY, ret = 0; + uint32_t timeout = 0; + + if((length == 0) || (data == 0)) { + if(HAL_I2C_IsDeviceReady(handle, address, 1, 10) == HAL_OK) + return 0; + else + return I2C_ERROR_BUS_BUSY; + } + + if ((obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) || + (obj_s->XferOperation == I2C_LAST_FRAME)) { + if (stop) + obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME; + else + obj_s->XferOperation = I2C_FIRST_FRAME; + } else if ((obj_s->XferOperation == I2C_FIRST_FRAME) || + (obj_s->XferOperation == I2C_NEXT_FRAME)) { + if (stop) + obj_s->XferOperation = I2C_LAST_FRAME; + else + obj_s->XferOperation = I2C_NEXT_FRAME; + } + + obj_s->event = 0; + + /* Activate default IRQ handlers for sync mode + * which would be overwritten in async mode + */ + i2c_ev_err_enable(obj, i2c_get_irq_handler(obj)); + + ret = HAL_I2C_Master_Sequential_Receive_IT(handle, address, (uint8_t *) data, length, obj_s->XferOperation); + + if(ret == HAL_OK) { + timeout = BYTE_TIMEOUT_US * (length + 1); + /* transfer started : wait completion or timeout */ + while(!(obj_s->event & I2C_EVENT_ALL) && (--timeout != 0)) { + wait_us(1); + } + + i2c_ev_err_disable(obj); + + if((timeout == 0) || (obj_s->event != I2C_EVENT_TRANSFER_COMPLETE)) { + DEBUG_PRINTF(" TIMEOUT or error in i2c_read\r\n"); + /* re-init IP to try and get back in a working state */ + i2c_init(obj, obj_s->sda, obj_s->scl); + } else { + count = length; + } + } else { + DEBUG_PRINTF("ERROR in i2c_read:%d\r\n", ret); + } + + return count; +} + int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { struct i2c_s *obj_s = I2C_S(obj); I2C_HandleTypeDef *handle = &(obj_s->handle); - int count = 0, ret = 0; + int count = I2C_ERROR_BUS_BUSY, ret = 0; uint32_t timeout = 0; + if((length == 0) || (data == 0)) { + if(HAL_I2C_IsDeviceReady(handle, address, 1, 10) == HAL_OK) + return 0; + else + return I2C_ERROR_BUS_BUSY; + } + if ((obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) || (obj_s->XferOperation == I2C_LAST_FRAME)) { if (stop) @@ -712,7 +730,7 @@ ret = HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *) data, length, obj_s->XferOperation); if(ret == HAL_OK) { - timeout = BYTE_TIMEOUT_US * length; + timeout = BYTE_TIMEOUT_US * (length + 1); /* transfer started : wait completion or timeout */ while(!(obj_s->event & I2C_EVENT_ALL) && (--timeout != 0)) { wait_us(1); @@ -891,7 +909,7 @@ ret = HAL_I2C_Slave_Sequential_Receive_IT(handle, (uint8_t *) data, length, I2C_NEXT_FRAME); if(ret == HAL_OK) { - timeout = BYTE_TIMEOUT_US * length; + timeout = BYTE_TIMEOUT_US * (length + 1); while(obj_s->pending_slave_rx_maxter_tx && (--timeout != 0)) { wait_us(1); } @@ -916,7 +934,7 @@ ret = HAL_I2C_Slave_Sequential_Transmit_IT(handle, (uint8_t *) data, length, I2C_NEXT_FRAME); if(ret == HAL_OK) { - timeout = BYTE_TIMEOUT_US * length; + timeout = BYTE_TIMEOUT_US * (length + 1); while(obj_s->pending_slave_tx_master_rx && (--timeout != 0)) { wait_us(1); } @@ -1048,6 +1066,4 @@ #endif // DEVICE_I2C_ASYNCH -#endif // STM32F1 - #endif // DEVICE_I2C