Driver for the IIC peripheral on RA MCUs. This module implements the I2C Slave Interface.
Overview
Features
- Supports multiple transmission rates
- Standard Mode Support with up to 100-kHz transaction rate.
- Fast Mode Support with up to 400-kHz transaction rate.
- Fast Mode Plus Support with up to 1-MHz transaction rate.
- Reads data written by master device.
- Write data which is read by master device.
- Can accept 0x00 as slave address.
- Can be assigned a 10-bit address.
- Clock stretching is supported and can be implemented via callbacks.
- Provides Transmission/Reception transaction size in the callback.
- I2C Slave can notify the following events via callbacks: Transmission/Reception Request, Transmission/Reception Request for more data, Transmission/Reception Completion, Error Condition.
- Additional build-time features:
- Optional (build time) DTC support for read and write respectively.
Configuration
Build Time Configurations for r_iic_slave
The following build time configurations are defined in fsp_cfg/r_iic_slave_cfg.h:
Configuration | Options | Default | Description |
Parameter Checking |
-
Default (BSP)
-
Enabled
-
Disabled
| Default (BSP) | If selected code for parameter checking is included in the build. |
DTC on Transmission and Reception |
| Disabled | If enabled, DTC instances will be included in the build for both transmission and reception. |
Configurations for Connectivity > I2C Slave (r_iic_slave)
This module can be added to the Stacks tab via New Stack > Connectivity > I2C Slave (r_iic_slave). Non-secure callable guard functions can be generated for this module by right clicking the module in the RA Configuration tool and checking the "Non-secure Callable" box.
Configuration | Options | Default | Description |
Interrupt Priority Level |
Transmit, Receive, and Transmit End | MCU Specific Options | | Select the interrupt priority level. This is set for TXI, RXI, and TEI interrupts. |
Error | MCU Specific Options | | Select the interrupt priority level. This is set for ERI interrupt. |
Name | Name must be a valid C symbol | g_i2c_slave0 | Module name. |
Channel | Value must be a non-negative integer | 0 | Specify the IIC channel. |
Rate |
-
Standard
-
Fast-mode
-
Fast-mode plus
| Standard | Select the transfer rate.
If the delay for the requested transfer rate cannot be achieved, the settings with the largest possible transfer rate that is less than or equal to the requested transfer rate are used. The theoretical calculated delay is printed in a comment in the generated iic_slave_extended_cfg_t structure. |
Internal Reference Clock |
-
PCLKB / 1
-
PCLKB / 2
-
PCLKB / 4
-
PCLKB / 8
-
PCLKB / 16
-
PCLKB / 32
-
PCLKB / 64
-
PCLKB / 128
| PCLKB / 1 | Select the internal reference clock for IIC slave. The internal reference clock is used only to determine the clock frequency of the noise filter samples. |
Digital Noise Filter Stage Select |
-
Disabled
-
Single-stage filter
-
2-stage filter
-
3-stage filter
-
4-stage filter
| 3-stage filter | Select the number of digital filter stages for IIC Slave. |
Slave Address | Value must be non-negative | 0x08 | Specify the slave address. |
General Call |
| Disabled | Allows the slave to respond to general call address: 0x00. |
Address Mode |
| 7-Bit | Select the slave address mode. |
Clock Stretching |
| Disabled | Configure Clock Stretching. |
Callback | Name must be a valid C symbol | NULL | A user callback function must be provided. This will be called from the interrupt service routine (ISR) to report I2C Slave transaction events and status. |
Clock Configuration
The IIC peripheral module uses the PCLKB as its clock source. The actual I2C transfer rate will be calculated and set by the tooling depending on the selected transfer rate. If the PCLKB is configured in such a manner that the selected transfer rate cannot be achieved, an error will be returned.
Pin Configuration
The IIC peripheral module uses pins on the MCU to communicate to external devices. I/O pins must be selected and configured as required by the external device. An I2C channel would consist of two pins - SDA and SCL for data/address and clock respectively.
Usage Notes
Interrupt Configuration
- The IIC error (EEI), receive buffer full (RXI), transmit buffer empty (TXI) and transmit end (TEI) interrupts for the selected channel must be enabled in the properties of the selected device.
- The interrupt priority of ERI can be set higher than or equal to the interrupt priorities of RXI, TXI and TEI.
- Note
- : During master-write slave-read type of operations if the slave device requires to perform clock stretching after the last data byte is received, a higher priority ERI will ensure that the ongoing transaction is completed (by accepting the Stop/Restart condition from the master) before the next transaction is initiated.
-
: To support clock stretching (Holding SCL low after the falling edge of the 9th clock cycle), 'Clock Stretching' configuration must be enabled.
Callback
- A callback function must be provided which will be invoked for the cases below:
- An I2C Master initiates a transmission or reception: I2C_SLAVE_EVENT_TX_REQUEST; I2C_SLAVE_EVENT_RX_REQUEST
- A Transmission or reception has been completed: I2C_SLAVE_EVENT_TX_COMPLETE; I2C_SLAVE_EVENT_RX_COMPLETE
- An I2C Master is requesting to read or write more data: I2C_SLAVE_EVENT_TX_MORE_REQUEST; I2C_SLAVE_EVENT_RX_MORE_REQUEST
- Error conditions: I2C_SLAVE_EVENT_ABORTED
- An I2C Master initiates a general call by passing 0x00 as slave address: I2C_SLAVE_EVENT_GENERAL_CALL
- The callback arguments will contain information about the transaction status/events, bytes transferred and a pointer to the user defined context.
- Clock stretching is enabled by the use of callbacks. This means that the IIC slave can hold the clock line SCL LOW to force the I2C Master into a wait state.
- The table below shows I2C Slave event handling expected in user code:
IIC Slave Callback Event | IIC Slave API expected to be called |
I2C_SLAVE_EVENT_ABORTED | Handle event based on application |
I2C_SLAVE_EVENT_RX_COMPLETE | Handle event based on application |
I2C_SLAVE_EVENT_TX_COMPLETE | Handle event based on application |
I2C_SLAVE_EVENT_RX_REQUEST | R_IIC_SLAVE_Read API. If the slave is a Write Only device call this API with 0 bytes to send a NACK to the master. |
I2C_SLAVE_EVENT_TX_REQUEST | R_IIC_SLAVE_Write API |
I2C_SLAVE_EVENT_RX_MORE_REQUEST | R_IIC_SLAVE_Read API. If the slave cannot read any more data call this API with 0 bytes to send a NACK to the master. |
I2C_SLAVE_EVENT_TX_MORE_REQUEST | R_IIC_SLAVE_Write API |
I2C_SLAVE_EVENT_GENERAL_CALL | R_IIC_SLAVE_Read |
- If parameter checking is enabled and R_IIC_SLAVE_Read API is not called for I2C_SLAVE_EVENT_RX_REQUEST and/or I2C_SLAVE_EVENT_RX_MORE_REQUEST, the slave will send a NACK to the master and would eventually timeout.
- R_IIC_SLAVE_Write API is not called for I2C_SLAVE_EVENT_TX_REQUEST and/or I2C_SLAVE_EVENT_TX_MORE_REQUEST:
- Slave timeout is less than Master timeout: The slave will timeout and release the bus causing the master to read 0xFF for every remaining byte.
- Slave timeout is more than Master timeout: The master will timeout first followed by the slave.
IIC Slave Rate Calculation
- The RA Configuration editor calculates the internal baud-rate setting based on the configured transfer rate. The closest possible baud-rate that can be achieved (less than or equal to the requested rate) at the current PCLKB settings is calculated and used.
Limitations
- When 'Clock Stretching' configuration is enabled, the receive operation will not utilize the double buffer arrangement in hardware for a continuous read. This means that the read operation would happen in single byte units such that the active master would send the next byte only when the slave has read the current byte of data.
- When DTC is enabled, the clock frequency supply for DTC must be configured greater than the "Internal Reference Clock" of the slave.
Examples
Basic Example
This is a basic example of minimal use of the R_IIC_SLAVE in an application. This example shows how this driver can be used for basic read and write operations.
{
.slave = I2C_7BIT_ADDR_IIC_SLAVE,
.p_callback = i2c_master_callback,
.p_context = &g_i2c_master_ctrl,
.p_transfer_tx = NULL,
.p_transfer_rx = NULL,
.p_extend = &g_iic_master_cfg_extend_standard_mode
};
iic_slave_instance_ctrl_t g_i2c_slave_ctrl;
{
.slave = I2C_7BIT_ADDR_IIC_SLAVE,
.p_callback = i2c_slave_callback,
.p_context = &g_i2c_slave_ctrl,
.p_extend = &g_iic_slave_cfg_extend_standard_mode
};
{
g_i2c_master_callback_event = p_args->
event;
}
{
g_i2c_slave_callback_event = p_args->
event;
{
}
{
err =
R_IIC_SLAVE_Read(&g_i2c_slave_ctrl, g_i2c_slave_buffer, g_slave_transfer_length);
assert(FSP_SUCCESS == err);
}
{
err =
R_IIC_SLAVE_Write(&g_i2c_slave_ctrl, g_i2c_slave_buffer, g_slave_transfer_length);
assert(FSP_SUCCESS == err);
}
else
{
}
}
void basic_example (void)
{
uint32_t i;
uint32_t timeout_ms = I2C_TRANSACTION_BUSY_DELAY;
g_slave_transfer_length = I2C_BUFFER_SIZE_BYTES;
assert(FSP_SUCCESS == err);
assert(FSP_SUCCESS == err);
for (i = 0; i < I2C_BUFFER_SIZE_BYTES; i++)
{
g_i2c_master_tx_buffer[i] = (uint8_t) i;
}
err =
R_IIC_MASTER_Write(&g_i2c_master_ctrl, &g_i2c_master_tx_buffer[0], I2C_BUFFER_SIZE_BYTES,
false);
assert(FSP_SUCCESS == err);
{
timeout_ms--;
}
{
__BKPT(0);
}
timeout_ms = I2C_TRANSACTION_BUSY_DELAY;
err =
R_IIC_MASTER_Read(&g_i2c_master_ctrl, &g_i2c_master_rx_buffer[0], I2C_BUFFER_SIZE_BYTES,
false);
assert(FSP_SUCCESS == err);
{
timeout_ms--;
}
{
__BKPT(0);
}
if (0U != memcmp(g_i2c_master_tx_buffer, g_i2c_master_rx_buffer, I2C_BUFFER_SIZE_BYTES))
{
__BKPT(0);
}
}
◆ iic_slave_clock_settings_t
struct iic_slave_clock_settings_t |
Data Fields |
uint8_t |
cks_value |
Internal Reference Clock Select. |
uint8_t |
brl_value |
Low-level period of SCL clock. |
uint8_t |
digital_filter_stages |
Number of digital filter stages based on brl_value. |
◆ iic_slave_extended_cfg_t
struct iic_slave_extended_cfg_t |
R_IIC_SLAVE extended configuration
◆ R_IIC_SLAVE_Open()
Opens the I2C slave device.
- Return values
-
FSP_SUCCESS | I2C slave device opened successfully. |
FSP_ERR_ALREADY_OPEN | Module is already open. |
FSP_ERR_IP_CHANNEL_NOT_PRESENT | Channel is not available on this MCU. |
FSP_ERR_INVALID_ARGUMENT | Error interrupt priority is lower than Transmit, Receive and Transmit End interrupt priority |
FSP_ERR_ASSERTION | Parameter check failure due to one or more reasons below:
- p_api_ctrl or p_cfg is NULL.
- extended parameter is NULL.
- Callback parameter is NULL.
- Set the rate to fast mode plus on a channel which does not support it.
- Invalid IRQ number assigned
- transfer instance in p_cfg is NULL when DTC support enabled
|
◆ R_IIC_SLAVE_Read()
Performs a read from the I2C Master device.
This function will fail if there is already an in-progress I2C transfer on the associated channel. Otherwise, the I2C slave read operation will begin. The caller will be notified when the operation has finished by an I2C_SLAVE_EVENT_RX_COMPLETE in the callback. In case the master continues to write more data, an I2C_SLAVE_EVENT_RX_MORE_REQUEST will be issued via callback. In case of errors, an I2C_SLAVE_EVENT_ABORTED will be issued via callback.
- Return values
-
FSP_SUCCESS | Function executed without issue |
FSP_ERR_ASSERTION | p_api_ctrl, bytes or p_dest is NULL. |
FSP_ERR_IN_USE | Another transfer was in progress. |
FSP_ERR_NOT_OPEN | Device is not open. |
FSP_ERR_INVALID_SIZE | Invalid size when reading data via DTC. |
◆ R_IIC_SLAVE_Write()
Performs a write to the I2C Master device.
This function will fail if there is already an in-progress I2C transfer on the associated channel. Otherwise, the I2C slave write operation will begin. The caller will be notified when the operation has finished by an I2C_SLAVE_EVENT_TX_COMPLETE in the callback. In case the master continues to read more data, an I2C_SLAVE_EVENT_TX_MORE_REQUEST will be issued via callback. In case of errors, an I2C_SLAVE_EVENT_ABORTED will be issued via callback.
- Return values
-
FSP_SUCCESS | Function executed without issue. |
FSP_ERR_ASSERTION | p_api_ctrl or p_src is NULL. |
FSP_ERR_IN_USE | Another transfer was in progress. |
FSP_ERR_NOT_OPEN | Device is not open. |
FSP_ERR_INVALID_SIZE | Invalid size when writing data via DTC. |
◆ R_IIC_SLAVE_CallbackSet()
Updates the user callback and has option of providing memory for callback structure. Implements i2c_slave_api_t::callbackSet
- Return values
-
FSP_SUCCESS | Callback updated successfully. |
FSP_ERR_ASSERTION | A required pointer is NULL. |
FSP_ERR_NOT_OPEN | The control block has not been opened. |
FSP_ERR_NO_CALLBACK_MEMORY | p_callback is non-secure and p_callback_memory is either secure or NULL. |
◆ R_IIC_SLAVE_Close()
Closes the I2C device.
- Return values
-
FSP_SUCCESS | Device closed successfully. |
FSP_ERR_NOT_OPEN | Device not opened. |
FSP_ERR_ASSERTION | p_api_ctrl is NULL. |