|
| fsp_err_t | R_I2C_MASTER_W_Open (i2c_master_ctrl_t *const p_api_ctrl, i2c_master_cfg_t const *const p_cfg) |
| |
| fsp_err_t | R_I2C_MASTER_W_Read (i2c_master_ctrl_t *const p_api_ctrl, uint8_t *const p_dest, uint32_t const bytes, bool const restart) |
| |
| fsp_err_t | R_I2C_MASTER_W_Write (i2c_master_ctrl_t *const p_api_ctrl, uint8_t *const p_src, uint32_t const bytes, bool const restart) |
| |
| fsp_err_t | R_I2C_MASTER_W_Abort (i2c_master_ctrl_t *const p_api_ctrl) |
| |
| fsp_err_t | R_I2C_MASTER_W_SlaveAddressSet (i2c_master_ctrl_t *const p_api_ctrl, uint32_t const slave, i2c_master_addr_mode_t const addr_mode) |
| |
| fsp_err_t | R_I2C_MASTER_W_CallbackSet (i2c_master_ctrl_t *const p_api_ctrl, void(*p_callback)(i2c_master_callback_args_t *), void *const p_context, i2c_master_callback_args_t *const p_callback_memory) |
| |
| fsp_err_t | R_I2C_MASTER_W_StatusGet (i2c_master_ctrl_t *const p_api_ctrl, i2c_master_status_t *p_status) |
| |
| fsp_err_t | R_I2C_MASTER_W_Close (i2c_master_ctrl_t *const p_api_ctrl) |
| |
Driver for the I2C peripheral on RA for Wireless (RAFW) MCUs. This module implements the I2C Master Interface.
Overview
The I2C Master on I2C_W HAL module supports transactions with an I2C Slave device. Callbacks must be provided which are invoked when a transmit or receive operation has completed. The callback argument will contain information about the transaction status, bytes transferred and a pointer to the user defined context.
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.
- I2C Master Read from a slave device.
- I2C Master Write to a slave device.
- Abort any in-progress transactions.
- Set the address of the slave device.
- Non-blocking behavior is achieved by the use of callbacks.
- Additional build-time features
- Optional (build time) DTC support for read and write respectively.
- Optional (build time) DMAC support for read and write respectively.
Configuration
Build Time Configurations for r_i2c_master_w
The following build time configurations are defined in fsp_cfg/r_i2c_master_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 Master (r_i2c_master_w)
This module can be added to the Stacks tab via New Stack > Connectivity > I2C Master (r_i2c_master_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_master_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 maximum desired transfer rate.
The actual transfer rate achieved, will be determined by the selected System Clock and the SCL High/Low Count configuration provided in module's extendend configuration. |
| Custom Rate (bps) | Value must be a non-negative integer | 0 | Set a custom bitrate (bps). Set to 0 to use the maximum bitrate for the selected mode.
Standard-mode: up to 100000; Fast-mode: up to 400000; Fast-mode plus: up to 1000000; HighSpeed-mode: up to 3400000; |
| Rise Time (ns) | Value must be a non-negative integer | 40 | Set the rise time (tr) in nanoseconds. |
| Fall Time (ns) | Value must be a non-negative integer | 40 | Set the fall time (tf) in nanoseconds. |
| Duty Cycle (%) | Value must be an integer between 0 and 100 | 50 | Set the SCL duty cycle. |
| Slave Address | Value must be non-negative | 0x23 | Specify the slave address. |
| Address Mode |
| 7-Bit | Select the slave address mode. Ensure 10-bit slave addressing is enabled in the configuration to use 10-Bit setting here. |
| 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) upon I2C transaction completion reporting the transaction 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 internal 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.
- Set equal priority levels for all the interrupts mentioned above. Setting the interrupts to different priority levels could result in improper operation.
I2C Master Rate Calculation
The RAFW Configuration editor calculates the internal baud-rate setting based on the configured transfer rate.
When the Custom Rate setting is set to 0 the bitrate is fixed to the maximum values shown below. Otherwise, the supplied value is used to generate bitrate settings.
- Standard-mode (Sm) : up to 100 kbps
- Fast-mode (Fm) : up to 400 kbps
- Fast-mode Plus (Fm+) : up to 1 Mbps
- HighSpeed-mode (HS) : up to 3.4 Mbps
- 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.
- If a valid clock rate could not be calculated, an error is returned by the tool.
Enabling DTC/DMAC with the I2C_W
- DTC/DMA transfer support is configurable and is disabled from the build by default. The I2C_W driver provides two DTC instances for transmission and reception respectively. The DTC/DMAC instances can be enabled individually during configuration.
- DTC/DMA is helpful for minimizing interrupts during large transactions. Many I2C applications have shorter transactions. These applications will likely not see any improvement with DTC/DMA. I2C often runs at a much slower speed than the CPU core clock. Some applications with longer transactions may prefer servicing the interrupts at the I2C bitrate to the overhead of bringing in the DTC/DMAC driver.
- For further details on DTC please refer to DTC_W and on DMAC please refer to DMAC_W_B
Multiple Devices on the Bus
- A single I2C instance can be used to communicate with multiple slave devices on the same channel by using the SlaveAddressSet API.
Multi-Master Support
- If multiple masters are connected on the same bus, the I2C Master is capable of detecting bus busy state before initiating the communication.
Restart
- I2C Master can hold the bus after an I2C transaction by issuing a repeated start condition.
Examples
Basic Example
This is a basic example of minimal use of the r_i2c_master_w in an application. This example shows how this driver can be used for basic read and write operations.
{
.slave = I2C_SLAVE_EEPROM,
.p_callback = i2c_callback,
.p_context = &g_i2c_device_ctrl_1,
.p_transfer_tx = NULL,
.p_transfer_rx = NULL,
.p_extend = &g_i2c_master_w_cfg_extend
};
{
g_i2c_callback_event = p_args->
event;
}
void basic_example (void)
{
uint32_t i;
uint32_t timeout_ms = I2C_TRANSACTION_BUSY_DELAY;
assert(FSP_SUCCESS == err);
#ifdef NDEBUG
(void) err;
#endif
for (i = 0; i < I2C_BUFFER_SIZE_BYTES; i++)
{
g_i2c_tx_buffer[i] = (uint8_t) i;
}
err =
R_I2C_MASTER_W_Write(&g_i2c_device_ctrl_1, &g_i2c_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_device_ctrl_1, &g_i2c_rx_buffer[0], I2C_BUFFER_SIZE_BYTES,
false);
assert(FSP_SUCCESS == err);
{
timeout_ms--;;
}
{
__BKPT(0);
}
if (0U != memcmp(g_i2c_tx_buffer, g_i2c_rx_buffer, I2C_BUFFER_SIZE_BYTES))
{
__BKPT(0);
}
}
Multiple Slave devices on the same channel (bus)
This example demonstrates how a single I2C_W driver can be used to communicate with different slave devices which are on the same channel.
- Note
- The callback function from the first example applies to this example as well.
{
.slave = I2C_SLAVE_TEMP_SENSOR,
.p_callback = i2c_callback,
.p_context = &g_i2c_device_ctrl_2,
.p_transfer_tx = NULL,
.p_transfer_rx = NULL,
.p_extend = &g_i2c_master_w_cfg_extend
};
void single_channel_multi_slave (void)
{
uint32_t timeout_ms = I2C_TRANSACTION_BUSY_DELAY;
assert(FSP_SUCCESS == err);
#ifdef NDEBUG
(void) err;
#endif
memset(g_i2c_rx_buffer, '0', I2C_BUFFER_SIZE_BYTES);
err =
R_I2C_MASTER_W_Read(&g_i2c_device_ctrl_2, &g_i2c_rx_buffer[0], I2C_BUFFER_SIZE_BYTES,
false);
assert(FSP_SUCCESS == err);
{
timeout_ms--;;
}
{
__BKPT(0);
}
assert(FSP_SUCCESS == err);
g_i2c_tx_buffer[0] = 0xAA;
g_i2c_tx_buffer[1] = 0xBB;
timeout_ms = I2C_TRANSACTION_BUSY_DELAY;
assert(FSP_SUCCESS == err);
{
timeout_ms--;;
}
{
__BKPT(0);
}
}
◆ i2c_master_w_clock_settings_t
| struct i2c_master_w_clock_settings_t |
| Data Fields |
|
uint16_t |
scl_hcnt |
I2C clock (SCL) high count. |
|
uint16_t |
scl_lcnt |
I2C clock (SCL) low count. |
◆ i2c_master_w_instance_ctrl_t
| struct i2c_master_w_instance_ctrl_t |
I2C control structure. DO NOT INITIALIZE.
◆ i2c_master_w_extended_cfg_t
| struct i2c_master_w_extended_cfg_t |
R_I2C extended configuration
| Data Fields |
|
i2c_master_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_MASTER_W_I2C1_MADDR
| #define I2C_MASTER_W_I2C1_MADDR |
I2C high speed master code. This bit field holds the value of the I2C HS mode master code. HS-mode master codes are reserved 8-bit codes (00001xxx) that are not used for slave addressing or other purposes. Each master has its unique master code. Up to eight high-speed mode masters can be present on the same I2C bus system. Valid values are from 0 to 7. This can be written only when the I2C interface is disabled, which corresponds to the IC_ENABLE[0] register being set to 0. Writes at other times have no effect.
◆ I2C_MASTER_W_FIFO_DEPTH
| #define I2C_MASTER_W_FIFO_DEPTH |
◆ i2c_master_w_int_t
Offset to make the I2C HW channels 0-based for the r_i2c_master_w driver. I2C interrupt source
| Enumerator |
|---|
| I2C_MASTER_W_INT_RX_UNDERFLOW | Attempt to read from empty RX FIFO has been made.
|
| I2C_MASTER_W_INT_RX_OVERFLOW | RX FIFO is full but new data are incoming and being discarded.
|
| I2C_MASTER_W_INT_RX_FULL | RX FIFO level is equal or above threshold.
|
| I2C_MASTER_W_INT_TX_OVERFLOW | Attempt to write to TX FIFO which is already full.
|
| I2C_MASTER_W_INT_TX_EMPTY | TX FIFO level is equal or below threshold.
|
| I2C_MASTER_W_INT_READ_REQUEST | I2C master attempts to read data(slave only)
|
| I2C_MASTER_W_INT_TX_ABORT | TX cannot be completed.
|
| I2C_MASTER_W_INT_RX_DONE | I2C master did not acknowledge transmitted byte(slave only)
|
| I2C_MASTER_W_INT_ACTIVITY | Any I2C activity occurred.
|
| I2C_MASTER_W_INT_STOP_DETECTED | STOP condition occurred.
|
| I2C_MASTER_W_INT_START_DETECTED | START/RESTART condition occurred.
|
| I2C_MASTER_W_INT_GENERAL_CALL | General Call address received(slave only)
|
◆ R_I2C_MASTER_W_Open()
Opens the I2C 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_MASTER_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_MASTER_W_Read()
| fsp_err_t R_I2C_MASTER_W_Read |
( |
i2c_master_ctrl_t *const |
p_api_ctrl, |
|
|
uint8_t *const |
p_dest, |
|
|
uint32_t const |
bytes, |
|
|
bool const |
restart |
|
) |
| |
Performs a read from the I2C device. The caller will be notified when the operation has completed (successfully) by an I2C_MASTER_EVENT_RX_COMPLETE in the 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. |
| [in] | restart | Restart information about this transfer. |
- Return values
-
| FSP_SUCCESS | Function executed without issue. |
| FSP_ERR_ASSERTION | p_api_ctrl, p_dest or bytes is NULL. |
| FSP_ERR_INVALID_SIZE | Provided number of bytes more than the configured TX buffer size or more than UINT16_MAX(= 65535) while DTC/DMAC is used for data transfer. |
| FSP_ERR_NOT_OPEN | Handle is not initialized. Call R_I2C_MASTER_W_Open to initialize the control block. |
- Returns
- See Common Error Codes or functions called by this function for other possible return codes. This function calls: transfer_api_t::reset.
◆ R_I2C_MASTER_W_Write()
| fsp_err_t R_I2C_MASTER_W_Write |
( |
i2c_master_ctrl_t *const |
p_api_ctrl, |
|
|
uint8_t *const |
p_src, |
|
|
uint32_t const |
bytes, |
|
|
bool const |
restart |
|
) |
| |
Performs a write to the I2C device. The caller will be notified when the operation has completed (successfully) by an I2C_MASTER_EVENT_TX_COMPLETE in the 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. |
| [in] | restart | Restart information about this transfer. |
- Return values
-
| FSP_SUCCESS | Function executed without issue. |
| FSP_ERR_ASSERTION | p_api_ctrl or p_src is NULL. |
| FSP_ERR_INVALID_SIZE | Provided number of bytes more than the configured TX buffer size or more than UINT16_MAX(= 65535) while DTC/DMAC is used for data transfer. |
| FSP_ERR_NOT_OPEN | Handle is not initialized. Call R_I2C_MASTER_W_Open to initialize the control block. |
- Returns
- See Common Error Codes or functions called by this function for other possible return codes. This function calls: transfer_api_t::reset.
◆ R_I2C_MASTER_W_Abort()
Safely aborts any in-progress transfer and forces the I2C peripheral into ready state.
- Parameters
-
| [in] | p_api_ctrl | Pointer to control block. |
- Return values
-
| FSP_SUCCESS | Channel was reset successfully. |
| FSP_ERR_ASSERTION | p_api_ctrl is NULL. |
| FSP_ERR_NOT_OPEN | Handle is not initialized. Call R_I2C_MASTER_W_Open to initialize the control block. |
| 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.
|
- Note
- A callback will not be invoked in case an in-progress transfer gets aborted by calling this API.
- 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_MASTER_W_SlaveAddressSet()
Sets address and addressing mode of the slave device. This function is used to set the device address and addressing mode of the slave without reconfiguring the entire bus.
- Parameters
-
| [in] | p_api_ctrl | Pointer to control block. |
| [in] | slave | Denotes the slave device. |
| [in] | addr_mode | Addressing mode (7 bit or 10 bit). |
- Return values
-
| FSP_SUCCESS | Address of the slave is set correctly. |
| FSP_ERR_ASSERTION | Pointer to control structure is NULL. |
| FSP_ERR_IN_USE | Another transfer was in-progress. |
| FSP_ERR_NOT_OPEN | Handle is not initialized. Call R_I2C_MASTER_W_Open to initialize the control block. |
| 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.
|
◆ R_I2C_MASTER_W_CallbackSet()
Updates the user callback and has option of providing memory for callback structure. Implements i2c_master_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_MASTER_W_StatusGet()
Provides driver status.
- Parameters
-
| [in] | p_api_ctrl | Pointer to control block. |
| [out] | p_status | Pointer to the I2C status. |
- Return values
-
| FSP_SUCCESS | Status stored in p_status. |
| FSP_ERR_ASSERTION | NULL pointer. |
◆ R_I2C_MASTER_W_Close()
Closes the I2C device. May power down I2C peripheral. This function will safely terminate any in-progress I2C transfers.
- Parameters
-
| [in] | p_api_ctrl | Pointer to control block. |
- Return values
-
| FSP_SUCCESS | Device closed without issue. |
| FSP_ERR_ASSERTION | p_api_ctrl is NULL. |
| FSP_ERR_NOT_OPEN | Handle is not initialized. Call R_I2C_MASTER_W_Open to initialize the control block. |
| 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.
|
- Note
- A callback will not be invoked in case an in-progress transfer gets aborted by calling this API.