mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #11908 from yarbcy/pr/i2c-improvement3
I2C byte read/write transmition improvementpull/11919/head
commit
ab7f602512
|
@ -119,13 +119,18 @@ void i2c_frequency(i2c_t *obj, int hz)
|
||||||
|
|
||||||
int i2c_start(i2c_t *obj)
|
int i2c_start(i2c_t *obj)
|
||||||
{
|
{
|
||||||
// Nothing to do; start/stop is generated by i2c_read/i2c_write
|
/* start/stop is generated by i2c_read/i2c_write */
|
||||||
|
struct i2c_s *i2c = cy_get_i2c(obj);
|
||||||
|
/* Clear state of address */
|
||||||
|
i2c->address_set = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i2c_stop(i2c_t *obj)
|
int i2c_stop(i2c_t *obj)
|
||||||
{
|
{
|
||||||
struct i2c_s *i2c = cy_get_i2c(obj);
|
struct i2c_s *i2c = cy_get_i2c(obj);
|
||||||
|
/* Clear state of address */
|
||||||
|
i2c->address_set = false;
|
||||||
if (i2c->hal_i2c.context.state != CY_SCB_I2C_IDLE) {
|
if (i2c->hal_i2c.context.state != CY_SCB_I2C_IDLE) {
|
||||||
return Cy_SCB_I2C_MasterSendStop(i2c->hal_i2c.base, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context));
|
return Cy_SCB_I2C_MasterSendStop(i2c->hal_i2c.base, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context));
|
||||||
}
|
}
|
||||||
|
@ -160,19 +165,49 @@ int i2c_byte_read(i2c_t *obj, int last)
|
||||||
{
|
{
|
||||||
struct i2c_s *i2c = cy_get_i2c(obj);
|
struct i2c_s *i2c = cy_get_i2c(obj);
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
if (CY_SCB_I2C_SUCCESS != Cy_SCB_I2C_MasterReadByte(i2c->hal_i2c.base, last != 0 ? CY_SCB_I2C_NAK : CY_SCB_I2C_ACK, &value, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context))) {
|
|
||||||
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER_I2C, MBED_ERROR_CODE_FAILED_OPERATION), "i2c_byte_read");
|
/* Slave device address is stored in object by first write operation */
|
||||||
|
if (i2c->address_set) {
|
||||||
|
/* Send slave device address */
|
||||||
|
/* Make sure if I2C transaction direction is 'Read' */
|
||||||
|
if (CY_SCB_I2C_SUCCESS != Cy_SCB_I2C_MasterSendStart(i2c->hal_i2c.base, i2c->address, CY_SCB_I2C_READ_XFER, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context))) {
|
||||||
|
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER_I2C, MBED_ERROR_CODE_FAILED_OPERATION), "i2c_send_start");
|
||||||
|
}
|
||||||
|
/* Clear state of address. It is not needed for next operation. */
|
||||||
|
i2c->address_set = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read next byte */
|
||||||
|
if (CY_SCB_I2C_SUCCESS != Cy_SCB_I2C_MasterReadByte(i2c->hal_i2c.base, last != 0 ? CY_SCB_I2C_NAK : CY_SCB_I2C_ACK, &value, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context))) {
|
||||||
|
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER_I2C, MBED_ERROR_CODE_FAILED_OPERATION), "i2c_read_byte");
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i2c_byte_write(i2c_t *obj, int data)
|
int i2c_byte_write(i2c_t *obj, int data)
|
||||||
{
|
{
|
||||||
struct i2c_s *i2c = cy_get_i2c(obj);
|
struct i2c_s *i2c = cy_get_i2c(obj);
|
||||||
// If we have not yet written the address, the first byte being sent is the address.
|
cy_en_scb_i2c_status_t status = CY_SCB_I2C_SUCCESS;
|
||||||
cy_en_scb_i2c_status_t status = i2c->hal_i2c.context.state == CY_SCB_I2C_IDLE
|
|
||||||
? Cy_SCB_I2C_MasterSendStart(i2c->hal_i2c.base, data >> 1, CY_SCB_I2C_WRITE_XFER, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context))
|
/* First byte should be address */
|
||||||
: Cy_SCB_I2C_MasterWriteByte(i2c->hal_i2c.base, (uint8_t)data, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context));
|
if (i2c->address_set) {
|
||||||
|
/* Verify if Master is ready for send slave address and send first data byte */
|
||||||
|
/* Make sure that I2C transaction direction is 'Write' */
|
||||||
|
if (i2c->hal_i2c.context.state == CY_SCB_I2C_IDLE) {
|
||||||
|
status = Cy_SCB_I2C_MasterSendStart(i2c->hal_i2c.base, i2c->address, CY_SCB_I2C_WRITE_XFER, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == CY_SCB_I2C_SUCCESS) {
|
||||||
|
status = Cy_SCB_I2C_MasterWriteByte(i2c->hal_i2c.base, (uint8_t)data, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Store slave address and remember status for next byte read or write operation */
|
||||||
|
i2c->address = data >> 1;
|
||||||
|
i2c->address_set = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case CY_SCB_I2C_MASTER_MANUAL_TIMEOUT:
|
case CY_SCB_I2C_MASTER_MANUAL_TIMEOUT:
|
||||||
return 2;
|
return 2;
|
||||||
|
|
|
@ -94,6 +94,8 @@ struct i2c_s {
|
||||||
size_t async_rx_size;
|
size_t async_rx_size;
|
||||||
#endif
|
#endif
|
||||||
uint8_t slave_event;
|
uint8_t slave_event;
|
||||||
|
uint32_t address;
|
||||||
|
bool address_set;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue