Skip to content

Commit

Permalink
Merge pull request #14659 from arduino/i2c_slave_patch
Browse files Browse the repository at this point in the history
STM32: make i2c_salve_read return the number of bytes read
  • Loading branch information
0xc0170 authored Jun 10, 2021
2 parents 7620120 + cd35063 commit b74f62c
Show file tree
Hide file tree
Showing 16 changed files with 88 additions and 6 deletions.
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F0/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F1/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F2/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F3/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F4/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F7/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32G0/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32G4/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32H7/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32L0/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32L1/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32L4/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32L5/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32WB/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32WL/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ struct i2c_s {
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
uint8_t *slave_rx_buffer;
volatile uint8_t slave_rx_buffer_size;
volatile uint8_t slave_rx_count;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
Expand Down
49 changes: 43 additions & 6 deletions targets/TARGET_STM/i2c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ static I2C_HandleTypeDef *i2c_handles[I2C_NUM];
#define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE))
#endif

#define SLAVE_MODE_RECEIVE 1
#define SLAVE_MODE_LISTEN 2
#define DEFAULT_SLAVE_MODE SLAVE_MODE_LISTEN

/* Declare i2c_init_internal to be used in this file */
void i2c_init_internal(i2c_t *obj, const i2c_pinmap_t *pinmap);

Expand Down Expand Up @@ -1199,7 +1203,7 @@ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
#if DEVICE_I2CSLAVE
/* restore slave address */
if (address != 0) {
obj_s->slave = 1;
obj_s->slave = DEFAULT_SLAVE_MODE;
i2c_slave_address(obj, 0, address, 0);
}
#endif
Expand Down Expand Up @@ -1251,7 +1255,7 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave)
I2C_HandleTypeDef *handle = &(obj_s->handle);

if (enable_slave) {
obj_s->slave = 1;
obj_s->slave = DEFAULT_SLAVE_MODE;
HAL_I2C_EnableListen_IT(handle);
} else {
obj_s->slave = 0;
Expand Down Expand Up @@ -1295,11 +1299,28 @@ void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle)
/* Get object ptr based on handler ptr */
i2c_t *obj = get_i2c_obj(I2cHandle);
struct i2c_s *obj_s = I2C_S(obj);
obj_s->pending_slave_rx_maxter_tx = 0;

if (obj_s->slave == SLAVE_MODE_LISTEN) {
obj_s->slave_rx_count++;
if (obj_s->slave_rx_count < obj_s->slave_rx_buffer_size){
HAL_I2C_Slave_Seq_Receive_IT(I2cHandle, &(obj_s->slave_rx_buffer[obj_s->slave_rx_count]), 1, I2C_NEXT_FRAME);
} else {
obj_s->pending_slave_rx_maxter_tx = 0;
}
} else {
obj_s->pending_slave_rx_maxter_tx = 0;
}
}

void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
{
i2c_t *obj = get_i2c_obj(hi2c);
struct i2c_s *obj_s = I2C_S(obj);

if (obj_s->slave == SLAVE_MODE_LISTEN) {
obj_s->pending_slave_rx_maxter_tx = 0;
}

/* restart listening for master requests */
HAL_I2C_EnableListen_IT(hi2c);
}
Expand Down Expand Up @@ -1328,18 +1349,34 @@ int i2c_slave_read(i2c_t *obj, char *data, int length)
int count = 0;
int ret = 0;
uint32_t timeout = 0;
int _length = 0;

if (obj_s->slave == SLAVE_MODE_LISTEN) {
/* We don't know in advance how many bytes will be sent by master so
* we'll fetch one by one until master ends the sequence */
_length = 1;
obj_s->slave_rx_buffer_size = length;
obj_s->slave_rx_count = 0;
obj_s->slave_rx_buffer = (uint8_t*)data;
} else {
_length = length;
}

/* Always use I2C_NEXT_FRAME as slave will just adapt to master requests */
ret = HAL_I2C_Slave_Seq_Receive_IT(handle, (uint8_t *) data, length, I2C_NEXT_FRAME);
ret = HAL_I2C_Slave_Seq_Receive_IT(handle, (uint8_t *) data, _length, I2C_NEXT_FRAME);

if (ret == HAL_OK) {
timeout = BYTE_TIMEOUT_US * (length + 1);
timeout = BYTE_TIMEOUT_US * (_length + 1);
while (obj_s->pending_slave_rx_maxter_tx && (--timeout != 0)) {
wait_us(1);
}

if (timeout != 0) {
count = length;
if (obj_s->slave == SLAVE_MODE_LISTEN) {
count = obj_s->slave_rx_count;
} else {
count = _length;
}
} else {
DEBUG_PRINTF("TIMEOUT or error in i2c_slave_read\r\n");
}
Expand Down

0 comments on commit b74f62c

Please sign in to comment.