Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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