Skip to content

Commit ab7f602

Browse files
authored
Merge pull request #11908 from yarbcy/pr/i2c-improvement3
I2C byte read/write transmition improvement
2 parents a99d9be + 3d09a5a commit ab7f602

File tree

2 files changed

+43
-6
lines changed

2 files changed

+43
-6
lines changed

targets/TARGET_Cypress/TARGET_PSOC6/cy_i2c_api.c

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,18 @@ void i2c_frequency(i2c_t *obj, int hz)
119119

120120
int i2c_start(i2c_t *obj)
121121
{
122-
// Nothing to do; start/stop is generated by i2c_read/i2c_write
122+
/* start/stop is generated by i2c_read/i2c_write */
123+
struct i2c_s *i2c = cy_get_i2c(obj);
124+
/* Clear state of address */
125+
i2c->address_set = false;
123126
return 0;
124127
}
125128

126129
int i2c_stop(i2c_t *obj)
127130
{
128131
struct i2c_s *i2c = cy_get_i2c(obj);
132+
/* Clear state of address */
133+
i2c->address_set = false;
129134
if (i2c->hal_i2c.context.state != CY_SCB_I2C_IDLE) {
130135
return Cy_SCB_I2C_MasterSendStop(i2c->hal_i2c.base, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context));
131136
}
@@ -160,19 +165,49 @@ int i2c_byte_read(i2c_t *obj, int last)
160165
{
161166
struct i2c_s *i2c = cy_get_i2c(obj);
162167
uint8_t value;
168+
169+
/* Slave device address is stored in object by first write operation */
170+
if (i2c->address_set) {
171+
/* Send slave device address */
172+
/* Make sure if I2C transaction direction is 'Read' */
173+
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))) {
174+
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER_I2C, MBED_ERROR_CODE_FAILED_OPERATION), "i2c_send_start");
175+
}
176+
/* Clear state of address. It is not needed for next operation. */
177+
i2c->address_set = false;
178+
}
179+
180+
/* Read next byte */
163181
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))) {
164-
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER_I2C, MBED_ERROR_CODE_FAILED_OPERATION), "i2c_byte_read");
182+
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER_I2C, MBED_ERROR_CODE_FAILED_OPERATION), "i2c_read_byte");
165183
}
184+
166185
return value;
167186
}
168187

169188
int i2c_byte_write(i2c_t *obj, int data)
170189
{
171190
struct i2c_s *i2c = cy_get_i2c(obj);
172-
// If we have not yet written the address, the first byte being sent is the address.
173-
cy_en_scb_i2c_status_t status = i2c->hal_i2c.context.state == CY_SCB_I2C_IDLE
174-
? Cy_SCB_I2C_MasterSendStart(i2c->hal_i2c.base, data >> 1, CY_SCB_I2C_WRITE_XFER, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context))
175-
: Cy_SCB_I2C_MasterWriteByte(i2c->hal_i2c.base, (uint8_t)data, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context));
191+
cy_en_scb_i2c_status_t status = CY_SCB_I2C_SUCCESS;
192+
193+
/* First byte should be address */
194+
if (i2c->address_set) {
195+
/* Verify if Master is ready for send slave address and send first data byte */
196+
/* Make sure that I2C transaction direction is 'Write' */
197+
if (i2c->hal_i2c.context.state == CY_SCB_I2C_IDLE) {
198+
status = Cy_SCB_I2C_MasterSendStart(i2c->hal_i2c.base, i2c->address, CY_SCB_I2C_WRITE_XFER, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context));
199+
}
200+
201+
if (status == CY_SCB_I2C_SUCCESS) {
202+
status = Cy_SCB_I2C_MasterWriteByte(i2c->hal_i2c.base, (uint8_t)data, CY_I2C_DEFAULT_TIMEOUT, &(i2c->hal_i2c.context));
203+
}
204+
} else {
205+
/* Store slave address and remember status for next byte read or write operation */
206+
i2c->address = data >> 1;
207+
i2c->address_set = true;
208+
}
209+
210+
176211
switch (status) {
177212
case CY_SCB_I2C_MASTER_MANUAL_TIMEOUT:
178213
return 2;

targets/TARGET_Cypress/TARGET_PSOC6/objects.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ struct i2c_s {
9494
size_t async_rx_size;
9595
#endif
9696
uint8_t slave_event;
97+
uint32_t address;
98+
bool address_set;
9799
};
98100
#endif
99101

0 commit comments

Comments
 (0)