Driver for the RIIC peripheral on RZ MPUs. 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.
Configuration
Build Time Configurations for r_riic_slave
The following build time configurations are defined in fsp_cfg/r_riic_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 Support |
| Disabled | If enabled, DMAC instances will be included in the build for both transmission and reception. |
Configurations for Connectivity > I2C Slave Driver on r_riic_slave
This module can be added to the Stacks tab via New Stack > Connectivity > I2C Slave Driver on r_riic_slave.
Configuration | Options | Default | Description |
Interrupt Priority Level > Transmit, Receive, and Transmit End | Value must be an integer between 0 and 255 | 12 | Select the interrupt priority level. This is set for TXI, RXI, and TEI interrupts. |
Interrupt Priority Level > NACK, Start, Stop, Timeout, Arbitration lost | Value must be an integer between 0 and 255 | 12 | Select the interrupt priority level. This is set for NAKI, SPI, STI, ALI, TMOI 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 RIIC channel. |
Rate |
-
Standard
-
Fast-mode
-
Fast-mode plus
| Standard | Select the transfer rate. |
Internal Reference Clock |
-
P0CLK / 1
-
P0CLK / 2
-
P0CLK / 4
-
P0CLK / 8
-
P0CLK / 16
-
P0CLK / 32
-
P0CLK / 64
-
P0CLK / 128
| P0CLK / 1 | Select the internal reference clock for RIIC 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 RIIC 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 RIIC peripheral module uses the clock shown in the following table as its clock source.
Device | Source Clock |
RZ/V2L | P0 clock |
RZ/V2H | Ch0 to Ch7: PLLCLN/16, Ch8: PLLCM33/16 |
RZ/V2N | Ch0 to Ch7: PLLCLN/16, Ch8: PLLCM33/16 |
The actual I2C transfer rate will be calculated and set by the tooling depending on the selected transfer rate. If the clock source 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
- TThe RIIC NACK reception (NAKI), Start condition (STI), Stop condition (SPI), Arbitration lost (ALI), Timeout (TMOI), receive data full (RXI), transmit data empty (TXI) and transmit end (TEI) interrupts for the selected channel used must be enabled in the properties of the selected device.
- The interrupt priority of NAKI, STI, SPI, ALI, TMOI 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 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:
RIIC Slave Callback Event | RIIC 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_RIIC_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_RIIC_SLAVE_Write API |
I2C_SLAVE_EVENT_RX_MORE_REQUEST | R_RIIC_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_RIIC_SLAVE_Write API |
I2C_SLAVE_EVENT_GENERAL_CALL | R_RIIC_SLAVE_Read |
- If parameter checking is enabled and R_RIIC_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_RIIC_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.
RIIC Slave Rate Calculation
- The 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 clock source 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.
Examples
Basic Example
This is a basic example of minimal use of the R_RIIC_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,
.rxi_irq = RIIC0_RI_IRQn,
.txi_irq = RIIC0_TI_IRQn,
.tei_irq = RIIC0_TEI_IRQn,
.ipl = 14,
.p_extend = &g_iic_master_cfg_extend_standard_mode
};
iic_slave_instance_ctrl_t g_i2c_slave_ctrl;
{
.slave = I2C_7BIT_ADDR_IIC_SLAVE,
.rxi_irq = RIIC1_RI_IRQn,
.txi_irq = RIIC1_TI_IRQn,
.tei_irq = RIIC1_TEI_IRQn,
.ipl = 14,
.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_RIIC_SLAVE_Read(&g_i2c_slave_ctrl, g_i2c_slave_buffer, g_slave_transfer_length);
assert(FSP_SUCCESS == err);
}
{
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_RIIC_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_RIIC_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. |
◆ riic_slave_extended_cfg_t
struct riic_slave_extended_cfg_t |
R_IIC_SLAVE extended configuration
Data Fields |
iic_slave_clock_settings_t |
clock_settings |
I2C Clock settings. |
IRQn_Type |
naki_irq |
NACK IRQ Number. |
IRQn_Type |
sti_irq |
Start condition IRQ Number. |
IRQn_Type |
spi_irq |
Stop condition IRQ Number. |
IRQn_Type |
ali_irq |
Arbitration lost IRQ Number. |
IRQn_Type |
tmoi_irq |
Timeout IRQ Number. |
◆ R_RIIC_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 | NACK, Start, Stop, Timeout, Arbitration lost 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 DMAC support enabled.
|
◆ R_RIIC_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. |
◆ R_RIIC_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. |
◆ R_RIIC_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. |
◆ R_RIIC_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. |