PSoC 6 IEC 60730 Class B safety software library for ModusToolbox

Scope and purpose

This application note describes the PSoC™ 6 MCU IEC 60730 Class B safety software library for use with ModusToolbox™. The document includes the safety library source code and example projects for PSoC™ 6 device families with self-check routines to help ensure reliable and safe operation. You can integrate the library routines and examples included in the example projects with your application. This application note also describes the API functions that are available in the library.

Intended audience

The intended audiences for this document are design engineers, technicians, and developers of electronic systems.

This document is intended for anyone who uses the PSoC™ 6 software libraries for ModusToolbox™ software.

Introduction

Today, the majority of automatic electronic controls for home appliances and industrial products use single-chip microcontroller units (MCUs). Manufacturers develop real-time embedded firmware that executes in the MCU and provides the hidden intelligence to control home appliances and industrial machines. MCU damage due to overheating, static discharge, overvoltage, or other factors can cause the end product to enter an unknown or unsafe state.

The International Electrotechnical Commission (IEC) 60730-1 safety standard discusses the mechanical, electrical, electronic, environmental endurance, EMC, and abnormal operation of home appliances.

This application note focuses on Annex H of IEC 60730-1, “Requirements for electronic controls,” These sections detail tests and diagnostic methods that promote the safe operation of embedded control hardware and software for home appliances and industrial machines.

Overview of IEC 60730-1 Annex H

Annex H of the IEC 60730-1 standard classifies appliance software into the following categories:

  • Class A control functions, which are not intended to be relied upon for the safety of the equipment. Examples are humidity controls, lighting controls, timers, and switches
  • Class B control functions, which are intended to prevent the unsafe operation of controlled equipment. Examples are thermal cutoffs and door locks for laundry equipment
  • Class C control functions, which are intended to prevent special hazards (such as an explosion caused by the controlled equipment). Examples are automatic burner controls and thermal cutouts for closed, unvented water heater systems

Large appliance products, such as washing machines, dishwashers, dryers, refrigerators, freezers, and cookers/stoves, tend to fall into Class B. An exception is an appliance that may cause an explosion, such as a gas-fired controlled dryer, which falls into Class C.

The Class B Safety Software Library and the example projects presented in this application note implement the self-test and self-diagnostic methods prescribed in the Class B category. These methods use various measures to detect software-related faults and errors and respond to them. According to the IEC 60730-1 standard, a manufacturer of automatic electronic controls must design its Class B software using one of the following structures:

  • Single channel with functional test
  • Single channel with periodic self-test
  • Dual channel without comparison (see Figure 1)

In the single-channel structure with the functional test, the software is designed using a single CPU to execute the functions as required. The functional test is executed after the application starts to ensure that all the critical features are functioning reliably.

In the single-channel structure with the periodic self-test, the software is designed using a single CPU to execute the functions as required. The periodic tests are embedded in the software, and the self-test occurs periodically while the software is in execution mode. The CPU is expected to check the critical functions of the electronic control regularly, without conflicting with the end application’s operation.

In the dual-channel structure without a comparison, the software is designed using two CPUs to execute the critical functions. Before executing a critical function, both CPUs are required to share that they have completed their corresponding task. For example, when a laundry door lock is released, one CPU stops the motor spinning the drum and the other CPU checks the drum speed to verify that it has stopped, as shown in Figure 1.

Figure 1. Dual-channel without comparison structure



The dual-channel structure implementation is costlier because two CPUs (or two MCUs) are required. In addition, it is more complex because two devices are needed to regularly communicate with each other. The single-channel structure with the periodic self-test is the most common implementation.

IEC 60730 Class B requirements

According to the IEC 60730-1 Class B Annex H Table H.11.12.7, certain components must be tested, depending on the software classification. Generally, each component offers optional measures to verify or test the corresponding component, providing flexibility for manufacturers.

To comply with Class B IEC 60730 for single-channel structures, manufacturers of electronic controls are required to test the components listed in Table 1.

Table 1. Components required to be tested for single-channel structures components required to be tested for single-channel structures

Class B IEC 60730 components required to be tested on electronic controls (Table H.11.12.7 in Annex H)Fault/Error
1.1 CPU registersStuck at
1.3 CPU program counterStuck at
2. Interrupt handling and executionNo interrupt or too frequent interrupt
3. ClockWrong frequency
4.1 Invariable memoryAll single-bit faults
4.2 Variable memoryDC fault
4.3 Addressing (relevant to variable/invariable memory)Stuck at
5.1 Internal data path dataStuck at
5.2 Internal data path addressing (for expanded memory MCU systems only)Wrong address
6.1 External communications dataHamming distance 3
6.2 External communications addressingHamming distance 3
6.3 TimingWrong point in time/sequence
7.1 I/O peripheryFault conditions specified in Appendix B, “IEC 60730-1, H.27”
7.2.1 Analog A/D and D/A convertersFault conditions specified in Appendix B, “IEC 60730-1, H.27”
7.2.2 Analog multiplexerWrong addressing

The user application must determine whether interrupts need to be enabled or disabled during the execution of the Class B Safety Software Library. For example, if an interrupt occurs during execution of the CPU self-test routine, an unexpected change may occur in any register. Therefore, when the interrupt service routine (ISR) is executed, the contents of the register will not match the expected value.

The Class B Safety Software Library example projects show where interrupts need to be disabled and enabled for correct self-testing.

Safety library usage

The Safety Software Library described in this application note can be used with PSoC™ 6 MCU devices. The library includes APIs that are designed to maximize application reliability through fault detection.

Some self-tests can be applied by only adding an appropriate API function to the *.c and *.h files from the Class B Safety Software Library.

This application note describes and implements two types of self-test functions:

  • Self-test functions to help meet the IEC 60730-1 Class B standards.

    • CPU registers: Test for stuck bits
    • Program counter: Test for jumps to the correct address
    • Program flow: Test for checking correct firmware program flow
    • Interrupt handling and execution: Test for proper interrupt calling and periodicity
    • Clock: Test for wrong frequency
    • Flash (invariable memory): Test for memory corruption
    • SRAM (variable memory): Test for stuck bits and proper memory addressing
    • Stack overflow: Test for checking stack overflow with the program data memory during program execution
    • Digital I/O: Test for pins short
    • ADC: Test for proper functionality
    • Communications (UART): Test for correct data reception
  • Additional self-test functions that PSoC™ 6 MCU can support due to programmable interconnect. Often, the end application also needs these self-tests, even though they are not provided in Appendix B of IEC 60730-1.

    • Startup configuration registers test
    • Watchdog test for chip reset

All self-tests can be executed once immediately after device startup and continuously during device operation. Performing the self-test at startup provides an opportunity to determine whether the chip is suitable for operation prior to executing the application firmware. Self-tests executed during normal operation allow continuous damage detection and user-defined corrective actions.

The following sections describe the implementation details for each test and list the APIs required to execute the corresponding tests.

API functions for PSoC 6

Summary table of test functions and return values that integrator must handle

Table 2. API functions for PSoC™ 6 devices

Test file nameTest functionReturn values
SelfTest_Analog.cSelfTest_ADC

0 No error

1 Error detected

SelfTests_Opamp

0 No error

1 Error detected

SelfTests_Comparator

0 No error

1 Error detected

SelfTest_Clock.cSelfTest_Clock

1 - Test failed

2 - Still testing

3 - Test completed

4 - Incorrect Usage

SelfTest_ConfigRegisters.cSelfTests_StartUp_ConfigReg

0 No error

1 Error detected

SelfTest_CPU.c SelfTest_CPU_Registers

0 No error

1 Error detected

SelfTest_PC

0 No error

1 Error detected

SelfTest_PROGRAM_FLOW

0 No error

1 Error detected

SelfTest_Flash.cSelfTest_FlashCheckSum

1 Error detected

2 Checksum for one block calculated, but end of Flash was not reached

3 Pass, Checksum of all flash is calculated and checked

SelfTest_Interrupt.cSelfTest_Interrupt

0 No error

1 Error detected

SelfTest_IO.cSelfTest_IO

0 No error

1 Error detected (Shorts to VCC)

2 Error detected (Shorts to GND)

SelfTest_RAM.cSelfTests_SRAM_March

1 Error detected

2 Still testing

3 Pass, all RAM is tested

SelfTests_Stack_March

1 Error detected

2 Still testing

3 Pass, all RAM is tested

SelfTest_Stack.cSelfTests_Stack_Check

0 No error

1 Error detected

SelfTests_Stack_Check_Range

0 No error

1 Error detected

SelfTest_FPU_Regs.cSelfTest_FPU_Registers

0 No error

1 Error detected

SelfTest_IPC.cSelfTest_IPC

0 No error

1 Error detected

SelfTest_WDT.cSelfTest_WDT

0 No error

1 Error detected

SelfTest_WWDT.cSelfTest_Windowed_WDT

0 No error

1 Error detected

SelfTest_DMAC.cSelfTest_DMAC

0 No error

1 Error detected

SelfTest_DMA_DW.cSelfTest_DMA_DW

0 No error

1 Error detected

SelfTest_Timer_Counter.cSelfTest_Counter_Timer

0 No error

1 Error detected

SelfTest_PWM.cSelfTest_PWM

0 No error

1 Error detected

SelfTest_PWM_GateKill.cSelfTest_PWM_GateKill

0 No error

1 Error detected

SelfTest_CANFD.cSelfTest_CANFD

0 No error

1 Error detected

SelfTest_UART_SCB.cSelfTest_UART_SCB

1 Error detected

2 Still testing

3 Pass, test completed

4 ERROR_TX_NOT_EMPTY

5 ERROR_RX_NOT_EMPTY

6 ERROR_TX_NOT_ENABLE

7 ERROR_RX_NOT_ENABLE

SelfTest_SPI_SCB.cSelfTest_SPI_SCB

1 Error detected

2 Still testing

3 Pass, test completed

4 TX not empty

5 RX not empty

SelfTest_I2C_SCB.cSelfTest_I2C_SCB

1 Error detected

2 Still testing

3 Pass, test completed

CPU register test

PSoC™ 6 with the Arm® Cortex®-M0+ and Cortex®-M4 CPUs have 16-bit and 32-bit registers. The following registers are included in the CPU test:

  • R0 to R12 – General-purpose registers
  • R13 – Stack pointer (SP): There are two stack pointers, with only one available at a time. The SP is always 32-bit-word aligned; bits [1:0] are always ignored and considered to be ‘0’
  • R14 – Link register: This register stores the return program counter during function calls
  • R15 – Program counter: This register can be written to control the program flow

All other special function registers like the floating point unit are not included in the test. The CPU registers test detects stuck-at faults in the CPU registers by using the checkerboard test. This test ensures that the bits in the registers are not stuck at value ‘0’ or ‘1’. It is a nondestructive test that performs the following major tasks:

  1. The contents of the CPU registers to be tested are saved on the stack before executing the routine
  2. The registers are tested by successively writing the binary sequences 01010101 followed by 10101010 into the registers, and then reading the values from these registers for verification
  3. The test returns an error code if the returned values do not match

Function

uint8	SelfTest_CPU_Registers(void) 
Returns: 0 No error
1 Error detected
Located in: SelfTest_CPU.c
SelfTest_CPU.h

The function SelfTest_CPU_Registers is called to do the CPU test.

If an error is detected, the PSoC™ device should not continue to function because its behavior can be unpredictable and therefore potentially unsafe.

Program counter test

The PSoC™ 6 CPU program counter R15 register is part of the CPU register set. To test these registers, a checkerboard test is commonly used; the addresses 0x10155555 and 0x100AAAAA must be allocated for this test. 0x10155555 and 0x100AAAAA represent the checkerboard bit patterns. Devices with reduced Flash memory size use an address that fits in the available address range.

The program counter (PC) test implements the functional test defined in section H.2.16.5 of the IEC 60730 standard. The PC holds the address of the next instruction to be executed. The test performs the following major tasks:

  1. The functions that are in flash memory at different addresses are called. For PSoC™ 6, this can be done by using the linker script in an

    *.ld

    file

    NV_CONFIG2 0x10155554 :
    (
    . = 0x00;
    KEEP (*(PC5555))
    ) >flash =0

    NV_CONFIG3 0x100AAAA8 :
    (
    . = 0x00;
    KEEP (*(PCAAAA))

    ) >flash =0

    In the example project, it is already added to the custom linker.ld file shipped with the example project

  2. The functions return a unique value
  3. The returned value is verified using the PC test function
  4. If the values match, the PC branches to the correct location, or a WDT triggers a reset because the program execution is out of range

Function

uint8	SelfTest_PC(void) 
Returns: 0 No error
1 Error detected
Located in: SelfTest_CPU.c
SelfTest_CPU.h

The function SelfTest_PC() is called to do the PC test.

Note: Linker file for each device family is created based on the default device for the corresponding family. Update linkers if the Flash size is different from the default device

Program flow test

A specific method is used to check program execution flow. For every critical execution code block, unique numbers are added to or subtracted from complementary counters before block execution and immediately after execution. These procedures allow you to see if the code block is correctly called from the main program flow and to check if the block is correctly executed.

As long as there are always the same number of exit and entry points, the counter pair will always be complementary after each tested block. See Figure 2.

Any unexpected values should be treated as a program flow execution error.

Figure 2. Program flow test



Interrupt handling and execution test

The PSoC 6 interrupt controllers provide the mechanism for hardware resources to change the program address to a new location independent of the current execution in main code. They also handle continuation of the interrupted code after completion of the ISR.

The interrupt test implements the independent time-slot monitoring defined in section H.2.18.10.4 of the IEC 60730 standard. It checks whether the number of interrupts that occurred is within the predefined range.

The goal of the interrupt test is to verify that interrupts occur regularly. The test checks the interrupt controller by using the interrupt source driven by the timer UM

Function

uint8	SelfTest_Interrupt(void) 
Returns: 0 No error
1 Error detected
Located in: SelfTest_Interrupt.c
SelfTest_Interrupt.h
Note: Global interrupts must be enabled for this test, but all interrupts except isr_1 must be disabled.

The SelfTest_Interrupt() function is called to check the interrupt controller operation. Calling the function starts the timers.

Timer_1 is configured to generate 13 interrupts per 1 ms. isr_1 counts the number of interrupts that occurred. If the counted value in isr_1 is ≥ 9 and ≤ 15, then the test is passed. The specific number of interrupts to pass this test is application dependent and can be modified as required.

Figure 3 shows the interrupt self-test flow chart.

Figure 3. Interrupt self-test flow chart



Clock test

The clock test implements independent time-slot monitoring defined in section H.2.18.10.4 of the IEC 60730 standard. It verifies the reliability of the internal main oscillator (IMO) system clock, specifically, that the system clock is neither too fast nor too slow within the tolerance of the internal low-speed oscillator (ILO). The 32 kHz ILO clock is accurate to ± 10 percent.

Function

uint8	SelfTest_Clock(void) 
Returns: 0 No error
Not 0 Error detected
Located in: SelfTest_Clock.h
SelfTest_Clock.c
Note: The tested clock accuracies are defined in the SelfTest_Clock.h file. Clock accuracies may be modified based on end system requirements.

The clock test uses the 16-bit timer0 integrated into the WDT and clocked by the 32.768 kHz ILO. The WDT timer0 is a continuous up counting 16-bit timer with overflow. The test starts by reading the current count of the timer, then waits 1 ms using a software delay, and finally reads the timer count a second time. The two count values are then subtracted and optionally corrected for the special case of a timer overflow mid test. The measured period (nominally 33 counts) is then tested. If it is within the predefined range, the test is passed. Figure 4 shows the clock self-test flow chart.

Figure 4. Clock self-test flow chart



Flash (invariable memory) test

PSoC 6 devices include an on-chip flash memory of up to 2048 KB. The flash memory is organized in rows, where each row contains 128 data bytes.

To complete a full diagnostic of the flash memory, a checksum of all used flash needs to be calculated. The current library uses a Fletcher’s 64-bit checksum or 32-bit CRC32. The Fletcher’s 64-bit method was chosen as the default because it maintains sufficient bit error detection and is significantly faster and smaller than CRC-32. Fletcher’s 64-bit algorithm reads a full 32-bit word and usually only performs 2 additions per read while requiring no ROM lookup table as compared to CRC32.

You can change the checksum modifying the FLASH_TEST_MODE macro in SelfTest_Flash.h. FLASH_END_ADDR in the SelfTest_Flash.h file defines the end of flash address that needs to be monitored.

Fletcher checksum method

To complete a full diagnostic of the flash memory, a checksum of all used flash needs to be calculated.

The current library uses a Fletcher’s 64-bit checksum. The Fletcher’s 64-bit method was chosen because it is sufficiently reliable.

You can change the Fletcher’s checksum method to any checksum method in function SelfTest_FlashCheckSum() in the SelfTest_Flash.c file.

CY_FLASH_SIZE in the SelfTest_Flash.h file defines the flash size that needs to be monitored.

The proposed checksum flash test reads each ROM or flash location and accumulates the values in a 64-bit variable to calculate a running checksum of the entire flash memory. The actual 64-bit checksum of flash is stored in the last 8 bytes of flash itself. When the test reaches the end of flash minus 8 bytes (0x7FF8 on 32-KB devices), it stops. Custom linker files are used to place the checksum in the desired location (see Table 2). The calculated checksum value is then compared with the actual value stored in the last 8 bytes of flash. A mismatch indicates flash failure, and code execution is frozen to avoid trying to execute invalid code.

Note: The checksum can also be stored in SFLASH, EEPROM, or any other external flash. See the System reference guide to know more about using SFLASH functions like CySysSFlashWriteUserRow to store checksum in SFLASH, if available.

CRC-32 method

The CRC-32 method uses a lookup table to speed execution but is slower than the Fletchers 64-bit method due to the need to read memory at byte boundaries and perform multiple bit operations per read. The CRC32 polynomial chosen is the most common version defined in ISO/IEC/IEEE 802-3 with polynomial 0x04C11DB7 (Reversed = 0xEDB88320). To maintain compatibility with the Fletcher 64-bit storage size the CRC32 value is stored in the last 4 bytes of the 8 byte reserved Flash space.

Programming method

Before starting the test, you need to set the correct precalculated checksum, as described in Appendix A: Set checksum in flash (invariable memory) test.

Function

uint8 SelfTest_FlashCheckSum()
<strong className="ph b">Returns:</strong>
1 Error detected
2 Checksum for one block calculated, but end of Flash was not reached
3 Pass, Checksum of all flash is calculated and checked
<strong className="ph b">Located in:</strong> SelfTest_Flash.c
SelfTest_Flash.h

The function SelfTest_FlashCheckSum() is called to perform the flash memory corruption test using the checksum method. During the call, this function calculates the checksum for one block of flash. The size of the block can be set using parameters in the SelfTest_Flash.h file:

/*Set size of one block in Flash test*/
#define FLASH_DOUBLE_WORDS_TO_TEST (512u)

The function must be called multiple times until the entire flash area is tested. Each call to the function will automatically increment to the next test block. If the checksum for the block is calculated and the end address of the tested flash is reached, the test returns 0x03. If the checksum for the block is calculated but the end address of flash is not reached, the test returns 0x02. If an error is detected, the test returns 0x01.

Note: The check does not work if there is a change in flash during run time. The checksum needs to be updated before calling the test. Other tests that may change the contents of Flash must be called prior to the flash test.

SRAM (variable memory) test

Note: PSoC™ 6 devices include an on-chip SRAM of up to 1024 KB. Part of this SRAM includes the stack located at the end of memory.

The variable memory test implements the periodic static memory test defined in section H.2.19.6 of the IEC 60730 standard. It detects single-bit faults in the variable memory. Variable memory tests can be destructive or nondestructive. Destructive tests destroy the contents of memory during testing, whereas nondestructive tests preserve the memory contents. While the test algorithm used in this library is destructive, it is encapsulated in code that first saves the memory contents before a test and then restores the contents after completion.

The variable memory contains data, which varies during program execution. The RAM memory test is used to determine if any bit of the RAM memory is stuck at ‘1’ or ‘0’. The March memory test and checkerboard test are among the most widely used static memory algorithms to check for DC faults.

The March tests comprise a family of similar tests with slightly different algorithms. The March test variations are denoted by a capital letter and allow tailoring of the test to a specific architecture’s test requirements. The March C test is implemented for the PSoC™ 6 Safety Software Library because it provides better test coverage than the checkerboard algorithm and is the optimal March method for this device. Separate functions are implemented for the “variable SRAM” and “stack SRAM” areas to ensure no data is corrupted during testing.

March C test

March tests perform a finite set of operations on every memory cell in the memory array. The March C test is used to detect the following types of faults in the variable memory:

  • Stuck-at fault
  • Addressing fault
  • Transition fault
  • Coupling fault

The test complexity is 11n, where “n” indicates the number of bits in memory, and 11 operations are required to test each location. While this test is normally destructive, Infineon provides the March C test without data corruption by testing only a small block of memory in each test, allowing the block’s contents to be saved and restored.

March C algorithm

The March C- Memory Built-In Self Test (MBIST) algorithm covers the majority of SRAM faults, including addressing faults, Stuck at Fault, State transition fault, and various coupling faults.

The algorithm is as follows:

  1. This test first duplicates data in the area to be tested as this test is destructive.
  2. Write 0 to the block in ascending order.
  3. Read 0 and write 1 in ascending order.
  4. Read 1 and write 0 in ascending order.
  5. Read 0.
  6. Read 0 and write 1 in descending order.
  7. Read 1 and write 0 in descending order.
  8. Read 0.
  9. Copy back the original data function
Function
uint8_t SelfTests_SRAM_March(void)
<strong className="ph b">Returns:</strong>
1 - Error Detected
2 - Pass, but still testing status
3 - pass and complete status
<strong className="ph b">Located in:</strong>
SelfTest_RAM.c
SelfTest_RAM.h

Test time

The default SRAM test configuration tests 256 bytes each time it is called until it tests the specified SRAM size address space. The block size and frequency that the test is called can be modified. The test takes one second per 1 MB in its default configuration.

The default stack memory test configuration tests 21 bytes each time it is called until it tests the one kb stack address space. The block size and frequency that the test is called can be modified. The test takes 4.2 ms for each 1 KB in its default configuration.

Stack overflow test

The stack is a section of RAM used by the CPU to store information temporarily. This information can be data or an address. The CPU needs this storage area since there are only a limited number of registers.

In PSoC™ 6, the stack is located at the end of RAM and grows downward. The stack pointer is 32 bits wide and is decremented with every PUSH instruction and incremented with POP.

The purpose of the stack overflow test is to ensure that the stack does not overlap with the program data memory during program execution. This can occur, for example, if recursive functions are used.

To perform this test, a reserved fixed-memory block at the end of the stack is filled with a predefined pattern, and the test function is periodically called to verify it. If stack overflow occurs, the reserved block will be overwritten with corrupted data bytes, which should be treated as an overflow error.

Function

void SelfTests_Init_Stack_Test(void)
Returns: NONE
Located in: SelfTest_Stack.c
SelfTest_Stack.h

This function is called once to fill the reserved memory block with a predefined pattern.

Function

uint8 SelfTests_Stack_Check(void)
Returns: 0 No error
1 Error detected

Located in: SelfTest_Stack.c
SelfTest_Stack.h

This function is called periodically at run time to test for stack overflow. The block size should be an even value and can be modified using the macro located in

SelfTest_Stack.h:

#define STACK_TEST_BLOCK_SIZE 0x08u

The pattern can be modified using the macro located in SelfTest_Stack.h:

#define STACK_TEST_PATTERN 0x55AAu

Analog tests

Analog tests comprise the ADC, comparator, and opamp test. These tests rely on two fixed reference voltages. Depending on the specific PSoC™ device, these voltage references can be generated internally or externally with the help of external hardware. It is up to the user to configure the voltage reference and route the voltages to the hardware under test. This provides flexibility for the user and control over internal routing. The AMUX buses are segmented allowing for greater flexibility in normal use.

Generating the reference voltages

Voltage reference can be provided to the device using external hardware. A possible method could be with the use of a three-resistor voltage divider between VDDA and GND. This will generate two reference voltages: 2/3VDDA and 1/3VDDA. These reference voltages can be attached to any GPIO pin and be connected to the AMUXBUS through the GPIO.

ADC test

The ADC test implements an independent input comparison as defined in section H.2.18.8 of the IEC 60730 standard. It provides a fault/error control technique with which the inputs/outputs that are designed to be within specified tolerances are compared.

The purpose of the test is to check the SAR ADC analog functions. Each ADC enabled by the test is connected to an internal reference voltage using the Programmable Analog block. If the measured value is more than the expected value, an error is returned.

Function
uint8_t SelfTests_ADC(void * base, uint32_t channel, int16_t expected_res, int16_t accuracy, uint32_t vbg_channel, bool count_to_mV);

<strong className="ph b">Parameters:</strong>

base : SAR ADC base addr
channel : Channel to be acanned
expected_res : If count_to_mV = 1 -&gt; pass expected voltage in mV else pass expected counts
vbg_channel : only used in PSoC6 device. Used to convert the count to mV.

<strong className="ph b">Returns:</strong>
0 - No error
1 - Error detected

<strong className="ph b">Located in:</strong> SelfTest_Analog.h
SelfTest_Analog.c

The ADC accuracy is defined in stl_Analog.h. A 12-bit ADC is used for testing:

#define ADC_TEST_ACC 12 // +/- ADC result Value

To perform this test, the ADC is configured to scan passed channel. A predefined (reference) voltage is generated externally and is sampled by the ADC.

The test is a success if the digitalized input voltage value is equal to the required voltage value within the defined accuracy. When the test is a success, the function returns 0; otherwise, it returns 1.

Comparator test

If the inputs to the comparators can be connected to the internal reference voltage, one side of each comparator is connected to the internal reference voltage and the other side is connected to ground. The results are checked. The inputs are switched and the result is checked again.

If the inputs cannot be modified via the programmable analog block, the test uses the pull-up and pull-down resistors in the GPIO to conduct a similar test.

Function
uint8 SelfTest_Comparator(void)
Returns:0 No error

Error detected
Located in: stl_Analog.h
stl_Analog.c

Opamp test

The opamp is tested by generating the same output as the input (Unity Gain Buffer) and the result is read by the SAR ADC. If it is as per expected the test passes.

Function
uint8_t SelfTests_Opamp(SAR_Type* sar_base, int16_t expected_res, int16_t accuracy, uint32_t opamp_in_channel, bool count_to_mV);

Parameters:

base : SAR ADC base addr
expected_res : If count_to_mV = 1 -&gt; pass expected voltage in mV else pass expected counts
opamp_in_channel : Channel to be acanned (where the output of OP-AMP is connected)

Returns:

0 - No error
1 - Error detected

Located in: SelfTest_Analog.h
SelfTest_Analog.c

IPC test

Each devices has few free IPC channels and IPC interrupts that can be mapped to each channel. This function implements the IPC functional test.

Function

uint8_t SelfTest_IPC(void) 
Returns: 0 - No error
1 - Error detected
Located in: SelfTest_IPC.c
SelfTest_IPC.h

This function does:

  1. Write the message to the channel
  2. Acquire an IPC channel and specify which IPC interrupts must be notified during the lock event
  3. In the ISR of that IPC interrupt read the data
  4. Release the IPC channel from the locked state using same IPC during the release event
  5. Similarly for the same channel use all the free interrupt
  6. Similarly take all IPC channels with all IPC interrupts

FPU register test

The FPU registers test detects stuck-at faults in the FPU by using the checkerboard test. This test ensures that the bits in the registers are not stuck at value '0' or '1'.

Function

uint8_t SelfTest_FPU_Registers(void)

Returns:

0 - No error
1 - Error detected

Located in: SelfTest_FPU_Regs.c
SelfTest_FPU_Regs.h

The function SelfTest_FPU_Registers is called to do the FPU test. If an error is detected, the device should not continue to function because its behavior can be unpredictable and therefore potentially unsafe.

It is a destructive test that performs the following major tasks:

  1. The registers are tested by performing a write/read/compare test sequence using a checkerboard pattern (0x5555 5555, then 0xaaaa aaaaa). These binary sequences are valid floating point values
  2. The test returns an error code if the returned values do not match

DMA/DW test

The DataWire blocks are tested using the following procedure. Each DW channel is tested using the same procedure. Few devices have might have DMA and few with DW block.

Function

uint8_t SelfTest_DMA_DW(DW_Type * base, uint32_t channel, cy_stc_dma_descriptor_t * descriptor0, cy_stc_dma_descriptor_t * descriptor1,
const cy_stc_dma_descriptor_config_t * des0_config,const cy_stc_dma_descriptor_config_t * des1_config,
cy_stc_dma_channel_config_t const * channelConfig, en_trig_output_pdma0_tr_t trigLine);

Parameters:

base - The pointer to the hardware DMA block
channel - A channel number
descriptor0 - This is the descriptor to be associated with the channel (transfer 0's to destination).
descriptor1 - This is the descriptor to be associated with the channel (transfer pattern to destination).
des0_config - This is a configuration structure that has all initialization information for the descriptor.
des1_config - This is a configuration structure that has all initialization information for the descriptor.
channelConfig - The structure that has the initialization information for the channel.
trigLine - The input of the trigger mux.

Returns:

0 - No error

1 - Error detected

Located in: SelfTest_DMAC.c
SelfTest_DMAC.h

The DMA/DW test performs the following steps:

  1. A destination block of size 64 bytes is set to 0 with DW transfers using 16 x 32-bit transfers from a fixed address

  2. The destination block is verified to be all 0
  3. The same destination block is filled with 00 00 ff by using an 8-bit DMA from a fixed address with an increment of 3 and a length of 22 (64+(3-1))/3

  4. The destination block is verified to contain the correct pattern (shown below with lowest address first):

    ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000…

Start-up configuration registers test

This test describes and shows an example of how to check the start-up configuration registers:

  1. Test digital clock configuration registers
  2. Test analog configuration registers (set to default values after start-up)
  3. Test the GPIO configuration and HSIOM registers

These start-up configuration registers are typically static and are in the cy_device.h file after the design is built. In rare use cases, some of these registers may be dynamically updated. Dynamically updated registers must be excluded from this test. Dynamic registers are instead tested in application with the knowledge of the current correct value.

Two test modes are implemented in the functions:

  • Store duplicates of start-up configuration registers in flash memory after device start-up. Periodically, the configuration registers are compared with stored duplicates. Corrupted registers can be restored from flash after checking
  • Compare the calculated CRC with the CRC previously stored in flash if the CRC status semaphore is set. If the status semaphore is not set, the CRC must be calculated and stored in flash, and the status semaphore must be set
Note: The following functions are examples and can be applied only to the example project. If you make changes in the configuration, other configuration registers may be generated in the cy_device.h. You must change the list of required registers based on the safety needs of your design.

Function

cystatus SelfTests_Save_StartUp_ConfigReg(void) 

Returns: 0 write in flash is successful
1 error detected during flash writing

Located in: SelfTest_ConfigRegisters.c
SelfTest_ConfigRegisters.h

This function copies all listed startup configuration registers into the last row(s) of flash as required by the number of registers to save.

Note: This function should be called once after the initial PSoC power up and initialization before entering the main program. It writes the startup configuration register values to flash. After this initial write, typically during manufacturing, the register values are already stored, and this function does not need to be called again.
Note: Make sure the Startup configuration registers or CRC values are not stored in a flash location which is already in use. For example, flash test uses the last 8 bytes to store the flash checksum by default.

Function

uint8 SelfTests_StartUp_ConfigReg(void) 
Returns: 0 No error
1 Error detected
Located in: SelfTest_ConfigRegisters.c
SelfTest_ConfigRegisters.h

This function checks the listed start-up configuration registers. There are two modes of checking:

  • CRC-16 calculation and verification
  • You can define the mode using the parameters in the SelfTest_ConfigRegisters.h file:
#define STARTUP_CFG_REGS_MODE               CFG_REGS_CRC_MODE/CFG_REGS_TO_FLASH_MODE

#define CFG_REGS_TO_FLASH_MODE (1u)

This mode stores duplicates of registers in flash and compares registers with the duplicates. It returns a fail (1) if the values are different. Registers can be restored in this mode. The SelfTests_Save_StartUp_ConfigReg function is used to store duplicates in flash. CONF_REG_FIRST_ROW defines the location of the startup configuration registers in flash memory and is automatically calculated inSelfTest_ConfigRegisters.h.

#define CFG_REGS_CRC_MODE (0u)

In this mode, the function calculates a CRC-16 of registers and stores the CRC in flash. Later, function calls recalculate the CRC-16 and compare it with the saved value. It returns a fail (1) if the values are different.

By default, the CRC mode values are stored at the 9th, 7th, and 8th byte locations from the end of flash. While using alongside the flash test, which uses last 8 bytes of flash, it is recommended to move the CRC mode values to the 16th, 14th, and 15th byte locations from the end of flash.

You can define custom location for CRC-16 values by updating defines CRC_STARTUP_SEMAPHORE_SHIFT,CRC_STARTUP_LO, and CRC_STARTUP_HI in the SelfTest_ConfigRegisters.h file.

Table 3. List of default registers included in library test

Clock registersHSIOM registersIO pin registers
SRSS_WDT_CTLHSIOM_PRT_PORT_SEL0(HSIOM_PRT0)GPIO_PRT_CFG(GPIO_PRT0)
SRSS_CLK_PATH_SELECTHSIOM_PRT_PORT_SEL1(HSIOM_PRT0)GPIO_PRT_CFG(GPIO_PRT1)
SRSS_CLK_ROOT_SELECTHSIOM_PRT_PORT_SEL0(HSIOM_PRT1)GPIO_PRT_CFG(GPIO_PRT2)
SRSS_CLK_SELECTHSIOM_PRT_PORT_SEL1(HSIOM_PRT1)GPIO_PRT_CFG(GPIO_PRT3)
SRSS_CLK_TIMER_CTLHSIOM_PRT_PORT_SEL0(HSIOM_PRT2)GPIO_PRT_CFG(GPIO_PRT4)
SRSS_CLK_ILO_CONFIGHSIOM_PRT_PORT_SEL1(HSIOM_PRT2)GPIO_PRT_CFG(GPIO_PRT5)
SRSS_CLK_OUTPUT_SLOWHSIOM_PRT_PORT_SEL0(HSIOM_PRT3)GPIO_PRT_CFG(GPIO_PRT6)
SRSS_CLK_OUTPUT_FASTHSIOM_PRT_PORT_SEL1(HSIOM_PRT3)GPIO_PRT_CFG(GPIO_PRT7)
SRSS_CLK_ECO_CONFIGHSIOM_PRT_PORT_SEL0(HSIOM_PRT4)GPIO_PRT_CFG(GPIO_PRT8)
SRSS_CLK_PILO_CONFIGHSIOM_PRT_PORT_SEL1(HSIOM_PRT4)GPIO_PRT_CFG(GPIO_PRT9)
SRSS_CLK_FLL_CONFIGHSIOM_PRT_PORT_SEL0(HSIOM_PRT5)GPIO_PRT_CFG(GPIO_PRT10)
SRSS_CLK_FLL_CONFIG2HSIOM_PRT_PORT_SEL1(HSIOM_PRT5)GPIO_PRT_CFG(GPIO_PRT11)
SRSS_CLK_FLL_CONFIG3HSIOM_PRT_PORT_SEL0(HSIOM_PRT6)GPIO_PRT_CFG(GPIO_PRT12)
SRSS_CLK_PLL_CONFIGHSIOM_PRT_PORT_SEL1(HSIOM_PRT6)GPIO_PRT_CFG(GPIO_PRT13)
HSIOM_PRT_PORT_SEL0(HSIOM_PRT7)
Analog routing regsHSIOM_PRT_PORT_SEL1(HSIOM_PRT7)
PASS_AREF_AREF_CTRLHSIOM_PRT_PORT_SEL0(HSIOM_PRT8)
HSIOM_PRT_PORT_SEL1(HSIOM_PRT8)
HSIOM_PRT_PORT_SEL0(HSIOM_PRT9)
HSIOM_PRT_PORT_SEL1(HSIOM_PRT9)
HSIOM_PRT_PORT_SEL0(HSIOM_PRT10)
HSIOM_PRT_PORT_SEL1(HSIOM_PRT10)
HSIOM_PRT_PORT_SEL0(HSIOM_PRT11)
HSIOM_PRT_PORT_SEL1(HSIOM_PRT11)
HSIOM_PRT_PORT_SEL0(HSIOM_PRT12)
HSIOM_PRT_PORT_SEL1(HSIOM_PRT12)
HSIOM_PRT_PORT_SEL0(HSIOM_PRT13)
HSIOM_PRT_PORT_SEL1(HSIOM_PRT13)

Watchdog test

This function implements the watchdog functional test. The function starts the WDT and runs an infinite loop. If the WDT works, it generates a reset. After the reset, the function analyzes the reset source. If the watchdog is the source of the reset, the function returns; otherwise, the infinite loop executes.

Function

void	SelfTest_WDT(void)
Returns: None
Located in: SelfTest_WDT.h
SelfTest_WDT.c

Figure 5 shows the test flow chart.

Figure 5. Implementation of WDT test



Digital I/O test

PSoC™ 6 provides up to 102 programmable GPIO pins. Any GPIO pin can be CAPSENSE®, LCD, analog, or digital. Drive modes, strengths, and slew rates are programmable.

Digital I/Os are arranged into ports, with up to eight pins per port. Some of the I/O pins are multiplexed with special functions (USB, debug port, crystal oscillator). Special functions are enabled using control registers associated with the specific functions.

The test goal is to ensure that I/O pins are not shorted to GND or Vcc. Tests to detect shorts between physically adjacent pins are not included and must be added by the integrator as there are end application integrations we cannot account for in a general-purpose test.

In normal operating conditions, the pin-to-ground and pin-to-VCC resistances are very high. To detect any shorts, resistance values are compared with the PSoC internal pull-up resistors.

To detect a pin-to-ground short, the pin is configured in the resistive pull-up drive mode. Under normal conditions, the CPU reads a logical one because of the pull-up resistor. If the pin is connected to ground through a small resistance, the input level is recognized as a logical zero.

To detect a sensor-to-VCC short, the sensor pin is configured in the resistive pull-down drive mode. The input level is zero under normal conditions.

Note: This test is application dependent and may require customization. The default test values may cause the pins to be momentarily configured into an incorrect state for the end application.

Function

uint8 SelfTests_IO()
Returns: 0 No error
1 Error detected (Short to VCC)
2 Error detected (Short to GND)
Located in: SelfTest_IO.c
SelfTest_IO.h

The function SelfTests_IO() is called to check shorts of the I/O pins to GND or Vcc. The PintToTest array in the SelfTests_IO() function is used to set the pins that must be tested.

For example:

static const uint8 PinToTest[] = 
(
0b11011111, /* PORT0 mask */
0b00111111, /* PORT1 mask */
0b11111111, /* PORT2 mask */
0b11110011, /* PORT3 mask */
0b00000000, /* PORT4 mask */
);

Each pin is represented by the corresponding bit in the PinToTest table port mask. Pin 0 is represented by the LSB, and pin 7 by the MSB. If a pin should be tested, a corresponding bit should be set to ‘1’.

TCPWM test

This test demonstrates the use of the Class-B Safety Test Library to test the TCPWM resource configured as a timer/counter, PWM, and PWM output Gate Kill in PSoC™ 6 MCUs. It verifies the proper operation and accuracy of these peripherals adhering to the IEC 60730 standards.

Timer/Counter test

Timer/counter is used to count clocks (timer) or external events (counter). The test uses the timer function. The test should be run on every safety-critical timer/counter.

Function
uint8_t SelfTest_Counter_Timer()

Returns:

0 - No error
1 - Error detected

Located in: SelfTest_Timer_Counter.c
SelfTest_Timer_Counter.h

The Timer/counter is tested using the following procedure:

  1. Configure the block to timer/counter personality
  2. Configure the input clock to the CPU clock
  3. Check that the counter is incrementing

PWM test

The PWM is tested using the following procedure:

  1. Configure a 16-bit PWM to run at 1/3 duty ON, 2/3 OFF duty cycle with a 1 millisecond period. Start the PWM
  2. Run the CPU in a loop for 5 milliseconds. Poll the output continuously in the loop. Count the instances of 0 and 1 output
  3. The test is successful if the off/on ratio is between 1 7/8 and 2 1/8. A range is used because the CPU polling loop is asynchronous to the PWM timing
Function
uint8_t SelfTest_PWM(GPIO_PRT_Type *pinbase, uint32_t pinNum)

Parameters:

pinbase - The pointer to a GPIO port instance to which the PWM pin is connected to.
pinNum - The GPIO pin number to which the PWM pin is connected to.

These parameters are ignored for CAT1C devices as pin is not driven.

Returns:

0 - No error
1 - Error detected

Located in: SelfTest_PWM.c
SelfTest_PWM.h

The test must not drive the PWM output pin.

PWM Gatekill test

The "Gate Kill" function is used in motor controllers and multi-level power converters. When an over-voltage or current state is detected, the Gate Kill shuts down the output drivers less than 50 nanoseconds after the over-voltage or over-current occurs.

Function
uint8_t SelfTest_PWM_GateKill(TCPWM_Type *base, uint32_t cntNum)

Parameters:

base - The pointer to a TCPWM instance
cntNum - The Counter instance number in the selected TCPWM


Returns:

0 - No error
1 - Error detected

Located in: SelfTest_PWM_GateKill.c
SelfTest_PWM_GateKill.h

The PWM GateKill is tested using the following procedure:

  1. Configure the Kill Mode as Stop on Kill
  2. The Low power comparator output or the Voltage range violation of SAR ADC is routed to Kill signal of TCPWM indicating over-voltage/over-current condition if voltage on +ve terminal is > -ve

  3. If over-voltage or over-current condition it will Kill PWM output
  4. The TCPWM base and CntNum is passed to check whether the counter is stopped or not

  5. If counter is not incrementing/decrementing the PWM output is inactive

Communications UART test

This test implements the UART internal data loopback test. The test is a success if the transmitted byte is equal to the received byte and returns 2. Each function call increments the test byte. After 256 function calls, when the test finishes testing all 256 values and they are all a success, the function returns 3. SmartIO is used for loopback and the UART pins are connected to SmartIO.

It should be noted that only few SCBs are routed through SmartIO. However, this test can still be used with other SCBs if the UART RX and TX pins are tied together externally.

Function

uint8	SelfTest_UART_SCB(void)
Returns:
1 Error detected
2 Pass test with current values, but not all tests in range from 0x00 to 0xFF have completed
3 Pass, tested with all values in range from 0x00 to 0xFF
4 ERROR_TX_NOT_EMPTY
5 ERROR_RX_NOT_EMPTY
6 ERROR_TX_NOT_ENABLE or ERROR_RX_NOT_ENABLE

Located in: SelfTest_UART_SCB.h
SelfTest_UART_SCB.c

The input and output terminals switch between the corresponding pins and loop to each other to provide the internal loopback test by using the UART multiplexer and demultiplexer. If the receiving or transmitting buffers are not empty before the test, the test is not executed and returns an ERROR_RX_NOT_EMPTY or ERROR_TX_NOT_EMPTY status.

The test function saves the component configuration before testing and restores them after the test ends. During the call, the function transmits 1 byte. The transmitted value increments after each function call. The range of test values is from 0x00 to 0xFF.

Communications UART data transfer protocol example

For additional system safety when transferring data between system components, you can use communication protocols with CRCs and packet handling. An example of safety communication follows.

Data is placed into the packets with a defined structure to be transferred. All packets have a CRC calculated with the packet data to ensure the packet’s safe transfer. Figure 6 shows the packet format.

Figure 6. UART packet structure



To allow the reserved start of packet marker (STX) value to be transmitted, use a common escape method. When any byte in a packet is equal to STX or ESC, it changes to a 2-byte sequence. If packet byte = ESC, replace it with 2 bytes (ESC, ESC + 1). If any packet byte = STX, then replace it with 2 bytes (ESC, STX + 1). This procedure provides a unique packet start symbol. The ESC byte is always equal to 0x1B. It is not a part of the packet and is always sent before the (packet byte + 1) or (ESC, STX + 1). Table 4 shows the packet field descriptions.

Table 4. Packet field description

NameLengthValueDescription
STX1 byte0x02Unique start of packet marker = 0x02.
ADDR1 or 2 bytes0x00-0xFF except 0x02Slave address. If this byte is equal to STX, it changes to a 2-byte sequence: (ESC) + (STX + 1). If this byte is equal to ESC, it changes to a 2-byte sequence: (ESC) + (ESC +1).
DL1 or 2 bytes0x00-0xFF except 0x02

Data length of packet (without protocol bytes). If this byte is equal to STX, it changes to a 2-byte sequence: (ESC) + (STX

  • 1). If this byte is equal to ESC, it changes to a 2-byte sequence: (ESC) + (ESC + 1).
D0-Dn (data)1...510 bytes0x00-0xFF except 0x02

Packet's data. If any byte in the data is equal to STX, it changes to a 2-byte sequence: (ESC) + (STX + 1). If any byte in the data is equal to ESC, it changes to a 2-byte sequence: (ESC) + (ESC

  • 1).
CRCH1 or 2 bytes0x00-0xFF except 0x02MSB of packet CRC. CRC-16 is used. CRC is calculated for all packet bytes from ADDR to the last data byte. CRC is calculated after the ESC changing procedure. If this byte is equal to STX, it changes to a 2-byte sequence: (ESC) + (STX + 1). If this byte is equal to ESC, it changes to a 2-byte sequence: (ESC) + (ESC + 1).
CRCL1 or 2 bytes0x00-0xFF except 0x02LSB of packet CRC. CRC-16 is used. CRC is calculated for all packet bytes from ADDR to the last data byte. CRC is calculated after the ESC changing procedure. If this byte is equal to STX, it changes to a 2-byte sequence: (ESC) + (STX + 1). If this byte is equal to ESC, it changes to a 2-byte sequence: (ESC) + (ESC + 1).

Data delivery control

The communication procedure can be divided into three parts:

  • Send request (opposite side receives request)
  • Wait for response (opposite side analyzes request)
  • Receive response (opposite side sends response)

“Send request” consists of sending the STX, sending the data length and data using the byte changing procedure, calculating the CRC, and sending the CRC.

“Receive response” consists of finding the STX and starting the CRC calculation. If the received address is invalid, the search for the STX byte is repeated. If the address is valid, the data length and data bytes are received. The CRC counter then stops and two CRC bytes are received. These bytes are compared with the calculated CRC value.

After sending a request, the guard timer is started to detect if a response is not received within the timeout period.

PSoC 6 implementation

The UART SCB Components are used to physically generate the signals. The software CRC-16 calculation is applied to every sent/received byte (except STX and the CRC itself). To detect an unsuccessful packet transaction, the timer is used.

Three interrupts implemented in this project provide a fully interrupt-driven background process:

  • The transmit interrupt in the UART is configured for a FIFO not full event to take the new data from the RAM and place it into the TX buffer, and for a transmit complete event to start or stop the CRC calculation
  • The receive interrupt in the UART is configured for a FIFO not empty event to analyze the received data, calculate the CRC, and store the received data into RAM
  • The timer interrupt is used to detect the end of an unsuccessful transmission

This software unit is implemented as an interrupt-driven driver. That is, the user only starts the process and checks the state of the unit. All operation is done in the background.

Four functions for working with the protocol unit for the master

Function1
void UartMesMaster_Init(CySCB_Type* uart_base, TCPWM_Type* counter_base,  uint32_t cntNum);
Returns: None
Located in: SelfTest_UART_master_message.h
SelfTest_UART_master_message.c

This function initializes the UART message unit.

Function 2
uint8 UartMesMaster_DataProc(uint8_t address, uint8_t *txd, uint8_t tlen, uint8_t * rxd, uint8_t rlen)
Parameters:
address - slave address for data transfer
txd - pointer to transmitted data
tlen - size of transmitted data in bytes
rxd - pointer to the buffer where the received data will be stored
rlen - size of received data buffer
Returns:
0 - No error
1 - Error detected
Located in:
SelfTest_UART_master_message.h
SelfTest_UART_master_message.c

This function starts the process of transmitting and receiving messages and returns the result of the process start: 0 = success and 1 = error. An error can occur because the unit is already busy sending a message or a null transmitting length was detected.

Function 3
uint8 UartMesMaster_State(void)
Returns:
0 (UM_COMPLETE) – the last transaction process finished successfully, the received buffer contains a response. The unit is ready to start a new process
1 (UM_ERROR) – the last transaction process finished with an error and the unit is ready to start a new process
2 (UM_BUSY) – the unit is busy with an active transaction operation.
Located in:
SelfTest_UART_master_message.h
SelfTest_UART_master_message.c

This function returns the current state of the UART message unit.

Function 4
uint8 UartMesMaster_GetDataSize(void)
Returns:
Received data size in buffer
Located in:
SelfTest_UART_master_message.h
SelfTest_UART_master_message.c

This function returns the received data size that is stored in the receive buffer. If the unit is busy or the last process generated an error, it returns 0.

Four functions for working with the protocol unit for the slave

Function 1
void UartMesSlave_Init(CySCB_Type* uart_base, uint8_t address)
Parameter:
uart_base - The pointer to the slave UART SCB instance.
address: Slave address
Returns:
None
Located in:
SelfTest_UART_slave_message.h
SelfTest_UART_slave_message.c
Function 2
uint8 UartMesSlave_Respond(char * txd, uint8 tlen)
Parameters:
txd: Pointer to the transmitted data (request data)
tlen: Length of the request in bytes
Returns:
0 - No error
1 - Error detected
Located in:
SelfTest_UART_slave_message.h
SelfTest_UART_slave_message.c

This function starts respond. It returns the result of process start. Success is 0, and error is 1 (the unit has not received a marker).

Function 3
uint8 UartMesSlave_State(void)
Returns:
0 (UM_IDLE) – the last transaction process is finished
1 (UM_PACKREADY) – the unit has received a marker and there is received data in the buffer. The master waits for a response.
2 (UM_RESPOND) – the unit is busy with sending a response.
Located in:
SelfTest_UART_slave_message.h
SelfTest_UART_slave_message.c

This function returns the current state of the UART message unit.

Function 4
uint8 * UartMesSlave_GetDataPtr(void)
Returns:
Returns pointer to received data buffer
Located in:
SelfTest_UART_slave_message.h
SelfTest_UART_slave_message.c

This function obtains a pointer to the received data.

Communications SPI test

This test implements the SPI internal data loopback test. The test is a success if the transmitted byte is equal to the received byte and returns 2. Each function call increments the test byte. After 256 function calls, when the test finishes testing all 256 values and they are all a success, the function returns 3. 256 bytes are tested so that all of the cells in the 256 byte FIFO are used.

The Serial Communication Block has a loopback capability that is used to enable this test.

Function

uint8 SelfTest_SPI_SCB (CySCB_Type *base, cy_stc_scb_spi_config_t const *config, cy_stc_scb_spi_context_t *context)

Parameters:

base – Base address of the UART to test

config – The pointer to the configuration structure cy_stc_scb_spi_config_t

context- The pointer to the context structure cy_stc_scb_spi_context_t.

Returns:

0 – Pass, tested with all values in range from 0x00 to 0xFF

1 – Pass test with current values, but not all tests in range from 0x00 to 0xFF have completed

2 – ERROR_DATA_MISMATCH

3 – ERROR_TX_NOT_EMPTY

4 – ERROR_RX_NOT_EMPTY

5 – ERROR_TX_NOT_ENABLE or ERROR_RX_NOT_ENABLE

Located in: stl_SPI_SCB.h

stl_SPI_SCB.c

The input and output terminals switch between the corresponding pins and loop to each other to provide the internal loopback test by using the SmartIO.

Communications I2C test

This test requires connecting the I2C Master and Slave externally as per Figure 8.

This project uses an I2C Master as component under test (Figure 9). With no modifications, the project can also be used for testing I2C Slave l (Figure 10). The end application must have the capability of configuring I2C Master as I2C Multi Master.

  1. Master periodically sends an I2C data addressing slave [0x08]
  2. Slave reads the data, complements, and writes to slave read buffer
  3. Master reads the data from slave and compares it with the complement of data sent in last interaction

Function

uint8 SelfTest_I2C_SCB(CySCB_Type *base, cy_stc_scb_i2c_config_t const *config, cy_stc_scb_i2c_context_t *context)

Parameters:

base_addr – Base address of the i2c to test

config – The pointer to the configuration structure cy_stc_scb_i2c_config_t

context- The pointer to the context structure cy_stc_scb_i2c_context_t.


Returns:

0 – Pass, tested with all values in range from 0x00 to 0xFF

2 – Error detected

3 – I2C Master Busy

Located in:stl_I2C_SCB.h
stl_I2C_SCB.c

I2C Write API - Operation

  • Initiates I2C Master transaction to write data to the slave
  • Waits for Write transfer completion
  • Reads the Slave Write buffer
  • Performs 1's complement on the read data
  • Writes the complemented data to Slave Read Buffer

I2C Read API - Operation

  • Initiates I2C Master transaction to read data from the slave
  • Waits for Read transfer completion
  • Checks whether the data read is equal to the complement of data written

Communications CAN-FD test

The CAN-FD block is tested using the loopback capability. The test steps are:

  1. Enable loopback externally or internally based on the parameter passed
  2. Configure CAN-FD to accept message IDs in the range 0x50 to 0x55 in any of the RX FIFO (1 or 2)
  3. Transmit a message with message ID 0x60
  4. Verify that the RX FIFO is empty
  5. Transmit a message with message ID 0x50
  6. Verify that the message is received correctly in the RX FIFO

Function

uint8_t SelfTest_CANFD(CANFD_Type *base, uint32_t chan, const cy_stc_canfd_config_t *config, cy_stc_canfd_context_t *context, stl_canfd_test_mode_t test_mode);

Parameters:

base - The pointer to a CAN FD instance. &lt;br&gt;
chan - The CAN FD channel number. &lt;br&gt;
config - The pointer to the CAN FD configuration structure.
context - The pointer to the context structure allocated by the user. The structure is used during the CAN FD operation for internal configuration and data retention. User must not modify anything in this structure.
test_mode - internal : will not drive the pin , external : will drive the external pins along with loopback


Returns:

0 - No error
1 - Error detected

Located in: SelfTest_CANFD.c
SelfTest_CANFD.h

If the CAN bus fails to operate, the device should fail-safe. CAN-FD to be tested from IP side with loop back mode.

List of test files

Table 5. Test files

File nameVersion
SelfTest_Analog.c2.0.0.827
SelfTest_Analog.h2.0.0.827
SelfTest_CANFD.c2.0.0.827
SelfTest_CANFD.h2.0.0.827
SelfTest_Clock.c2.0.0.827
SelfTest_Clock.h 2.0.0.827
SelfTest_CPU.c2.0.0.827
SelfTest_CPU.h2.0.0.827
SelfTest_CPU_Regs.h2.0.0.827
SelfTest_CRC_calc.c2.0.0.827
SelfTest_CRC_calc.h 2.0.0.827
SelfTest_DMA_DW.c2.0.0.827
SelfTest_DMA_DW.h2.0.0.827
SelfTest_DMAC.c2.0.0.827
SelfTest_DMAC.h2.0.0.827
SelfTest_Flash.c2.0.0.827
SelfTest_Flash.h 2.0.0.827
SelfTest_FPU_Regs.c2.0.0.827
SelfTest_FPU_Regs.h2.0.0.827
SelfTest_Interrupt.c2.0.0.827
SelfTest_Interrupt.h 2.0.0.827
SelfTest_IO.c2.0.0.827
SelfTest_IO.h2.0.0.827
SelfTest_IPC.c2.0.0.827
SelfTest_IPC.h2.0.0.827
SelfTest_PWM.c2.0.0.827
SelfTest_PWM.h2.0.0.827
SelfTest_PWM_GateKill.c2.0.0.827
SelfTest_PWM_GateKill.h2.0.0.827
SelfTest_RAM.c2.0.0.827
SelfTest_RAM.h2.0.0.827
SelfTest_ConfigRegisters.c2.0.0.827
SelfTest_ConfigRegisters.h2.0.0.827
SelfTest_UART_SCB.c2.0.0.827
SelfTest_UART_SCB.h2.0.0.827
SelfTest_I2C_SCB.c2.0.0.827
SelfTest_I2C_SCB.h2.0.0.827
SelfTest_SPI_SCB.c2.0.0.827
SelfTest_SPI_SCB.h2.0.0.827
SelfTest_UART_master_message.c2.0.0.827
SelfTest_UART_master_message.h2.0.0.827
SelfTest_UART_slave_message.c2.0.0.827
SelfTest_UART_slave_message.h2.0.0.827
SelfTest_Stack.c2.0.0.827
SelfTest_Stack.h2.0.0.827
SelfTest_Timer_Counter.c2.0.0.827
SelfTest_Timer_Counter.h2.0.0.827
SelfTest_WDT.c2.0.0.827
SelfTest_WDT.h2.0.0.827
SelfTest_WWDT.c2.0.0.827
SelfTest_WWDT.h2.0.0.827
UART_Debug.c2.0.0.827
UART_Debug.h2.0.0.827

Summary

This application note described how to implement diagnostic tests defined by the IEC 60730 standard. Incorporation of this standard into the design of white goods and other appliances will add a new level of safety for consumers.

By taking advantage of the unique hardware configurability offered by PSoC™ 6, designers can comply with regulations while maintaining or reducing electronic systems cost. Use of PSoC™ and the Safety Software Library enables the creation of a strong system-level development platform to achieve superior performance, fast time to market, and energy efficiency.

Appendix A: Set checksum in flash (invariable memory) test

The following instructions will help you program your part for proper flash and ROM diagnostic testing.

  1. Build a project in ModusToolbox™ and store the checksum value set to 0x0000 in the source file.

    For the GCC compiler:

    #if defined(__GNUC__)
    /* Allocate last 8 bytes in Flash for flash checksum for PSoC6 */
    static volatile const uint64_t flash_StoredCheckSum __attribute__((used,
    section(".flash_checksum"))) =
    0x0000000000000000ULL;
    #endif
  2. Read the calculated flash checksum. There are two ways:

    1. Read the checksum in debug mode

      1. Open the project file SelfTest_Flash.c and set the breakpoint in debug mode to the line shown in Figure 7
      2. Figure 7. Stored checksum in debug mode



      3. Press [F10] to single step past the breakpoint location and hover the mouse over the variable “flash_CheckSum.” A value stored in this variable should appear, as shown in Figure 8.

        Figure 8. Retrieve the stored checksum value in debug mode



    2. Read the checksum using the communication protocol:

      1. To speed up the process of testing the flash checksum outputs, use a UART. This feature is implemented in Class B firmware. It will print the calculated checksum value when the stored flash checksum does not match the calculated flash checksum. To use this project, set the UART parameters shown in Figure 9.

        Figure 9. Checksum output using UART



  3. Copy this checksum value and store it in the checksum location, but remember that PSoC™ 6 uses little endian format. The project for the GCC compiler is shown in Figure 10.

    Figure 10. Reassign checksum constant with actual checksum



  4. Compile the project and program PSoC™

Appendix B: IEC 60730-1 certificate of compliance

Appendix C: Supported part numbers

The certified libraries support the following PSoC™ 6 families:

  • CY8C61x
  • CY8C62x
  • CY8C63x
  • CY8C64x

For details on the supported part numbers, see the ordering information section of the corresponding device datasheet.

Appendix D: MISRA compliance

Table 6

and

Table 7

in this appendix provide details on MISRA-C:2004 compliance and deviations for the test projects. The motor industry software reliability association (MISRA) specification covers a set of 122 mandatory rules and 20 advisory rules that apply to firmware design. The automotive industry compiled it to enhance the quality and robustness of the firmware code embedded in automotive devices.

Table 6. Verification environment

ComponentNameVersion
Test specificationMISRAC:2012 guidelines for the use of the C language in critical systems3 rd edition, Feb 2019
Target deviceCY8C61x, CY8C62x, CY8C63x, CY8C64xProduction
Target compiler GCCv11.3.1
Generation tool ModusToolbox™v3.2
Peripheral Driver LibraryPDL mtb-pdl-cat2 V2.12.0
MISRA checking tool Coverity Static Analysis Tool2022.12.0

Table 7. Deviated rules

MISRA-C:2012 ruleRule class (R/A)Rule description

Description of deviation(s)

1.2ALanguage extensions should not be used.Using low level compiler specific commands are required. Confirmed correct for each supported compiler.
2.5AA project should not contain unused macro declarationsNot all features of library are able to be enabled at the same time, so macros required for disabled tests appear unused.
3.1 R The character sequences /* and // shall not be used within a comment.Hyper Link used with “/” and “//”. Only included in comments for use in documenting the library. Not used in code.
4.6ATypedefs that indicate size and signedness should be used in place of the basic numerical types.Variables declared using basic numerical types are used as the expression to iterate the for loop. This doesnot have any major impact on the code functionality.
4.8AIf a pointer to a structure or union is never dereferenced within a Translation Unit, then the implementation of the object should be hidden.The implementation of an object need only be hidden if all pointers to that type in a translation unit are never dereferenced and there are no other reasons for the internal details of the structure/union to be known.
4.9 AA function should be used in preference to a function-like macro where yet are interchangeable.Using function like macros unavoidable because use of platform PDL.
5.5RIdentifiers shall be distinct from macro names

The diagnostic rule requires that macro identifiers should be distinct within the limits recommended by standard.

C90: 31 first characters

C99: 63 first characters

5.8RIdentifiers that define objects or functions with external linkage shall be unique

An identifier with external keyword should be unique in a program. The name should not be used by other identifiers .

5.9AIdentifiers that define objects or functions with internal linkage should be unique

An identifier with external keyword should be unique in a program. The name should not be used by other identifiers .

8.3RAll declarations of an object or function shall use the same names and type qualifiers

It demands that the declaration and definition are identical, and the declaration must be in prototype format

8.4RA compatible declaration shall be visible when an object or function with external linkage is defined

Use extern keyword for identifier wherever is possible

8.5RAn external object or function shall be declared once in one and only one file

Objects or functions with external linkage should be declared once.

8.6RAn identifier with external linkage shall have exactly one external definition.Declared but never defined in C. Defined in assembly files.
8.7AFunctions and objects should not be defined with external linkage if they are referenced in only one translation unit.Remove global variables as possible based on safety library integration with user project.
8.9AAn object should be defined at block scope if its identifier only appears in a single functionScope is dependent on library integration in user project.
8.13AA pointer should point to a const-qualified type whenever possibleFalse positives.
11.4AA conversion should not be performed between a pointer to object and an integer typeCasting pointer to integer and vice versa unavoidable due to PDL use requirements.
13.2RThe value of an expression and its persistent side effects shall be the same under all permitted evaluation ordersUsing a volatile variable more than once in a evaluation. This is ok since the only time the volatile variable has more than 1 operation per evaluation is in the ISR.
14.3RControlling expressions shall not be invariantBoolean expression always evaluates true unavoidable due to use of PDL
15.5AA function should have a single point of exit at the end.

A function should have only one 'return' statement, which must come after all the other statements in the function's body. Multiple 'return' statements could obscure the code and make it harder to maintain.

18.4AThe +, -, += and -= operators should not be applied to an expression of pointer type

Pointers should not be used in expressions with the operators '+', '-', '+=', and '-=' but can be used with the subscript '[]' and increment/decrement ('++'/'--') operators.

References

  • IEC 60730 Standard, “Automatic electrical controls for household and similar use,” IEC 60730-1 Edition 3.2, 2007-03

Revision history

Document revisionDateDescription of changes
**2024-09-18Initial release