Skip to content

I2C byte read/write transmition improvement #11908

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 41 additions & 6 deletions targets/TARGET_Cypress/TARGET_PSOC6/cy_i2c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,18 @@ void i2c_frequency(i2c_t *obj, int hz)

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;
}

int i2c_stop(i2c_t *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) {
return Cy_SCB_I2C_MasterSendStop(i2c->hal_i2c.base, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context));
}
Expand Down Expand Up @@ -160,19 +165,49 @@ int i2c_byte_read(i2c_t *obj, int last)
{
struct i2c_s *i2c = cy_get_i2c(obj);
uint8_t value;

/* 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_byte_read");
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER_I2C, MBED_ERROR_CODE_FAILED_OPERATION), "i2c_read_byte");
}

return value;
}

int i2c_byte_write(i2c_t *obj, int data)
{
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 = 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))
: Cy_SCB_I2C_MasterWriteByte(i2c->hal_i2c.base, (uint8_t)data, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context));
cy_en_scb_i2c_status_t status = CY_SCB_I2C_SUCCESS;

/* First byte should be address */
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) {
case CY_SCB_I2C_MASTER_MANUAL_TIMEOUT:
return 2;
Expand Down
2 changes: 2 additions & 0 deletions targets/TARGET_Cypress/TARGET_PSOC6/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ struct i2c_s {
size_t async_rx_size;
#endif
uint8_t slave_event;
uint32_t address;
bool address_set;
};
#endif

Expand Down