RA Flexible Software Package Documentation  Release v5.6.0

 
I2C Master (r_sau_i2c)

Functions

fsp_err_t R_SAU_I2C_Open (i2c_master_ctrl_t *const p_api_ctrl, i2c_master_cfg_t const *const p_cfg)
 
fsp_err_t R_SAU_I2C_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_SAU_I2C_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_SAU_I2C_Abort (i2c_master_ctrl_t *const p_api_ctrl)
 
fsp_err_t R_SAU_I2C_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_SAU_I2C_CallbackSet (i2c_master_ctrl_t *const p_api_ctrl, void(*p_callback)(i2c_master_callback_args_t *), void const *const p_context, i2c_master_callback_args_t *const p_callback_memory)
 
fsp_err_t R_SAU_I2C_StatusGet (i2c_master_ctrl_t *const p_api_ctrl, i2c_master_status_t *p_status)
 
fsp_err_t R_SAU_I2C_Close (i2c_master_ctrl_t *const p_api_ctrl)
 
fsp_err_t R_SAU_I2C_Start (sau_i2c_instance_ctrl_t *const p_ctrl)
 
fsp_err_t R_SAU_I2C_Stop (sau_i2c_instance_ctrl_t *const p_ctrl)
 

Detailed Description

Driver for the SAU peripheral on RA MCUs. This module implements the I2C Master Interface.

Overview

The Simple I2C master on SAU HAL module supports transactions with an I2C Slave device. Callbacks must be provided which would be invoked when a transmission or receive has been completed. The callback arguments will contain information about the transaction status, bytes transferred and a pointer to the user defined context.

Features

Configuration

Build Time Configurations for r_sau_i2c

The following build time configurations are defined in fsp_cfg/r_sau_i2c_cfg.h:

ConfigurationOptionsDefaultDescription
Parameter Checking
  • Default (BSP)
  • Enabled
  • Disabled
Default (BSP) If selected code for parameter checking is included in the build.
Enable Critical Section
  • Enabled
  • Disabled
Disabled Critical section needs to be enabled if multiple channels on the same SAU unit are configured for I2C
Manual Start-Stop
  • Enabled
  • Disabled
Disabled If enabled, users need to manually call the R_SAU_I2C_Start/R_SAU_I2C_Stop functions to generate the I2C start and stop conditions.
Enable Single Channel
  • 00
  • 20
  • 11
  • Disabled
Disabled Enable single channel to reduce code size if only one channel (00, 11, or 20) is to be configured for SAU I2C.
I2C Restart
  • Enable
  • Disable
Enable Select whether to include code for the I2C restart (repeated start) condition in the build. Set to 'Disable' to reduce code size when all I2C slaves used by all SAU instances do not use I2C restart.
DTC Support
  • Enable
  • Disable
Disable Enable DTC support for the SAU I2C module.

Configurations for Connectivity > I2C Master (r_sau_i2c)

This module can be added to the Stacks tab via New Stack > Connectivity > I2C Master (r_sau_i2c).

ConfigurationOptionsDefaultDescription
General
NameName must be a valid C symbolg_i2c0 Module name.
ChannelMCU Specific OptionsSelect the SAU channel.
Operation clock
  • CK0
  • CK1
CK0 Select the I2C operation clock. Use the Clocks tab to set the operation clock divider.
Slave AddressValue must be a non-negative integer0x00 Specify the slave address.
Rate
  • Standard
  • Fast mode
  • Fast mode plus
Standard Select the I2C data rate.

If the requested rate cannot be achieved, adjust the operation clock frequency until the rate is achievable. The calculated rate is printed in a comment in the generated sau_i2c_extended_cfg_t structure.
Delay time (Microseconds)Value must be a non-negative integer5 Hold SDA (or SCK) for delay time to meet the I2C start (or stop) condition. Needs to be specified according to slave devices.
CallbackName must be a valid C symbolsau_i2c_master_callback A user callback function can be provided. If this callback function is provided, it will be called from the interrupt service routine (ISR).
Transfer end interrupt priorityMCU Specific OptionsSelect transfer end interrupt priority. This is set for TEI interrupt.
Custom Rate (bps)Value must be a non-negative integer0 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

Clock Configuration

The SAU clock uses the system clock (ICLK) as its clock source.

A prescaler is applied to the ICLK in order to produce the operation clock frequency. The operation clock is used to generate the desired transfer period of the SAU module.

SAU operation clocks are shared among all channels within a SAU unit. Check the Hardware User's Manual for your MCU for available units and channels. SAU operation clock dividers are configurable in the Clocks tab.

The operation clock dividers are named SAU CKmn where m is the SAU unit, and n is the operation clock. For example, SAU CK01 applies to all SAU0 instances using CK1 as the operation clock (m=0, n=1).

Pin Configuration

The SAU 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

Enabling Single Channel By User With The SAU I2C

Enabling Start/Stop Condition By User With The SAU I2C

Interrupt Configuration

SAU I2C Master Rate Calculation

Selecting Operation Clock Frequency

The relationship between operation clock frequency and bitrate is: bitrate = f_mck / [ 2 * (SDRmn.STCLK + 1) ] where:

By plugging in the minimum and maximum SDRmn.STCLK values, the range of bitrates for a given operation clock frequency can be obtained.

Note that due to STCLK being set as discrete integers, the actual bitrate may not be exact. The actual bitrate and percent errors can be calculated by the formulas:

actual_bitrate = f_mck / [ 2 * (SDRmn.STCLK + 1) ]
percent_error = 100 * abs [(actual_bitrate - expected_bitrate) / expected_bitrate]

Using the fastest possible operation clock for the desired bitrate will result in the lowest deviation from the requested bitrate. Set the CKmn operation clock divider in the Clocks tab to select the desired operation clock frequency.

Enabling DTC with the SAU I2C

Multiple Channels Being Used In Same Unit

I2C Restart Support

Multiple Devices On The Bus

Limitations

Examples

Basic Example

This is a basic example of minimal use of the r_sau_i2c in an application. This example shows how this driver can be used for basic read and write operations.

void basic_example (void)
{
fsp_err_t err;
uint32_t i;
uint32_t timeout_ms = I2C_TRANSACTION_BUSY_DELAY;
/* Initialize the I2C module */
err = R_SAU_I2C_Open(&g_i2c_device_ctrl_1, &g_i2c_device_cfg_1);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
/* Write some data to the transmit buffer */
for (i = 0; i < I2C_BUFFER_SIZE_BYTES; i++)
{
g_i2c_tx_buffer[i] = (uint8_t) i;
}
/* Send data to I2C slave */
g_i2c_callback_event = I2C_MASTER_EVENT_ABORTED;
err = R_SAU_I2C_Write(&g_i2c_device_ctrl_1, &g_i2c_tx_buffer[0], I2C_BUFFER_SIZE_BYTES, false);
assert(FSP_SUCCESS == err);
/* Since there is nothing else to do, block until Callback triggers*/
while ((I2C_MASTER_EVENT_TX_COMPLETE != g_i2c_callback_event) && timeout_ms)
{
timeout_ms--;;
}
if (I2C_MASTER_EVENT_ABORTED == g_i2c_callback_event)
{
__BKPT(0);
}
/* Read data back from the I2C slave */
g_i2c_callback_event = I2C_MASTER_EVENT_ABORTED;
timeout_ms = I2C_TRANSACTION_BUSY_DELAY;
err = R_SAU_I2C_Read(&g_i2c_device_ctrl_1, &g_i2c_rx_buffer[0], I2C_BUFFER_SIZE_BYTES, false);
assert(FSP_SUCCESS == err);
/* Since there is nothing else to do, block until Callback triggers*/
while ((I2C_MASTER_EVENT_RX_COMPLETE != g_i2c_callback_event) && timeout_ms)
{
timeout_ms--;;
}
if (I2C_MASTER_EVENT_ABORTED == g_i2c_callback_event)
{
__BKPT(0);
}
/* Verify the read data */
if (0U != memcmp(g_i2c_tx_buffer, g_i2c_rx_buffer, I2C_BUFFER_SIZE_BYTES))
{
__BKPT(0);
}
}

Enabling Start/Stop Condition By User

This example demonstrates how to write code for SAU I2C communication when the call start/stop condtion by user is enabled.

void manual_trigger_condition_example (void)
{
fsp_err_t err;
uint32_t i;
uint32_t timeout_ms = I2C_TRANSACTION_BUSY_DELAY;
/* Initialize the I2C module */
err = R_SAU_I2C_Open(&g_i2c_device_ctrl_1, &g_i2c_device_cfg_1);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
/* Write some data to the transmit buffer */
for (i = 0; i < I2C_BUFFER_SIZE_BYTES; i++)
{
g_i2c_tx_buffer[i] = (uint8_t) i;
}
/* Send data to I2C slave */
g_i2c_callback_event = I2C_MASTER_EVENT_ABORTED;
err = R_SAU_I2C_Write(&g_i2c_device_ctrl_1, &g_i2c_tx_buffer[0], I2C_BUFFER_SIZE_BYTES, false);
assert(FSP_SUCCESS == err);
err = R_SAU_I2C_Start(&g_i2c_device_ctrl_1);
assert(FSP_SUCCESS == err);
/* Since there is nothing else to do, block until Callback triggers*/
while ((I2C_MASTER_EVENT_TX_COMPLETE != g_i2c_callback_event) && timeout_ms)
{
timeout_ms--;;
}
if (I2C_MASTER_EVENT_ABORTED == g_i2c_callback_event)
{
__BKPT(0);
}
err = R_SAU_I2C_Stop(&g_i2c_device_ctrl_1);
assert(FSP_SUCCESS == err);
/* Read data back from the I2C slave */
g_i2c_callback_event = I2C_MASTER_EVENT_ABORTED;
timeout_ms = I2C_TRANSACTION_BUSY_DELAY;
err = R_SAU_I2C_Read(&g_i2c_device_ctrl_1, &g_i2c_rx_buffer[0], I2C_BUFFER_SIZE_BYTES, false);
assert(FSP_SUCCESS == err);
err = R_SAU_I2C_Start(&g_i2c_device_ctrl_1);
assert(FSP_SUCCESS == err);
/* Since there is nothing else to do, block until Callback triggers*/
while ((I2C_MASTER_EVENT_RX_COMPLETE != g_i2c_callback_event) && timeout_ms)
{
timeout_ms--;;
}
err = R_SAU_I2C_Stop(&g_i2c_device_ctrl_1);
assert(FSP_SUCCESS == err);
if (I2C_MASTER_EVENT_ABORTED == g_i2c_callback_event)
{
__BKPT(0);
}
/* Verify the read data */
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 SAU I2C driver can be used to communicate with different slave devices which are on the same channel.

void single_channel_multi_slave (void)
{
fsp_err_t err;
uint32_t timeout_ms = I2C_TRANSACTION_BUSY_DELAY;
err = R_SAU_I2C_Open(&g_i2c_device_ctrl_2, &g_i2c_device_cfg_2);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
/* Clear the recieve buffer */
memset(g_i2c_rx_buffer, '0', I2C_BUFFER_SIZE_BYTES);
/* Read data from I2C slave */
g_i2c_callback_event = I2C_MASTER_EVENT_ABORTED;
err = R_SAU_I2C_Read(&g_i2c_device_ctrl_2, &g_i2c_rx_buffer[0], I2C_BUFFER_SIZE_BYTES, false);
assert(FSP_SUCCESS == err);
while ((I2C_MASTER_EVENT_RX_COMPLETE != g_i2c_callback_event) && timeout_ms)
{
timeout_ms--;;
}
if (I2C_MASTER_EVENT_ABORTED == g_i2c_callback_event)
{
__BKPT(0);
}
/* Send data to I2C slave on the same channel */
err = R_SAU_I2C_SlaveAddressSet(&g_i2c_device_ctrl_2, I2C_SLAVE_DISPLAY_ADAPTER, I2C_MASTER_ADDR_MODE_7BIT);
assert(FSP_SUCCESS == err);
g_i2c_tx_buffer[0] = (uint8_t) I2C_EXAMPLE_DATA_1;
g_i2c_tx_buffer[1] = (uint8_t) I2C_EXAMPLE_DATA_2;
g_i2c_callback_event = I2C_MASTER_EVENT_ABORTED;
timeout_ms = I2C_TRANSACTION_BUSY_DELAY;
err = R_SAU_I2C_Write(&g_i2c_device_ctrl_2, &g_i2c_tx_buffer[0], 2U, false);
assert(FSP_SUCCESS == err);
while ((I2C_MASTER_EVENT_TX_COMPLETE != g_i2c_callback_event) && timeout_ms)
{
timeout_ms--;;
}
if (I2C_MASTER_EVENT_ABORTED == g_i2c_callback_event)
{
__BKPT(0);
}
}

Data Structures

struct  sau_i2c_clock_settings_t
 
struct  sau_i2c_instance_ctrl_t
 
struct  sau_i2c_extended_cfg_t
 

Enumerations

enum  sau_i2c_operation_clock_t
 

Data Structure Documentation

◆ sau_i2c_clock_settings_t

struct sau_i2c_clock_settings_t

I2C clock settings

Data Fields
uint8_t stclk Bit rate register settings.
sau_i2c_operation_clock_t operation_clock I2C operating clock select.

◆ sau_i2c_instance_ctrl_t

struct sau_i2c_instance_ctrl_t

I2C control structure. DO NOT INITIALIZE.

Data Fields

i2c_master_cfg_t const * p_cfg
 Pointer to the configuration structure.
 
uint32_t open
 Flag to determine if the device is open.
 
R_SAU0_Type * p_reg
 Base register for this channel.
 
uint8_t * p_buff
 Holds the data associated with the transfer.
 
uint32_t total
 Holds the total number of data bytes to transfer.
 
uint32_t loaded
 Tracks the number of data bytes written to the register.
 
volatile bool read
 Holds the direction of the data byte transfer.
 
volatile bool restart
 Holds whether or not the restart should be issued when done.
 
volatile bool restarted
 Tracks whether or not a restart was issued during the previous transfer.
 
volatile bool do_dummy_read
 Tracks whether a dummy read is issued on the first RX.
 
uint8_t slave
 The address of the slave device.
 

◆ sau_i2c_extended_cfg_t

struct sau_i2c_extended_cfg_t

SAU I2C extended configuration

Data Fields
sau_i2c_clock_settings_t clock_settings I2C clock settings.
uint8_t delay_time The delay time of the slave device.
uint8_t i2c_unit The SAU unit corresponding to the selected channel.

Enumeration Type Documentation

◆ sau_i2c_operation_clock_t

Operation clock

Enumerator
SAU_I2C_MASTER_OPERATION_CLOCK_CK0 

Operating clock select CK0.

SAU_I2C_MASTER_OPERATION_CLOCK_CK1 

Operating clock select CK1.

Function Documentation

◆ R_SAU_I2C_Open()

fsp_err_t R_SAU_I2C_Open ( i2c_master_ctrl_t *const  p_api_ctrl,
i2c_master_cfg_t const *const  p_cfg 
)

Opens the SAU device.

Return values
FSP_SUCCESSRequested clock rate was set exactly.
FSP_ERR_ALREADY_OPENModule is already open.
FSP_ERR_ASSERTIONParameter check failure due to one or more reasons below:
  1. p_api_ctrl or p_cfg is NULL.
  2. extended parameter is NULL.
  3. Callback parameter is NULL.
  4. Clock rate requested is greater than 400KHz
  5. Invalid IRQ number assigned

◆ R_SAU_I2C_Read()

fsp_err_t R_SAU_I2C_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.

Return values
FSP_SUCCESSFunction executed without issue.
FSP_ERR_ASSERTIONThe parameter p_api_ctrl, p_dest is NULL, bytes is 0.
FSP_ERR_INVALID_SIZEProvided number of bytes more than uint16_t size (65535) while DTC is used for data transfer.
FSP_ERR_NOT_OPENInstance control block is not open.

◆ R_SAU_I2C_Write()

fsp_err_t R_SAU_I2C_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.

This function will fail if there is already an in-progress I2C transfer on the associated channel. Otherwise, the I2C write operation will begin. The write operation is non-blocking and the caller will be notified when the operation has finished by an I2C_EVENT_TX_COMPLETE in the callback.

Return values
FSP_SUCCESSFunction executed without issue.
FSP_ERR_ASSERTIONp_api_ctrl, p_src is NULL.
FSP_ERR_INVALID_SIZEProvided number of bytes more than uint16_t size (65535) while DTC is used for data transfer.
FSP_ERR_NOT_OPENInstance control block is not open.

◆ R_SAU_I2C_Abort()

fsp_err_t R_SAU_I2C_Abort ( i2c_master_ctrl_t *const  p_api_ctrl)

Aborts any in-progress transfer and forces the I2C peripheral into a ready state.

This function will safely terminate any in-progress I2C transfer with the device. If a transfer is aborted, the user will be notified via callback with an abort event.

Return values
FSP_SUCCESSTransaction was aborted without issue.
FSP_ERR_ASSERTIONp_ctrl is NULL.
FSP_ERR_NOT_OPENInstance control block is not open.

◆ R_SAU_I2C_SlaveAddressSet()

fsp_err_t R_SAU_I2C_SlaveAddressSet ( i2c_master_ctrl_t *const  p_api_ctrl,
uint32_t const  slave,
i2c_master_addr_mode_t const  addr_mode 
)

Sets address of the slave device.

This function is used to set the device address of the slave without reconfiguring the entire bus.

Return values
FSP_SUCCESSAddress of the slave is set correctly.
FSP_ERR_ASSERTIONp_ctrl or address is NULL.
FSP_ERR_NOT_OPENInstance control block is not open.
FSP_ERR_IN_USEAn I2C Transaction is in progress.

◆ R_SAU_I2C_CallbackSet()

fsp_err_t R_SAU_I2C_CallbackSet ( i2c_master_ctrl_t *const  p_api_ctrl,
void(*)(i2c_master_callback_args_t *)  p_callback,
void const *const  p_context,
i2c_master_callback_args_t *const  p_callback_memory 
)

Updates the user callback.

Note
p_callback_memory is not used in this implementation and can be set to NULL.

Implements i2c_master_api_t::callbackSet

Return values
FSP_SUCCESSCallback updated successfully.
FSP_ERR_ASSERTIONA required pointer is NULL.
FSP_ERR_NOT_OPENThe control block has not been opened.

◆ R_SAU_I2C_StatusGet()

fsp_err_t R_SAU_I2C_StatusGet ( i2c_master_ctrl_t *const  p_api_ctrl,
i2c_master_status_t p_status 
)

Provides driver status.

Return values
FSP_SUCCESSStatus stored in p_status.
FSP_ERR_ASSERTIONNULL pointer.

◆ R_SAU_I2C_Close()

fsp_err_t R_SAU_I2C_Close ( i2c_master_ctrl_t *const  p_api_ctrl)

Closes the I2C device. Power down I2C peripheral.

This function will safely terminate any in-progress I2C transfer with the device. If a transfer is aborted, the user will be notified via callback with an abort event.

Return values
FSP_SUCCESSDevice closed without issue.
FSP_ERR_ASSERTIONThe parameter p_ctrl is NULL.
FSP_ERR_NOT_OPENInstance control block is not open.

◆ R_SAU_I2C_Start()

fsp_err_t R_SAU_I2C_Start ( sau_i2c_instance_ctrl_t *const  p_ctrl)

This function starts/restarts the IIC condition.

Parameters
[in]p_ctrlInstance control structure.

◆ R_SAU_I2C_Stop()

fsp_err_t R_SAU_I2C_Stop ( sau_i2c_instance_ctrl_t *const  p_ctrl)

This function stops the IIC condition.

Parameters
[in]p_ctrlInstance control structure.