CAT2 Peripheral Driver Library
IsoUART (Isolated UART)

The iso UART is a point-to-point differential current edge-triggered UART interface for communication with the other battery management system (BMS) ICs. More...

Modules

 Macros
 
 Functions
 
 Data Structures
 
 Enumerated Types
 

Detailed Description

The iso UART is a point-to-point differential current edge-triggered UART interface for communication with the other battery management system (BMS) ICs.

Note
Supported on PSOC™ 4 HVPA SPM only.

The functions and other declarations used in this driver are in cy_isouart.h. You can include cy_pdl.h to get access to all functions and declarations in the PDL.

Overview

The iso UART can be configured to operate in different modes: Master (Host) or Slave (Node). This protocol consists of a single master device and multiple slave devices. The master device can address the slave devices using node-id and block id. It provides galvanic isolation with UART-style frames (start bit, stop bit, 8 data bits, zero parity bits), and has high robustness against external noise.

Physical Interfaces

The iso UART communicates via two physical links: high side interface (IFH) and low side interface (IFL). Both high and low side interfaces can drive the differential lines (TX) and both have a differential receiver circuit (RX). This offers the necessary isolation to guarantee error-free communication between different modules in the battery system. The interface allowed to drive the bus lines is determined by the bus timing protocol.

Topologies

The protocol supports up to 30 devices in a single chain using device IDs. This can be extended to more than 30 devices using Block ID. Block ID can also be used to group devices and limit the number of devices responding to broadcast messages. There are two possible topologies: Master-on-Bottom (MOB) and Master-on-Top (MOT). These topologies can also be optionally wired as complete loops (Ring).

isouart_topologies.png
MOT, MOB and Ring topology

Master-on-Top (MOT):

Master-on-Bottom (MOB):

Ring Topologies (MOT-Ring, MOB-Ring):

Both high side (IFH) and low side (IFL) interfaces can act as transmitters and receivers. Nodes automatically detect the wake signal source and configure their internal multiplexer to receive commands from the appropriate interface while simultaneously forwarding frames through the chain via the opposite interface. When transmitting a response, the slave transmits on both High and Low interfaces simultaneously.

Command Types

The iso UART protocol supports six command types for Host-Node communication, with two main categories: write and read requests that differ primarily in Address/ID field content. All frames are hardware-interpreted and use 8-bit data with full CRC protection (no parity). The protocol tolerates frequency mismatch between Host and Node transmissions and supports broadcast operations.

isouart_commands.png
Possible Master to Slave communication commands

Write Commands:
The Host can write data to Node registers or SRAM locations using several write command types:

When executing write commands, Nodes return Write Reply messages containing operation status information (CRC, status flags, error bits) stored in HIGH_INTERFACE_READ or LOW_INTERFACE_READ registers. Standard Write commands receive a response from the addressed Node, while Broadcast Write commands receive a response from the final Node in the chain. It is essential for broadcast write mode that the final Node in the chain must be properly marked with FN=1 (Final Node flag) during the enumeration process. If no Node has FN=1 set, Broadcast Write commands will not receive any Write Reply frame, resulting in a FRAME ERROR. This configuration is essential for proper broadcast communication functionality.

Read Commands:
The Host can read data from Node registers or SRAM locations using several read command types:

Two non-data notifications commands:

SRAM

The iso UART block contains the 128 x 32-bit SRAM, which serves as the primary memory for data storage and exchange. It is the only interface between the iso UART peripheral and the rest of the chip via CPU or DMA. The SRAM defaults to an unexpected state and must be initialized and divided before iso UART block is enabled.

SRAM Word Structure (32 bits):

The 128-word SRAM can be divided into two parts Low and High, with each part being dedicated to store data received from corresponding interface in certain receive modes.

The iso UART provides three distinct receiver modes that determine how incoming frame data is processed and stored in SRAM:

In Unpacked and Raw modes, data is written to both SRAM and interface registers, with optional ECC calculation for enhanced data integrity protection. Register mode writes data only to interface registers without using SRAM.

Configuration Considerations

Device Configurator Setup

The ModusToolbox Device Configurator provides a graphical user interface to configure the iso UART peripheral. This tool automatically generates initialization code and configuration structures based on your settings.

To use the Device Configurator:

  1. Open the ModusToolbox Device Configurator from your project.
  2. Navigate to the "Peripherals" tab and under "Communication" group enable "Iso UART" block.
  3. Choose the operation mode (Host or Node).
  4. Configure basic parameters like topology, bit rate, and CRC policy.
  5. Save the configuration to generate the initialization code.

After Device Configurator is set up, the initialization structures, clocks, peripheral clock dividers, GPIOs, and other peripheral configuration code are auto-generated and placed in ../bsps/TARGET_APP_.../config directory files.
Place the call of the cybsp_init() function before using any iso UART API functions to ensure initialization of all external resources required for the iso UART operation.

Host Configuration

To set up the iso UART driver in the Host mode, provide the configuration parameters in the cy_stc_isouart_host_config_t structure. Host configuration requires careful consideration of topology, receiver mode, CRC policy, block ID usage, and multi-read settings to match those configured on the nodes in the physical chain setup. To initialize the driver, call the Cy_ISOUART_HostInit function providing a pointer to the populated cy_stc_isouart_host_config_t structure.

/* Populate Host configuration structure */
const cy_stc_isouart_host_config_t hostConfig =
{
.topology = CY_ISOUART_MOT, /* Master-on-Top topology. */
.hostBitrate = CY_ISOUART_HOST_BITRATE_2_1MBPS, /* 2.1 Mbps data rate. */
.receiverMode = CY_ISOUART_RECEIVER_MODE_UNPACKED, /* Unpacked receive mode. */
.crcPolicy = CY_ISOUART_CRC8_SAE_J1850, /* CRC8 SAE J1850 polynomial. */
.enableBlockId = true, /* Enable Block ID feature. */
.useWriteDoneTrig = false, /* No trigger on write complete. */
.useLowSramFullTrig = false, /* No trigger when low SRAM full. */
.useHighSramFullTrig = false, /* No trigger when high SRAM full. */
.enableMultiReadBC = false, /* Disable broadcast multi-read. */
.enableInternalLoopback = false, /* Disable internal loopback. */
};
/* Configure iso UART Host to operate */
Cy_ISOUART_HostInit(ISOUART, &hostConfig);

Node Configuration

To set up the iso UART driver in the Node mode, provide the configuration parameters in the cy_stc_isouart_node_config_t structure. Node configuration must be compatible with the host configuration, especially regarding CRC policy, Block ID usage, and multi-read settings. To initialize the driver, call Cy_ISOUART_NodeInit function providing a pointer to the populated cy_stc_isouart_node_config_t structure.

/* Populate Node configuration structure */
const cy_stc_isouart_node_config_t nodeConfig =
{
.crcPolicy = CY_ISOUART_CRC8_SAE_J1850, /* Match host CRC policy. */
.enableBlockId = true, /* Enable if host uses Block ID. */
.useTrig0Emm = false, /* No emergency mode trigger 0. */
.useTrig1Emm = false, /* No emergency mode trigger 1. */
.useTrig2Emm = false, /* No emergency mode trigger 2. */
.useTrig3Emm = false, /* No emergency mode trigger 3. */
.enableMultiReadBC = false, /* Disable broadcast multi-read. */
.baseAddressA = 0UL, /* Base address A for multi-read. */
.baseAddressB = 0UL, /* Base address B for multi-read. */
};
/* Configure iso UART Node to operate */
Cy_ISOUART_NodeInit(ISOUART, &nodeConfig);

Clock Configuration

The iso UART block requires proper configuration of high frequency clock (HFCLK) and peripheral dividers to operate at 24 MHz. This clock is configured using the SysClk (System Clock) driver API.

/* This example assumes that the HFCLK has already been initialized to 24MHz before this APIs is called.
* Therefore, it simply enables peripheral divider with no divider.
*/
#define CLK_DIV_TYPE (CY_SYSCLK_DIV_16_BIT)
#define CLK_DIV_NUM (1UL)
#define CLK_DIV_VALUE (0UL)
Cy_SysClk_PeriphDisableDivider(CLK_DIV_TYPE, CLK_DIV_NUM); /* Disable divider before configuring. */
Cy_SysClk_PeriphAssignDivider(PCLK_ISOUART_CLOCK_IUART, CLK_DIV_TYPE, CLK_DIV_NUM); /* Assign divider to the iso UART clock. */
Cy_SysClk_PeriphSetDivider(CLK_DIV_TYPE, CLK_DIV_NUM, CLK_DIV_VALUE); /* Set divider 0 resulting 24MHz. */
Cy_SysClk_PeriphEnableDivider(CLK_DIV_TYPE, CLK_DIV_NUM); /* Enable the divider. */

Interrupt Configuration

The iso UART can use interrupts to handle communication events. Configuration flow includes setting up the interrupt service routine (ISR) and enabling the appropriate interrupt sources.

/* Assign iso UART interrupt number and priority. */
#define CY_ISOUART_INTR_NUM ((IRQn_Type) isouart_interrupt_IRQn)
#define CY_ISOUART_INTR_PRIORITY (3UL)
/* Populate configuration structure. */
cy_stc_sysint_t IntrConfig =
{
.intrSrc = CY_ISOUART_INTR_NUM,
.intrPriority = CY_ISOUART_INTR_PRIORITY,
};
(void) Cy_SysInt_Init(&IntrConfig, &IntrHandler); /* Initialize system interrupt with handler */
NVIC_ClearPendingIRQ(IntrConfig.intrSrc); /* Clear any pending interrupts */
NVIC_EnableIRQ(IntrConfig.intrSrc); /* Enable interrupt in NVIC */

Enable Iso UART

The iso UART must be enabled to operate. This includes enabling the peripheral and global interrupts.

/* Enable iso UART to operate. */
/* Enable global interrupts. */
__enable_irq();

Multi-Read Configuration

The multi-read feature allows reading multiple registers from a Node using pre-configured address ranges. To use this feature, the multi-read configuration must be set via broadcast write before use.

/* Scenario: Configure multi-read settings for nodes.
* This example demonstrates configuring the multi-read configuration register
* for PSOC 4 HVPA SPM 1.0 and writing it to all nodes at once using a broadcast write command.
*/
/* ISOUART_MULTI_READ_CFG bit fields for PSOC4 HVPA SPM 1.0
* See Architecture Reference Manual for detailed bit field descriptions.
*/
#define ISOUART_MULTI_READ_CFG_NUM_A_Pos (0UL)
#define ISOUART_MULTI_READ_CFG_SUBTRACT_A_Pos (4UL)
#define ISOUART_MULTI_READ_CFG_NUM_B_Pos (5UL)
#define ISOUART_MULTI_READ_CFG_SUBTRACT_B_Pos (8UL)
#define ISOUART_MULTI_READ_CFG_DUMMY_DATA_Pos (9UL)
#define ISOUART_BROADCAST_ID (63U)
const uint32_t blockId = 0UL; /* Applied block ID (Applicable if block ID is enabled). */
/* Prepare multi-read configuration data. */
uint16_t multiReadNumA = 3U; /* Number of reads from Base Address A (exclusive). */
uint16_t keepLastAddrA = 1U; /* Do not subtract from reads from Base Address A. */
uint16_t multiReadNumB = 5U; /* Number of reads from Base Address B (exclusive). */
uint16_t keepLastAddrB = 1U; /* Do not subtract from reads from Base Address B. */
uint16_t dummyDataNum = 0U; /* Number of dummy reads after reads from Base Address A and Base Address B. */
uint16_t multiReadConfig = 0U;
multiReadConfig |= multiReadNumA << ISOUART_MULTI_READ_CFG_NUM_A_Pos;
multiReadConfig |= keepLastAddrA << ISOUART_MULTI_READ_CFG_SUBTRACT_A_Pos;
multiReadConfig |= multiReadNumB << ISOUART_MULTI_READ_CFG_NUM_B_Pos;
multiReadConfig |= keepLastAddrB << ISOUART_MULTI_READ_CFG_SUBTRACT_B_Pos;
multiReadConfig |= dummyDataNum << ISOUART_MULTI_READ_CFG_DUMMY_DATA_Pos;
/* Send multi-read configuration to all Nodes at once using broadcast write command. */
Cy_ISOUART_HostSendWriteCommand(ISOUART, blockId, ISOUART_BROADCAST_ID, CY_ISOUART_ADDR_MULTI_READ_CFG, multiReadConfig);

Common Use Cases

This section demonstrates a typical iso UART Host and Node implementation using the following configuration:

Host Use Case

This section demonstrates how to configure a Host to communicate with Nodes in the chain. The Host can be configured using either auto-generated code from Device Configurator Setup or manual configuration as described in Host Configuration, Clock Configuration, Interrupt Configuration, and Enable Iso UART sections.

Enumeration Process
Before starting communication, the Host must enumerate each Node in the chain to assign unique IDs. This process is required at a startup and after a wake-up from Sleep mode, as Node-IDs are reset to 0. The Host sequentially assigns IDs by sending write commands to Device ID 0, starting from 1. Every enumerated Node starts forwarding messages which allow access to the next Node with ID 0. This continues until all Nodes receive consecutive IDs, with the final Node marked appropriately:

/* Scenario: Perform node enumeration in Master-on-Top topology.
* This process assigns a unique ID to a node and configures it as the final node in the chain.
* This example uses polling to wait for command completion instead of interrupt-driven approach.
*/
const uint32_t blockId = 0UL; /* Applied block ID (Applicable if block ID is enabled). */
const uint32_t nodeId = 1UL; /* Applied ID to the node, must start from 0 and sequential. */
const bool isFinalNode = true; /* Specify the node is the last node in the chain, this config affects broadcast command. */
/* For the 1st command, enable the wakeup sequence to awake nodes in the chain.
* This request is one-shot, no need to send a wakeup sequence other than the 1st command.
* The wakeup delay depends on the nodes in the chain, the delay allows nodes to set up themselves to react to commands.
*/
/* Prepare node configuration data. */
const uint16_t configData = (nodeId | (blockId << 6UL) | (isFinalNode << 11UL));
/* Send the configuration command into the bus.
* Node ID in the enumeration command must be 0.
* Prior to the command frame, the requested wakeup sequence will be sent.
*/
Cy_ISOUART_HostSendWriteCommand(ISOUART, blockId, 0UL, CY_ISOUART_ADDR_CONFIG, configData);
/* Wait for Write command completion by polling FRAME_RECEIVED interrupt status
* (interface side depends on topology) instead of using interrupt service routine.
*/
uint32_t intrStatus = 0UL;
do
{
intrStatus = Cy_ISOUART_GetInterruptStatusMasked(ISOUART);
} while (0UL == (intrStatus & CY_ISOUART_INTR_MASTER_LOW_FRAME_RECEIVED));
/* Clear interrupt flags. */
Cy_ISOUART_ClearInterrupt(ISOUART, intrStatus);
/* Read the write response from low interface (because of MOT topology)
* and verify the CRC of the write response.
*/
uint8_t regVal_low = Cy_ISOUART_HostReadLowInterface(ISOUART);
bool ret_low = Cy_ISOUART_HostVerifyCRC(regVal_low);
if (false == ret_low)
{
/* Handle the incorrect CRC data in the write response. */
}

Write Operations
The Host writes data to Node registers or SRAM using Cy_ISOUART_HostSendWriteCommand. This function supports both individual Node writes and broadcast writes to all Nodes simultaneously (for broadcast mode, set the nodeId parameter to 63).

After every write operation, Nodes return Write Reply frames containing operation status information such as CRC validation, error flags, and operation status. These replies are stored in HIGH_INTERFACE_READ or LOW_INTERFACE_READ registers. If any error bits are set in the reply (status, access, or address errors), the Host triggers the corresponding interrupts: CY_ISOUART_INTR_MASTER_SLAVE_STATUS_ERROR, CY_ISOUART_INTR_MASTER_SLAVE_ACCESS_ERROR, or CY_ISOUART_INTR_MASTER_SLAVE_ADDRESS_ERROR. Additionally, if the CRC doesn't match the expected value, the Host triggers CY_ISOUART_INTR_MASTER_CRC_ERROR interrupt.

To process the write reply, there are two approaches for CRC validation. You can enable the CY_ISOUART_INTR_MASTER_CRC_ERROR interrupt or, alternatively, you can use manual validation by reading the reply data with Cy_ISOUART_HostReadLowInterface or Cy_ISOUART_HostReadHighInterface (depending on your topology configuration) and then passing this value to Cy_ISOUART_HostVerifyCRC to validate the CRC value.

/* Scenario: Perform write operation to specific node in Master-on-Top topology.
* This demonstrates sending data to node SRAM and verifying write response with CRC check.
* This example uses polling to wait for command completion instead of interrupt-driven approach.
*/
/* Write command parameters */
const uint32_t address = 0UL; /* SRAM address to write to. */
const uint32_t writeData = 0x1234UL; /* Data to write. */
/* Send Write command in sequenced mode. */
Cy_ISOUART_HostSendWriteCommand(ISOUART, blockId, nodeId, address, writeData);
/* Wait for Write command completion by polling FRAME_RECEIVED interrupt status
* (interface side depends on topology) instead of using interrupt service routine.
*/
uint32_t intrStatus = 0UL;
do
{
intrStatus = Cy_ISOUART_GetInterruptStatus(ISOUART);
} while (0UL == (intrStatus & CY_ISOUART_INTR_MASTER_LOW_FRAME_RECEIVED));
/* Clear interrupt flags. */
Cy_ISOUART_ClearInterrupt(ISOUART, intrStatus);
/* Read the write response from low interface (because of MOT topology)
* and verify the CRC of the write response.
*/
uint8_t regVal_low = Cy_ISOUART_HostReadLowInterface(ISOUART);
bool ret_low = Cy_ISOUART_HostVerifyCRC(regVal_low);
if (false == ret_low)
{
/* Handle incorrect CRC data in write response. */
}

Read Operations
The Host can read data from Node registers or SRAM locations using Cy_ISOUART_HostSendReadCommand. Received data is stored in SRAM and can be retrieved using appropriate API functions based on the configured receiver mode: Cy_ISOUART_HostReadSramUnpack for Unpacked mode, Cy_ISOUART_HostReadSramRaw for Raw mode (returns complete packet with addr, nodeID, data, CRC fields, or use Cy_ISOUART_ReadSramRow16 / Cy_ISOUART_ReadSramRow32 for direct data field access), or Cy_ISOUART_HostReadLowInterface / Cy_ISOUART_HostReadHighInterface for Register mode:

/* Scenario: Perform read operation from specific node in Master-on-Top topology.
* This demonstrates SRAM size configuration, reading data from node, and unpacked data retrieval.
* This example uses polling to wait for command completion instead of interrupt-driven approach.
*/
const uint32_t address = 0UL; /* SRAM address to read from. */
/* Disable iso UART block. */
/* For the proper handling, set the interface SRAM size to the expected size by the transaction.
* NOTE: The SRAM size shall only be changed when iso UART is disabled or both interfaces are in Slave mode.
* e.g. for unpack mode, normal read command = 1
* e.g. for raw mode, normal read command = 3
* e.g. for unpack mode, multi read command = 1 x number of multi read
* e.g. for unpack mode, BC read command = 1 x number of nodes in the chain
*/
Cy_ISOUART_HostSetSramSize(ISOUART, 1UL, 0UL); /* Set the Low side 1 row, High side 0 row. */
/* Enable iso UART to operate. */
/* Perform Read operation. */
Cy_ISOUART_HostSendReadCommand(ISOUART, blockId, nodeId, address);
/* Wait for Read command completion by polling SRAM_FULL interrupt status
* (interface side depends on topology) instead of using interrupt service routine.
*/
uint32_t intrStatus = 0UL;
do
{
intrStatus = Cy_ISOUART_GetInterruptStatus(ISOUART);
} while (0UL == (intrStatus & CY_ISOUART_INTR_MASTER_LOW_SRAM_FULL));
/* Clear interrupt flags. */
Cy_ISOUART_ClearInterrupt(ISOUART, intrStatus);
/* Read data from low interface SRAM. */
uint16_t readData = Cy_ISOUART_HostReadSramUnpack(ISOUART, CY_ISOUART_IF_LOW, 0UL);
/* Process the read data */

Node Use Case

This section demonstrates how to configure a Node to receive and process commands from the Host. The Node can be configured using either auto-generated code from Device Configurator Setup or manual configuration as described in Node Configuration, Clock Configuration, Interrupt Configuration, and Enable Iso UART sections.

Trigger Interrupts Structures and Attributes Configuration
To properly handle Host commands, the Node must be configured to monitor-specific SRAM addresses and trigger actions based on received data. This requires configuring interrupt trigger structures and linking them to specific SRAM row attributes:

/* Scenario: Configure the iso UART Node interrupt trigger structure and SRAM row attributes.
* This setup enables Primary Access interrupt on write operations to SRAM address 0.
* The interrupt handler (IntrHandler) will process the triggered interrupt.
*/
/* Use trigger structure ID 1 to configure */
const uint8_t intrTrigStructId = 1U;
/* Configure interrupt trigger structure */
intrTrigStructId, /* Trigger structure ID */
CY_ISOUART_EVENT_NONE, /* Trigger source */
CY_ISOUART_EVENT_WRITE, /* Primary interrupt source */
CY_ISOUART_EVENT_NONE); /* Secondary interrupt source */
/* Configure SRAM row attributes for address 0 */
SRAM_ADDRESS, /* SRAM address */
intrTrigStructId, /* Trigger structure ID */
false, /* Invalid address disabled */
false); /* Read protection disabled */
Note
After configuring the trigger structure, ensure that:
  1. Primary Access and other relevant interrupts are enabled in the interrupt mask.
  2. Interrupt handler is properly configured (see next snippet).
  3. Global interrupts are enabled before expecting interrupt triggers.

Implementing the Interrupt Handler
The Node's interrupt handler processes incoming write commands from the Host and executes appropriate responses. Note that proper interrupt configuration (as described in Interrupt Configuration) must be completed before this handler can function correctly:

/* Scenario: Handle iso UART Node interrupts including Wake-up and Primary Access events.
* This handler processes write operations to SRAM address 0 and wakeup signals from Host.
*/
void IntrHandler(void)
{
uint32_t intrStatus = Cy_ISOUART_GetInterruptStatusMasked(ISOUART);
Cy_ISOUART_ClearInterrupt(ISOUART, intrStatus);
/* Check for Wake-up interrupt on both interfaces. */
if (0UL != (intrStatus & (CY_ISOUART_INTR_WAKE_HIGH | CY_ISOUART_INTR_WAKE_LOW)))
{
/* Handle Wake-up interrupt. */
}
/* Check for Primary Access interrupt. */
if (0UL != (intrStatus & CY_ISOUART_INTR_REG_ACCESS_P))
{
/* Get the interrupt address and event type. */
uint8_t intrAddress = Cy_ISOUART_NodeGetIntrAddrPrim(ISOUART);
/* Check if write command was sent to the expected SRAM address. */
if ((SRAM_ADDRESS == intrAddress) && (CY_ISOUART_EVENT_WRITE == intrEvent))
{
/* Read the received data from SRAM. */
receivedData = Cy_ISOUART_ReadSramRow16(ISOUART, intrAddress);
/* Process received data. */
}
}
}

Maintaining Node Activity
The Node contains a 7-bit watchdog counter that counts downward from its maximum value and must be serviced regularly to prevent the device from entering Sleep mode. The watchdog operates with a 16ms resolution on a 24MHz clock, and so provide a maximum timeout of 2.03 seconds. This watchdog timer must be refreshed periodically before it reaches zero using Cy_ISOUART_NodeSetWdtCount on the Node or using Cy_ISOUART_HostSendWriteCommand on the Host side.

Refreshing watchdog counter from Host:

/* Scenario: Refresh the watchdog timer of all nodes in the chain from the Host side. */
#define ISOUART_BROADCAST_ID (63U)
const uint32_t blockId = 0UL; /* Applied block ID (Applicable if block ID is enabled). */
/* Refresh watchdog timer for all nodes using broadcast write command. */
Cy_ISOUART_HostSendWriteCommand(ISOUART, blockId, ISOUART_BROADCAST_ID, CY_ISOUART_ADDR_WDOG_CNT, 0x7F);

Refreshing watchdog counter on the Node:

/* Scenario: Refresh the watchdog timer in the main loop to prevent Node from going into Sleep mode. */
for (;;)
{
/* Refresh a 7-bit watchdog timer. */
/* 50 ms delay between watchdog refreshes */
}

SRAM Address Protection

The iso UART provides mechanisms to protect SRAM addresses on Nodes using Cy_ISOUART_NodeConfigSramRowAttr. Two protection modes are available:
Invalid Address Protection
When a Node marks a SRAM address as invalid using Cy_ISOUART_NodeConfigSramRowAttr, any Host read or write attempt to that address will be rejected. For write commands, the Node responds with the address error bit set in the reply frame, triggering the CY_ISOUART_INTR_MASTER_SLAVE_ADDRESS_ERROR interrupt on the Host side.

Node-side configuration:

/* Scenario: Configure Node SRAM address as invalid.
* When a SRAM address is marked as invalid (isInvalid=true), any Host read or write attempt to that address
* will be rejected. For write commands, the Node responds with the address error bit set in the reply frame,
* triggering the CY_ISOUART_INTR_MASTER_SLAVE_ADDRESS_ERROR interrupt on the Host side (if enabled in the interrupt mask).
*/
const uint32_t invalidAddress = 0x10UL; /* Address to mark as invalid. */
/* Configure SRAM address as invalid on Node side. */
invalidAddress, /* SRAM address to protect */
1U, /* Trigger structure ID */
true, /* Mark as invalid address */
false); /* Read protection not needed */

Host-side error handling:

/* Scenario: Handle the address error on Host side when accessing an invalid Node SRAM address.
* This example demonstrates Host-side configuration and error handling for Master-on-Top topology
* when attempting to access a Node address marked as invalid.
*/
const uint32_t invalidAddress = 0x10UL; /* Invalid address on Node side. */
const uint32_t writeData = 0x5678UL; /* Data to write. */
/* Enable the address error interrupt on Host to detect when Node reports the address error. */
uint32_t intrMask = Cy_ISOUART_GetInterruptMask(ISOUART);
/* Attempt to write to the invalid address. */
Cy_ISOUART_HostSendWriteCommand(ISOUART, blockId, nodeId, invalidAddress, writeData);
/* Wait for write command completion. */
uint32_t intrStatus = 0UL;
do
{
intrStatus = Cy_ISOUART_GetInterruptStatusMasked(ISOUART);
} while (0UL == (intrStatus & (CY_ISOUART_INTR_MASTER_LOW_FRAME_RECEIVED | CY_ISOUART_INTR_MASTER_SLAVE_ADDRESS_ERROR)));
/* Clear interrupt flags. */
Cy_ISOUART_ClearInterrupt(ISOUART, intrStatus);
/* Check if an address error occurred. */
if (0UL != (intrStatus & CY_ISOUART_INTR_MASTER_SLAVE_ADDRESS_ERROR))
{
/* Node responded with the address error bit set.
* This indicates that the requested address is marked as invalid on Node.
* Handle the error condition appropriately.
*/
}
Note
Interrupt CY_ISOUART_INTR_MASTER_SLAVE_ADDRESS_ERROR must be enabled in the interrupt mask on the Host.

Read-Only Protection
When a Node marks a SRAM address as read-only using Cy_ISOUART_NodeConfigSramRowAttr, write attempts from the Host will be rejected while read operations remain allowed. The Node responds with the access error bit set in the reply frame, triggering the CY_ISOUART_INTR_MASTER_SLAVE_ACCESS_ERROR interrupt on the Host side.

Node-side configuration:

/* Scenario: Configure Node SRAM address as read-only.
* When a SRAM address is marked as read-only (isReadOnly=true), Host write attempts to that address will be
* rejected, while read operations remain allowed. Node will respond to the write attempts with the access error bit set
* and will trigger the CY_ISOUART_INTR_MASTER_SLAVE_ACCESS_ERROR interrupt on Host side (if enabled in the interrupt mask).
*/
const uint32_t readOnlyAddress = 0x20UL; /* Address to mark as read-only. */
/* Configure SRAM address as read-only on Node side. */
readOnlyAddress, /* SRAM address to protect */
1U, /* Trigger structure ID */
false, /* Not invalid address */
true); /* Mark as read-only */

Host-side error handling:

/* Scenario: Handle the access error on Host side when writing to a read-only Node SRAM address.
* This example demonstrates Host-side configuration and error handling for Master-on-Top topology
* when attempting to write to a Node address marked as read-only. It also shows that read
* operations to the same address are allowed and will succeed.
*/
const uint32_t readOnlyAddress = 0x20UL; /* Read-only address on Node side. */
const uint32_t writeData = 0xABCDUL; /* Data to write. */
/* Enable the access error interrupt on Host to detect when Node reports the access error. */
uint32_t intrMask = Cy_ISOUART_GetInterruptMask(ISOUART);
/* Attempt to write to the read-only address - this will trigger access error. */
Cy_ISOUART_HostSendWriteCommand(ISOUART, blockId, nodeId, readOnlyAddress, writeData);
/* Wait for write command completion. */
uint32_t intrStatus = 0UL;
do
{
intrStatus = Cy_ISOUART_GetInterruptStatusMasked(ISOUART);
} while (0UL == (intrStatus & (CY_ISOUART_INTR_MASTER_LOW_FRAME_RECEIVED | CY_ISOUART_INTR_MASTER_SLAVE_ACCESS_ERROR)));
/* Clear interrupt flags. */
Cy_ISOUART_ClearInterrupt(ISOUART, intrStatus);
/* Check if an access error occurred. */
if (0UL != (intrStatus & CY_ISOUART_INTR_MASTER_SLAVE_ACCESS_ERROR))
{
/* Node responded with the access error bit set.
* This indicates that the write operation to the read-only address was rejected.
* Handle the error condition appropriately.
*/
}
/* Read from the read-only address - this operation is allowed and will succeed. */
Cy_ISOUART_HostSendReadCommand(ISOUART, blockId, nodeId, readOnlyAddress);
/* Wait for read command completion. */
do
{
intrStatus = Cy_ISOUART_GetInterruptStatus(ISOUART);
} while (0UL == (intrStatus & CY_ISOUART_INTR_MASTER_LOW_SRAM_FULL));
/* Clear interrupt flags. */
Cy_ISOUART_ClearInterrupt(ISOUART, intrStatus);
/* Check if an access error occurred. (Should not occur for read operations) */
if (0UL != (intrStatus & CY_ISOUART_INTR_MASTER_SLAVE_ACCESS_ERROR))
{
/* Handle the error condition appropriately. */
}
/* Read data from SRAM - this will succeed without errors. */
uint16_t readData = Cy_ISOUART_HostReadSramUnpack(ISOUART, CY_ISOUART_IF_LOW, 0UL);
/* Process the read data. */
Note
Interrupt CY_ISOUART_INTR_MASTER_SLAVE_ACCESS_ERROR must be enabled in the interrupt mask on the Host.

More Information.

See the Iso UART chapter of the device technical reference manual (TRM).

Changelog

VersionChangesReason for Change
1.0 The initial version.