Driver for the IIC peripheral on RZ microprocessor. 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.
- 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) DMAC 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. |
| DMAC on Transmission and Reception |
| Disabled | If enabled, DMAC instances will be included in the build for both transmission and reception. Even if enabled, DMAC is not used without adding DMAC driver. |
| Nested Interrupt (Multiplex Interrupt) |
| Disabled | Enable nested interrupt for a single driver. |
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).
| Configuration | Options | Default | Description |
| Interrupts Priority Level > Transmit, Receive, and Transmit End | MCU Specific Options | | Select the interrupt priority level. This is set for TXI, RXI, and TEI interrupts. |
| Interrupts Priority Level > 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 | 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 |
-
PCLKL / 1
-
PCLKL / 2
-
PCLKL / 4
-
PCLKL / 8
-
PCLKL / 16
-
PCLKL / 32
-
PCLKL / 64
-
PCLKL / 128
| PCLKL / 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 PCLKL 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 PCLKL 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 MPU 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 FSP 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 PCLKL 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 DMAC is enabled, the clock frequency supply for DMAC must be configured greater than the "Internal Reference Clock" of the slave.
Data coherency
- Note
- This section applies only when I2C Slave utilizes the DMAC.
Source and destination buffers must either be allocated to a non-cacheable region, or, if placed in a cacheable region, be managed via explicit cache maintenance operations (clean/invalidate) to ensure data coherency (This involves cleaning the cache before starting the transmission and invalidating it once the transmission is completed). In the case of the write-back policy, when a destination buffer is placed in a cacheable region, it must be aligned with 64 bytes. See Memory attributes for details.
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,
.ipl = 12,
.rxi_irq = VECTOR_NUMBER_IIC2_RXI,
.txi_irq = VECTOR_NUMBER_IIC2_TXI,
.tei_irq = VECTOR_NUMBER_IIC2_TEI,
.eri_irq = VECTOR_NUMBER_IIC2_EEI,
.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
};
{
.slave = I2C_7BIT_ADDR_IIC_SLAVE,
.ipl = 12,
.eri_ipl = 12,
.rxi_irq = VECTOR_NUMBER_IIC1_RXI,
.txi_irq = VECTOR_NUMBER_IIC1_TXI,
.tei_irq = VECTOR_NUMBER_IIC1_TEI,
.eri_irq = VECTOR_NUMBER_IIC1_EEI,
.p_callback = i2c_slave_callback,
.p_context = &g_i2c_slave_ctrl,
.clock_stretching_enable = false,
.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);
}
}
◆ RZN::st_iic_slave_clock_settings
| struct RZN::st_iic_slave_clock_settings |
| Class Members |
|
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. |
◆ RZN::st_iic_slave_instance_ctrl
| struct RZN::st_iic_slave_instance_ctrl |
I2C control structure. DO NOT INITIALIZE.
◆ RZN::st_iic_slave_extended_cfg
| struct RZN::st_iic_slave_extended_cfg |
R_IIC_SLAVE extended configuration
| Class Members |
|
iic_slave_clock_settings_t |
clock_settings |
I2C Clock settings. |
|
void * |
p_reg |
Register base address for specified channel. |
◆ iic_slave_clock_settings_t
◆ iic_slave_instance_ctrl_t
◆ iic_slave_extended_cfg_t
◆ 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 MPU. |
| FSP_ERR_INVALID_ARGUMENT | Error interrupt priority is lower than Transmit, Receive and Transmit End interrupt priority. DMAC activation is not available for safety channel. |
| FSP_ERR_ASSERTION | Parameter check failure due to one or more reasons below:
- p_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 invalid when DMAC 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_ctrl, bytes or p_dest is NULL. |
| FSP_ERR_IN_USE | Another transfer was in progress. |
| FSP_ERR_NOT_OPEN | Device is not open. |
◆ 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_ctrl or p_src is NULL. |
| FSP_ERR_IN_USE | Another transfer was in progress. |
| FSP_ERR_NOT_OPEN | Device is not open. |
◆ 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. |
◆ 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_ctrl is NULL. |