RA Flexible Software Package Documentation  Release v5.5.0

 
SMBUS Communication Device (rm_comms_smbus)

Functions

fsp_err_t RM_COMMS_SMBUS_Open (rm_comms_ctrl_t *const p_api_ctrl, rm_comms_cfg_t const *const p_cfg)
 Opens and configures the SMBUS Comms module. Implements rm_comms_api_t::open. More...
 
fsp_err_t RM_COMMS_SMBUS_Close (rm_comms_ctrl_t *const p_api_ctrl)
 Disables specified SMBUS Comms module. Implements rm_comms_api_t::close. More...
 
fsp_err_t RM_COMMS_SMBUS_CallbackSet (rm_comms_ctrl_t *const p_api_ctrl, void(*p_callback)(rm_comms_callback_args_t *), void const *const p_context)
 Updates the SMBUS Comms callback. Implements rm_comms_api_t::callbackSet. More...
 
fsp_err_t RM_COMMS_SMBUS_Read (rm_comms_ctrl_t *const p_api_ctrl, uint8_t *const p_dest, uint32_t const bytes)
 Performs a read from the SMBUS device. Implements rm_comms_api_t::read. More...
 
fsp_err_t RM_COMMS_SMBUS_Write (rm_comms_ctrl_t *const p_api_ctrl, uint8_t *const p_src, uint32_t const bytes)
 Performs a write from the SMBUS device. Implements rm_comms_api_t::write. More...
 
fsp_err_t RM_COMMS_SMBUS_WriteRead (rm_comms_ctrl_t *const p_api_ctrl, rm_comms_write_read_params_t const write_read_params)
 Performs a write to, then a read from the SMBUS device. Implements rm_comms_api_t::writeRead. More...
 
void rm_comms_smbus_transmission_callback (i2c_master_callback_args_t *p_args)
 Common callback function called in the I2C driver callback function when SMBus is used.
 
void rm_comms_smbus_timeout_callback (timer_callback_args_t *p_args)
 Callback function called in the GPT driver callback function when SMBus is used.
 

Detailed Description

Middleware to implement the SMBUS communications interface. This module implements the Communicatons Middleware Interface.

Overview

The RM_COMMS_SMBUS module implements COMMS API for SMBUS interface.

Features

Supported SMBUS command:

Packet error check is supported by software CRC-8 (x^8 + x^2 + x + 1).

Supported RTOS (FreeRTOS and AzureOS).

Configuration

Build Time Configurations for rm_comms_smbus

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

ConfigurationOptionsDefaultDescription
Parameter Checking
  • Default (BSP)
  • Enabled
  • Disabled
Default (BSP) If selected code for parameter checking is included in the build.

Configurations for Connectivity > SMBus Communication Device (rm_comms_smbus)

This module can be added to the Stacks tab via New Stack > Connectivity > SMBus Communication Device (rm_comms_smbus).

ConfigurationOptionsDefaultDescription
NameManual Entryg_comms_smbus0 Module name.
CallbackName must be a valid C symbolcomms_smbus_callback A user callback function can be provided.
Semaphore Timeout (RTOS only)Value must be a non-negative integer0xFFFFFFFF Timeout for semaphore operation in using RTOS.
Slave AddressValue must be non-negative0x00 Specify the slave address.
CRC support
  • Enable
  • Disable
Enable Use CRC-8 algorithm to generate PEC byte for SMBus communication.

Pin Configuration

This module uses SDA and SCL pins of I2C Master

Usage Notes

If an RTOS is used, blocking and bus lock is available.

If an RTOS is used and blocking and bus lock is enabled, RM_COMMS_SMBUS_Write(), RM_COMMS_SMBUS_Read() and RM_COMMS_SMBUS_WriteRead() cannot be called in callback.

Dependency module General PWM Timer (GPT) and Event Link Controller (ELC) need to be openned before opening SMBus comms device.

Protocol support by SMBUS API:

Warning
The recommended frequency of PCLKB (when using r_iic_master) or I3CCLK (when using r_iic_b_master) is in range of 1 MHz - 86 MHz. If the frequency too high, the middleware will not able to meet the 300 ns of data hold time of SMBUS standard. On the contrary, the low frequency may cause the count of BRL smaller than SDA delay count which will lead to communication between devices might malfunction or falsely indicate a start or stop condition, depending on the bus state.

Bus Initialization

The SMBUS communications interface expects a bus instance to be opened before opening any specific SMBUS comms device. The communications interface will handle switching between devices on the bus but will not open or close the bus instance. The user should open the bus with the appropriate SMBUS Communication Device (rm_comms_smbus) open call.

Examples

Basic Example

This is a basic example of minimal use of SMBus communications implementation in an application.

void rm_comms_smbus_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
/* Open the relevant drivers if it is not already open. */
rm_comms_i2c_bus_extended_cfg_t * p_comms_i2c_extend =
((rm_comms_smbus_extended_cfg_t *) (g_comms_smbus_cfg.p_extend))->p_comms_i2c_extend_cfg;
i2c_master_instance_t * p_driver_iic = (i2c_master_instance_t *) p_comms_i2c_extend->p_driver_instance;
elc_instance_t * p_driver_elc = (elc_instance_t *) p_comms_i2c_extend->p_elc;
timer_instance_t * p_driver_timer = (timer_instance_t *) p_comms_i2c_extend->p_timer;
p_driver_iic->p_api->open(p_driver_iic->p_ctrl, p_driver_iic->p_cfg);
p_driver_elc->p_api->open(p_driver_elc->p_ctrl, p_driver_elc->p_cfg);
p_driver_timer->p_api->open(p_driver_timer->p_ctrl, p_driver_timer->p_cfg);
#if (BSP_CFG_RTOS != 0)
/* Create a semaphore for blocking if a semaphore is not NULL */
if (NULL != p_comms_i2c_extend->p_blocking_semaphore)
{
#if (BSP_CFG_RTOS == 1) // AzureOS
tx_semaphore_create(p_comms_i2c_extend->p_blocking_semaphore->p_semaphore_handle,
p_comms_i2c_extend->p_blocking_semaphore->p_semaphore_name,
(ULONG) 0);
#elif (BSP_CFG_RTOS == 2) // FreeRTOS
*(p_comms_i2c_extend->p_blocking_semaphore->p_semaphore_handle) =
xSemaphoreCreateCountingStatic((UBaseType_t) 1,
(UBaseType_t) 0,
p_comms_i2c_extend->p_blocking_semaphore->p_semaphore_memory);
#endif
}
/* Create a recursive mutex for bus lock if a recursive mutex is not NULL */
if (NULL != p_comms_i2c_extend->p_bus_recursive_mutex)
{
#if (BSP_CFG_RTOS == 1) // AzureOS
tx_mutex_create(p_comms_i2c_extend->p_bus_recursive_mutex->p_mutex_handle,
p_comms_i2c_extend->p_bus_recursive_mutex->p_mutex_name,
TX_INHERIT);
#elif (BSP_CFG_RTOS == 2) // FreeRTOS
*(p_comms_i2c_extend->p_bus_recursive_mutex->p_mutex_handle) =
xSemaphoreCreateRecursiveMutexStatic(p_comms_i2c_extend->p_bus_recursive_mutex->p_mutex_memory);
#endif
}
#endif
err = RM_COMMS_SMBUS_Open(&g_comms_smbus_ctrl, &g_comms_smbus_cfg);
assert(FSP_SUCCESS == err);
err = RM_COMMS_SMBUS_CallbackSet(&g_comms_smbus_ctrl, comms_smbus_callback, NULL);
assert(FSP_SUCCESS == err);
g_write_read_param.p_dest = g_read_buffer;
g_write_read_param.p_src = g_write_buffer;
/* SMBus send byte command */
g_smbus_callback_args.event = (rm_comms_event_t) INITIALIZE_EVENT;
err = RM_COMMS_SMBUS_Write(&g_comms_smbus_ctrl, g_write_buffer, 1);
assert(FSP_SUCCESS == err);
wait_for_transmission();
assert(RM_COMMS_EVENT_OPERATION_COMPLETE == g_smbus_callback_args.event);
assert(RM_COMMS_SMBUS_NO_ERROR == g_smbus_error->smbus_event);
/* SMBus receive byte command */
g_smbus_callback_args.event = (rm_comms_event_t) INITIALIZE_EVENT;
err = RM_COMMS_SMBUS_Read(&g_comms_smbus_ctrl, g_read_buffer, 2); // 1 byte for data, 1 byte for PEC.
assert(FSP_SUCCESS == err);
wait_for_transmission();
assert(RM_COMMS_EVENT_OPERATION_COMPLETE == g_smbus_callback_args.event);
assert(RM_COMMS_SMBUS_NO_ERROR == g_smbus_error->smbus_event);
/* SMBus write byte command */
g_smbus_callback_args.event = (rm_comms_event_t) INITIALIZE_EVENT;
g_write_buffer[0] = (uint8_t) SMBUS_COMMAND_CODE;
g_write_buffer[1] = (uint8_t) SMBUS_DUMMY_WRITE_DATA;
err = RM_COMMS_SMBUS_Write(&g_comms_smbus_ctrl, g_write_buffer, 2); // 1 byte for command code, 1 byte for data. PEC byte will be padded automatically.
assert(FSP_SUCCESS == err);
wait_for_transmission();
assert(RM_COMMS_EVENT_OPERATION_COMPLETE == g_smbus_callback_args.event);
assert(RM_COMMS_SMBUS_NO_ERROR == g_smbus_error->smbus_event);
/* SMBus read byte command */
g_smbus_callback_args.event = (rm_comms_event_t) INITIALIZE_EVENT;
g_write_buffer[0] = (uint8_t) SMBUS_COMMAND_CODE;
g_write_read_param.src_bytes = 1; // 1 byte of command code
g_write_read_param.dest_bytes = 2; // 1 data byte + 1 PEC byte
err = RM_COMMS_SMBUS_WriteRead(&g_comms_smbus_ctrl, g_write_read_param);
assert(FSP_SUCCESS == err);
wait_for_transmission();
assert(RM_COMMS_EVENT_OPERATION_COMPLETE == g_smbus_callback_args.event);
assert(RM_COMMS_SMBUS_NO_ERROR == g_smbus_error->smbus_event);
/* SMBus write word */
g_smbus_callback_args.event = (rm_comms_event_t) INITIALIZE_EVENT;
g_write_buffer[0] = (uint8_t) SMBUS_COMMAND_CODE;
g_write_buffer[1] = (uint8_t) SMBUS_DUMMY_WRITE_DATA; // Data byte low
g_write_buffer[2] = (uint8_t) SMBUS_DUMMY_WRITE_DATA; // Data byte high
err = RM_COMMS_SMBUS_Write(&g_comms_smbus_ctrl, g_write_buffer, 3);
assert(FSP_SUCCESS == err);
wait_for_transmission();
assert(RM_COMMS_EVENT_OPERATION_COMPLETE == g_smbus_callback_args.event);
assert(RM_COMMS_SMBUS_NO_ERROR == g_smbus_error->smbus_event);
/* SMBus read word */
g_smbus_callback_args.event = (rm_comms_event_t) INITIALIZE_EVENT;
g_write_buffer[0] = (uint8_t) SMBUS_COMMAND_CODE;
g_write_read_param.src_bytes = 1; // 1 byte of command code
g_write_read_param.dest_bytes = 3; // 2 data byte + 1 PEC byte
err = RM_COMMS_SMBUS_WriteRead(&g_comms_smbus_ctrl, g_write_read_param);
assert(FSP_SUCCESS == err);
wait_for_transmission();
assert(RM_COMMS_EVENT_OPERATION_COMPLETE == g_smbus_callback_args.event);
assert(RM_COMMS_SMBUS_NO_ERROR == g_smbus_error->smbus_event);
/* SMBus read block */
g_smbus_callback_args.event = (rm_comms_event_t) INITIALIZE_EVENT;
g_write_buffer[0] = (uint8_t) SMBUS_COMMAND_CODE;
g_write_read_param.src_bytes = 1; // 1 byte of command code
g_write_read_param.dest_bytes = 10; // 1 block count byte + 8 data byte + 1 PEC byte
err = RM_COMMS_SMBUS_WriteRead(&g_comms_smbus_ctrl, g_write_read_param);
assert(FSP_SUCCESS == err);
wait_for_transmission();
assert(RM_COMMS_EVENT_OPERATION_COMPLETE == g_smbus_callback_args.event);
assert(RM_COMMS_SMBUS_NO_ERROR == g_smbus_error->smbus_event);
}

Data Structures

struct  rm_comms_smbus_error_t
 
struct  rm_comms_smbus_extended_cfg_t
 
struct  rm_comms_smbus_instance_ctrl_t
 

Enumerations

enum  rm_comms_smbus_event_t
 

Data Structure Documentation

◆ rm_comms_smbus_error_t

struct rm_comms_smbus_error_t

SMBus error structure

◆ rm_comms_smbus_extended_cfg_t

struct rm_comms_smbus_extended_cfg_t

Extend configuration of SMBus

Data Fields
bool pec_enable Calculate PEC byte for SMBus transmission.
rm_comms_i2c_bus_extended_cfg_t * p_comms_i2c_extend_cfg Pointer to extend configuration block of rm_comms_i2c.
rm_comms_i2c_instance_ctrl_t * p_comms_i2c_ctrl Control block of rm_comms_i2c.

◆ rm_comms_smbus_instance_ctrl_t

struct rm_comms_smbus_instance_ctrl_t

SMBus middleware control block

Data Fields
bool timer_is_enabled Validate that external event triggers stop the timer is enabled.
uint8_t write_buff[RM_COMMS_SMBUS_TRANSMISSION_MAX_BYTES] Intermediate buffer.
uint8_t receive_crc_seed CRC seed value.
uint32_t open Open flag.
rm_comms_i2c_instance_ctrl_t * p_comms_i2c_ctrl Control block of rm_comms_i2c.
rm_comms_smbus_error_t * p_smbus_error SMBus specific error code.
const void * p_context

Enumeration Type Documentation

◆ rm_comms_smbus_event_t

SMBus specific event

Enumerator
RM_COMMS_SMBUS_NO_ERROR 

SMBus transmission complete without any error.

RM_COMMS_SMBUS_MISC_ERROR 

Dependency modules failed.

RM_COMMS_SMBUS_DATA_CORRUPT 

PEC byte is incorrect.

RM_COMMS_SMBUS_SEXT_TIMEOUT 

Total transmission time exceeded 25 ms.

RM_COMMS_SMBUS_MEXT_TIMEOUT 

Transmission time between each event exceeded 10 ms.

Function Documentation

◆ RM_COMMS_SMBUS_Open()

fsp_err_t RM_COMMS_SMBUS_Open ( rm_comms_ctrl_t *const  p_api_ctrl,
rm_comms_cfg_t const *const  p_cfg 
)

Opens and configures the SMBUS Comms module. Implements rm_comms_api_t::open.

Return values
FSP_SUCCESSCommunications Middle module successfully configured.
FSP_ERR_ASSERTIONNull pointer, or one or more configuration options is invalid.
FSP_ERR_ALREADY_OPENModule is already open. This module can only be opened once.
Returns
See Common Error Codes or functions called by this function for other possible return codes.

◆ RM_COMMS_SMBUS_Close()

fsp_err_t RM_COMMS_SMBUS_Close ( rm_comms_ctrl_t *const  p_api_ctrl)

Disables specified SMBUS Comms module. Implements rm_comms_api_t::close.

Return values
FSP_SUCCESSSuccessfully closed.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not open.

◆ RM_COMMS_SMBUS_CallbackSet()

fsp_err_t RM_COMMS_SMBUS_CallbackSet ( rm_comms_ctrl_t *const  p_api_ctrl,
void(*)(rm_comms_callback_args_t *)  p_callback,
void const *const  p_context 
)

Updates the SMBUS Comms callback. Implements rm_comms_api_t::callbackSet.

Return values
FSP_SUCCESSSuccessfully set.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not open.

◆ RM_COMMS_SMBUS_Read()

fsp_err_t RM_COMMS_SMBUS_Read ( rm_comms_ctrl_t *const  p_api_ctrl,
uint8_t *const  p_dest,
uint32_t const  bytes 
)

Performs a read from the SMBUS device. Implements rm_comms_api_t::read.

Note
When Packet Error Check (PEC) is used, size of destination buffer and the number of reading bytes must have 1-byte in addition for PEC byte.
Return values
FSP_SUCCESSSuccessfully data decoded.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not open.
FSP_ERR_INVALID_SIZERead data size is invalid.
Returns
See Common Error Codes or functions called by this function for other possible return codes.

◆ RM_COMMS_SMBUS_Write()

fsp_err_t RM_COMMS_SMBUS_Write ( rm_comms_ctrl_t *const  p_api_ctrl,
uint8_t *const  p_src,
uint32_t const  bytes 
)

Performs a write from the SMBUS device. Implements rm_comms_api_t::write.

Return values
FSP_SUCCESSSuccessfully writing data .
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not open.
FSP_ERR_INVALID_SIZETransfer data size is invalid.
Returns
See Common Error Codes or functions called by this function for other possible return codes.

◆ RM_COMMS_SMBUS_WriteRead()

fsp_err_t RM_COMMS_SMBUS_WriteRead ( rm_comms_ctrl_t *const  p_api_ctrl,
rm_comms_write_read_params_t const  write_read_params 
)

Performs a write to, then a read from the SMBUS device. Implements rm_comms_api_t::writeRead.

Note
When Packet Error Check (PEC) is used, size of destination buffer and the number of reading bytes must have 1-byte in addition for PEC byte.
Return values
FSP_SUCCESSSuccessfully data decoded.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not open.
FSP_ERR_INVALID_SIZETransfer data size is invalid.
Returns
See Common Error Codes or functions called by this function for other possible return codes.