Driver for the I2C peripheral on RA for Wireless (RAFW) 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.
- HighSpeed Mode Support with up to 3.4-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 internally by the HW IP.
- 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.
- Optional (build time) DMAC_W_B support for read and write respectively.
Configuration
Build Time Configurations for r_i2c_slave_w
The following build time configurations are defined in fsp_cfg/r_i2c_slave_w_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. |
| DMAC on Transmission and Reception |
| Disabled | If enabled, DMAC instances will be included in the build for both transmission and reception. |
| Use ONLY the Generic Interrupt |
| Disabled | If enabled, I2C will use only the Generic Interrupt (gen_irq) for its operation. DTC is not available in this mode. |
| Maximum Transmission Length (Used when DTC/DMA support is enabled) | Value must be a non-negative integer | 256 | The maximum transfer length when transmitting using DTC. |
Configurations for Connectivity > I2C Slave (r_i2c_slave_w)
This module can be added to the Stacks tab via New Stack > Connectivity > I2C Slave (r_i2c_slave_w). 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 TXE, RX, and TXR interrupts. |
| Generic | MCU Specific Options | | Select the interrupt priority level. This is set for GEN interrupt. |
| Name | Name must be a valid C symbol | g_i2c_slave_w0 | Module name. |
| Channel | Value must be an integer greater than 0 | 1 | Specify the I2C channel. |
| Rate |
-
Standard
-
Fast-mode
-
Fast-mode plus
-
HighSpeed
| 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 i2c_slave_w_extended_cfg_t structure. |
| Digital Noise Filter Counts | Value must an integer greater than 0 | 0x01 | Select the counts of source clock periods used for spike suppression for I2C Slave. |
| SDA Setup Time Counts | Value must an integer greater than 0 | 0x64 | Select the Data Setup time in counts of source clock periods. |
| SDA Hold Time Counts (TX) | Value must be an integer greater than 1 | 0x01 | Select the Data Hold time in counts of source clock periods when in Transmitter mode. |
| SDA Hold Time Counts (RX) | Value must be a non-negative integer | 0x00 | Select the Data Hold time in counts of source clock periods when in Receiver mode. |
| 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. |
| Enable Bursts in DMA TX |
| Enabled | Enable DMA Burst TX Transactions when the transaction length is 4- or 8-byte aligned. Relevant only when DMA support is enabled. |
| Enable Bursts in DMA RX |
| Enabled | Enable DMA Burst RX Transactions when the transaction length is 4- or 8-byte aligned. Relevant only when DMA support is enabled. |
| 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 I2C peripheral module uses the System Clock (Div1/DivN) 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 clock source is configured in such a manner that the selected transfer rate cannot be achieved, an error will be returned.
Pin Configuration
The I2C 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 I2C generic (GEN) interrupt for the selected channel used must be enabled in the properties of the selected device.
- The I2C dedicated receive buffer full (RX), transmit buffer empty (TXE) and transmit end (TXR) interrupts for the selected channel used must be enabled in the properties of the selected device only when DTC is used.
- The interrupt priority of GEN can be set higher than or equal to the interrupt priorities of RX, TXE and TXR.
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.
- The table below shows I2C Slave event handling expected in user code:
| I2C Slave Callback Event | I2C 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_I2C_SLAVE_W_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_I2C_SLAVE_W_Write API |
| I2C_SLAVE_EVENT_RX_MORE_REQUEST | R_I2C_SLAVE_W_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_I2C_SLAVE_W_Write API |
| I2C_SLAVE_EVENT_GENERAL_CALL | R_I2C_SLAVE_W_Read |
- If R_I2C_SLAVE_W_Read API is not called for I2C_SLAVE_EVENT_RX_REQUEST and/or I2C_SLAVE_EVENT_RX_MORE_REQUEST:
- Transaction size exceeds FIFO size (32): Slave will send a NACK to the master and will timeout.
- Transaction size does not exceed FIFO size (32): Master will read 0xFF and slave will timeout.
- If R_I2C_SLAVE_W_Write API is not called for I2C_SLAVE_EVENT_TX_REQUEST and/or I2C_SLAVE_EVENT_TX_MORE_REQUEST:
- Slave will hold SCL LOW. A reset of the system is required.
I2C_W Slave Rate Calculation
- The RAFW 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 source clock settings is calculated and used.
Examples
Basic Example
This is a basic example of minimal use of the R_I2C_SLAVE_W in an application. This example shows how this driver can be used for basic read and write operations.
{
.slave = I2C_7BIT_ADDR_I2C_SLAVE,
.p_callback = i2c_master_callback,
.p_context = &g_i2c_master_ctrl,
.p_transfer_tx = NULL,
.p_transfer_rx = NULL,
.p_extend = &g_i2c_master_w_cfg_extend_standard_mode
};
{
.slave = I2C_7BIT_ADDR_I2C_SLAVE,
.p_callback = i2c_slave_callback,
.p_context = &g_i2c_slave_ctrl,
.p_extend = &g_i2c_slave_cfg_extend_standard_mode
};
{
g_i2c_master_callback_event = p_args->
event;
}
{
g_i2c_slave_callback_event = p_args->
event;
{
}
{
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_I2C_MASTER_W_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_I2C_MASTER_W_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);
}
}
◆ i2c_slave_w_clock_settings_t
| struct i2c_slave_w_clock_settings_t |
| Data Fields |
|
uint8_t |
digital_filter_stages |
Counts of source clock periods for spike suppression. |
|
uint8_t |
sda_setup_counts |
Counts of source clock periods for SDA Setup time. |
|
uint16_t |
sda_hold_tx_counts |
Counts of source clock periods for SDA Hold time when in Transmitter mode. |
|
uint16_t |
sda_hold_rx_counts |
Counts of source clock periods for SDA Hold time when in Receiver mode. |
◆ i2c_slave_w_instance_ctrl_t
| struct i2c_slave_w_instance_ctrl_t |
I2C control structure. DO NOT INITIALIZE.
◆ i2c_slave_w_extended_cfg_t
| struct i2c_slave_w_extended_cfg_t |
R_I2C_SLAVE_W extended configuration
| Data Fields |
|
i2c_slave_w_clock_settings_t |
clock_settings |
I2C Clock settings. |
|
bool |
select_divn |
Select the clock source (DIVN/DIV1 clock) |
|
IRQn_Type |
gen_irq |
Generic I2C Interrupt IRQ number. |
|
uint8_t |
gen_ipl |
Generic I2C Interrupt Priority. |
◆ I2C_SLAVE_W_FIFO_DEPTH
| #define I2C_SLAVE_W_FIFO_DEPTH |
◆ i2c_slave_w_transfer_dir_t
Offset to make the I2C HW channels 0-based for the r_i2c_slave_w driver. I2C Slave transaction enumeration
◆ i2c_slave_w_int_t
I2C interrupt source
| Enumerator |
|---|
| I2C_SLAVE_W_INT_RX_UNDERFLOW | Attempt to read from empty RX FIFO has been made.
|
| I2C_SLAVE_W_INT_RX_OVERFLOW | RX FIFO is full but new data are incoming and being discarded.
|
| I2C_SLAVE_W_INT_RX_FULL | RX FIFO level is equal or above threshold.
|
| I2C_SLAVE_W_INT_TX_OVERFLOW | Attempt to write to TX FIFO which is already full.
|
| I2C_SLAVE_W_INT_TX_EMPTY | TX FIFO level is equal or below threshold.
|
| I2C_SLAVE_W_INT_READ_REQUEST | I2C master attempts to read data (slave only)
|
| I2C_SLAVE_W_INT_TX_ABORT | TX cannot be completed.
|
| I2C_SLAVE_W_INT_RX_DONE | I2C master did not acknowledge transmitted byte(slave only)
|
| I2C_SLAVE_W_INT_ACTIVITY | Any I2C activity occurred.
|
| I2C_SLAVE_W_INT_STOP_DETECTED | STOP condition occurred.
|
| I2C_SLAVE_W_INT_START_DETECTED | START/RESTART condition occurred.
|
| I2C_SLAVE_W_INT_GENERAL_CALL | General Call address received(slave only)
|
◆ R_I2C_SLAVE_W_Open()
Opens the I2C slave device.
- Parameters
-
| [in] | p_api_ctrl | Pointer to control block. |
| [in] | p_cfg | Pointer to I2C specific configuration structure. |
- 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_HW_CONDITION | I2C's power domain is not enabled. |
| FSP_ERR_ASSERTION | Parameter check failure due to one or more reasons below:
- p_api_ctrl or p_cfg is NULL.
- p_extend parameter is NULL.
- Invalid IRQ number assigned. Please refer to the documentation of I2C_SLAVE_W_CFG_GENERIC_ONLY
- Invalid driver configuration.
|
| FSP_ERR_TIMEOUT | Device is stuck & cannot be disabled. To recover from such an issue you can:
- reset the SCLK & SDA pins,
- disable PD_COM,
- perform a HW reset.
|
- Returns
- See Common Error Codes or functions called by this function for other possible return codes. This function calls: transfer_api_t::open.
◆ R_I2C_SLAVE_W_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.
- Parameters
-
| [in] | p_api_ctrl | Pointer to control block. |
| [out] | p_dest | Pointer to the destination buffer. |
| [in] | bytes | Number of bytes to be read. |
- Return values
-
| FSP_SUCCESS | Function executed without issue. |
| FSP_ERR_ASSERTION | p_api_ctrl, p_dest or p_callback 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_I2C_SLAVE_W_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.
- Parameters
-
| [in] | p_api_ctrl | Pointer to control block. |
| [in] | p_src | Pointer to the source buffer. |
| [in] | bytes | Number of bytes to be write. |
- Return values
-
| FSP_SUCCESS | Function executed without issue. |
| FSP_ERR_ASSERTION | p_api_ctrl, p_src or p_callback 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_I2C_SLAVE_W_CallbackSet()
Updates the user callback and has option of providing memory for callback structure. Implements i2c_slave_api_t::callbackSet
- Parameters
-
| [in] | p_api_ctrl | Pointer to control block. |
| [in] | p_callback | Pointer to the callback. |
| [in] | p_context | Pointer to context. |
| [in] | p_callback_memory | Pointer to the callback memory. |
- 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_I2C_SLAVE_W_Close()
Closes the I2C device.
- Parameters
-
| [in] | p_api_ctrl | Pointer to control block. |
- Return values
-
| FSP_SUCCESS | Device closed successfully. |
| FSP_ERR_NOT_OPEN | Device not opened. |
| FSP_ERR_ASSERTION | p_api_ctrl is NULL. |
| FSP_ERR_TIMEOUT | Device is stuck & cannot be disabled. To recover from such an issue you can:
- reset the SCLK & SDA pins,
- disable PD_COM,
- perform a HW reset.
|