Programmable Real-Time Unit and Industrial Communication Subsystem(PRU-ICSS) driver provides a well-defined API layer which allows applications to use the PRU-ICSS. PRU-ICSS is firmware programmable and can take on various personalities like Industrial Communication Protocol Switch (for protocols like EtherCAT, Profinet, EtherNet/IP), Ethernet Switch, Ethernet MAC, Industrial Drives, etc.
Features Supported
- PRU control features like enabling/disabling/resetting a Programmable Real-Time Units (PRU0 and PRU1), Auxiliary Programmable Real-Time Units (RTU_PRU0 and RTU_PRU1) or Transmit Programmable Real-Time Units (TX_PRU0 and TX_PRU1) core
- Loading the firmware in PRU cores
- Read/Write/Reset different memories inside PRU-ICSS
- PRU and Host Event management. It does mapping of sys_evt/channel/hosts in the INTC module. APIs to register interrupt handler for events, generate an event, wait for occurrence of an event, and clear an event.
- Basic configurations in registers like GPCFG, MII_RT_G_CFG, ICSSG_SA_MX
- IEP clock selection, IEP counter enable/disable, IEP counter increment configuration
- PRU Constant Table Configuration
SysConfig Features
- Note
- It is strongly recommend to use SysConfig where it is available instead of using direct SW API calls. This will help simplify the SW application and also catch common mistakes early in the development cycle.
- Option to select the PRU-ICSS instance
- Option to select the Core Clock Frequency
- Option to enable the IEP Sync Mode
- Option to select the IEP Clock Frequency if IEP Sync Mode is disabled
- Optional sub-module to select pin configurations
- Optional sub-module to select ICSS interrupt controller signals mapping
- Based on above parameters, the SysConfig generated code does following:
- Call PRUICSS_init in System_init, and PRUICSS_deinit in System_deinit
- Enable the Core Clock and set the selected frequency
- Create macros like
CONFIG_PRU_ICSS1
using the name passed in SysConfig. This is used as an input to PRUICSS_open API.
- Set hardware register for enabling IEP Sync mode in System_init
PRUICSS Interrupt Controller
The interrupt controller (INTC) module maps interrupts coming from different parts of the device (mapped to PRU-ICSS instance) to a reduced set of interrupt channels.
The interrupt controller has the following features:
- Capturing up to 160 Events (inputs)
- Upper 96 are external events
- Lower 64 are internal events
- Supports up to 20 output interrupt channels
- Generation of 20 Host Interrupts
- 2 Host Interrupts shared between the PRUs (PRU0 and PRU1) and TX_PRUs (TX_PRU0 and TX_PRU1).
- 2 Host Interrupts for the RTU PRUs (RTU_PRU0 and RTU_PRU1).
- 8 Host Interrupts exported from the PRU_ICSSG internal INTC for signaling the device level interrupt controllers (pulse and level provided).
- 8 Host Interrupts (event 12 through 19) for the Task Managers.
- Each event can be enabled and disabled.
- Each host event can be enabled and disabled.
- Hardware prioritization of events.
Following are some important points related to INTC configuration:
- Any of the 160 internal interrupts can be mapped to any of the 20 channels.
- Multiple interrupts can be mapped to a single channel.
- An interrupt should not be mapped to more than one channel.
- Any of the 20 channels can be mapped to any of the 20 host interrupts. It is recommended to map channel "x" to host interrupt "x", where x is from 0 to 19.
- A channel should not be mapped to more than one host interrupt
- For channels mapping to the same host interrupt, lower number channels have higher priority.
- For interrupts on same channel, priority is determined by the hardware interrupt number. The lower the interrupt number, the higher the priority.
- Host Interrupt 0 is connected to bit 30 in register 31 (R31) of PRU0 and PRU1 in parallel.
- Host Interrupt 1 is connected to bit 31 in register 31 (R31) for PRU0 and PRU1 in parallel.
- Host Interrupts 2 through 9 exported from PRU-ICSS and mapped to device level interrupt controllers.
- Host Interrupt 10 is connected to bit 30 in register 31 (R31) to both RTU_PRU0 and RTU_PRU1 in parallel.
- Host Interrupt 11 is connected to bit 31 in register 31 (R31) to both RTU_PRU0 and RTU_PRU1 in parallel.
- Host Interrupts 12 through 19 are connected to each of the 4 Task Managers.
For industrial communication protocol examples running on R5F, Host Interrupts 2 through 9 exported from PRU-ICSS are used for signalling an interrupt to R5F. As this mapping is programmable and varies from example to example, we have a *_pruss_intc_mapping.h
file for different protocol examples which is used for passing PRUICSS_IntcInitData structure while calling PRUICSS_intcInit API.
Sysconfig for INTC
You may use the sysconfig interface for PRU_ICSSG Local INTC mapping.
Sysconfig will create (see on right side generated code)
- PRUICSS_IntcInitData structures for interrupt mapping named
icss0_intc_initdata
, icss1_intc_initdata
for ICSS0, ICSS1 instances respectively in ti_drivers_config.c
. This is for use in main app to initialize interrupt settings by passing these to PRUICSS_intcInit. The previous interrupt settings are overwritten by this so please use it only once to initialize the interrupts.
User Defined INTC Settings
Following is an example of one mapping from ${SDK_INSTALL_PATH}/source/industrial_comms/ethercat_slave/icss_fwhal/tiesc_pruss_intc_mapping.h
used for EtherCAT SubDevice.
The following line maps PRU_ARM_EVENT2
to CHANNEL6
.
CHANNEL6
is mapped to the fourth host interrupt mapped to device level interrupt controller(Host Interrupt 6 out of 20) through this line.
In AM64x, PRU_ICSSG0_PR1_HOST_INTR_PEND_0
-PRU_ICSSG0_PR1_HOST_INTR_PEND_7
(8 host interrupts) are mapped to R5FSS0_CORE0_INTR_IN_120
-R5FSS0_CORE0_INTR_IN_127
. This values are for ICSSG0 events mapped to R5FSS0 CORE0. For details regarding interrupt numbers on other cores, please refer to "9.4 Interrupt Sources" section in Technical Reference Manual(TRM) of AM64x, or corresponding section in TRM of other SoCs. These interrupt numbers can change from SoC to SoC, so please consult TRM before making any modifications to the interrupt map.
For the example mentioned above, interrupt number 124 (R5FSS0_CORE0_INTR_IN_124
) should be used for intrNum
parameter for PRUICSS_registerIrqHandler. PRUICSS_registerIrqHandler creates Hwi instance using HwiP_construct API with the intrNum
passed,
This mapping alone determines which interrupt number on R5F will be associated with a particular interrupt from PRUICSS. For example, in the code shown above, where `PRU_ARM_EVENT2
maps to CHANNEL6
, and CHANNEL6
maps to PRU_EVTOUT4
can be modified to following, and the interrupt number on R5F would still remain the same.
But the usefulness of channels is that channels allow us to map multiple PRU events to a single channel and in turn to a single host interrupt. For example, take a look at the following mapping used for link interrupt.
This configuration maps both Port 0 and Port 1 link interrupts to a single channel and in turn to a single host interrupt for PRU1 (Host Interrupt 1 out of 20).
- Note
- Please refer to section "6.4.7 PRU_ICSSG Local INTC" in Technical Reference Manual(TRM) of AM64x for more details on INTC module
Example Usage
Include the below file to access the APIs
Instance Open Example
Sequence for loading a firmware on PRU and running the PRU core
pruEvtoutNum,
intrNum,
eventNum,
waitEnable,
irqHandler);
0,
(uint32_t *) pruFirmware,
pruFirmwareLength);
API
APIs for PRUICSS