in common/util/hal_i2c_slave.c [374:479]
static int do_i2c_slave_cfg(uint8_t bus_num, struct _i2c_slave_config *cfg)
{
if (!cfg)
return I2C_SLAVE_API_INPUT_ERR;
int status;
uint8_t slave_status = I2C_SLAVE_HAS_NO_ERR;
int ret = I2C_SLAVE_API_NO_ERR;
/* check input, support while bus slave is unregistered */
slave_status = i2c_slave_status_get(bus_num);
if (slave_status & (I2C_SLAVE_BUS_INVALID | I2C_SLAVE_CONTROLLER_ERR)) {
LOG_ERR("Bus[%d] check status failed with error status 0x%x!", bus_num,
slave_status);
return I2C_SLAVE_API_BUS_GET_FAIL;
}
/* need unregister first */
if (!(slave_status & I2C_SLAVE_NOT_REGISTER)) {
status = do_i2c_slave_unregister(bus_num);
if (status) {
LOG_ERR("Slave bus[%d] mutex lock failed!", bus_num);
return I2C_SLAVE_API_BUS_GET_FAIL;
}
}
/* Mutex init here */
if (slave_status & I2C_SLAVE_NOT_INIT) {
if (k_mutex_init(&i2c_slave_mutex[bus_num])) {
LOG_ERR("Slave bus[%d] mutex init - failed!", bus_num);
return I2C_SLAVE_API_LOCK_ERR;
}
LOG_DBG("Slave bus[%d] mutex init - success!", bus_num);
}
if (k_mutex_lock(&i2c_slave_mutex[bus_num], K_MSEC(1000))) {
LOG_ERR("Slave bus[%d] mutex lock failed!", bus_num);
return I2C_SLAVE_API_LOCK_ERR;
}
uint8_t slave_address = cfg->address;
uint16_t _max_msg_count = cfg->i2c_msg_count;
struct i2c_slave_data *data = &i2c_slave_device_global[bus_num].data;
char *i2C_slave_queue_buffer;
/* do init, Only one time init for each bus slave */
if (slave_status & I2C_SLAVE_NOT_INIT) {
LOG_DBG("Bus[%d] is going to init!", bus_num);
data->i2c_bus = bus_num;
char controllername[10];
if (snprintf(controllername, sizeof(controllername), "%s%d", I2C_DEVICE_PREFIX,
bus_num) < 0) {
LOG_ERR("I2C controller name parsing error!");
ret = I2C_SLAVE_API_MEMORY_ERR;
goto unlock;
}
data->i2c_controller = device_get_binding(controllername);
if (!data->i2c_controller) {
LOG_ERR("I2C controller not found!");
ret = -EINVAL;
goto unlock;
}
data->config.callbacks = &i2c_slave_cb;
}
/* do modify, modify config set after init */
else {
LOG_DBG("Bus[%d] is going to modified!", bus_num);
k_msgq_purge(&data->z_msgq_id);
if (data->z_msgq_id.buffer_start != NULL) {
free(data->z_msgq_id.buffer_start);
data->z_msgq_id.buffer_start = NULL;
}
}
data->max_msg_count = _max_msg_count;
data->config.address = slave_address >> 1; // to 7-bit slave address
i2C_slave_queue_buffer = malloc(data->max_msg_count * sizeof(struct i2c_msg_package));
if (!i2C_slave_queue_buffer) {
LOG_ERR("I2C slave bus[%d] msg queue memory allocate failed!", data->i2c_bus);
ret = I2C_SLAVE_API_MEMORY_ERR;
goto unlock;
}
k_msgq_init(&data->z_msgq_id, i2C_slave_queue_buffer, sizeof(struct i2c_msg_package),
data->max_msg_count);
i2c_slave_device_global[bus_num].is_init = 1;
LOG_DBG("I2C slave bus[%d] message queue create success with count %d!", data->i2c_bus,
data->max_msg_count);
unlock:
if (k_mutex_unlock(&i2c_slave_mutex[bus_num])) {
LOG_ERR("Mutex unlock failed!");
}
return ret;
}