7. PRU-ICSS Firmware¶
7.6. PRU-ICSS ESPI¶
7.6.1. Introduction¶
7.6.2. Firmware Organization¶
FW Item | Directory |
---|---|
Source code | <PDK>/packages/ti/drv/spi/firmware/icss_espi/src/ |
Design Guide | <PDK>/packages/ti/drv/spi/docs/ |
7.6.3. Firmware Build Instruction¶
7.6.3.1. Build instruction from Processor SDK Release package¶
Pre-requisites to Building
Refer to the Processor SDK RTOS Building page for information on setting up the build environment.
Compiling Driver/Firmware
make spi
Running CCS Application
CCS applications will be build and run just like any other project with one exception. Before loading the binary, from the menu-bar run Scripts > PRU_ICSS > PRU_ICSS_Init
.
7.6.4. Supported EVMs¶
Supported EVMs and pin configurations for these EVMs are listed below. See the design document in <PDK>/packages/ti/drv/spi/docs/
for more information.
EVM Name | PRU-ICSS Instances | PRU-ICSS Revision |
---|---|---|
bbbAM335x | 1 | REV1 |
idkAM437x | 2 | REV1 |
bbbAM335x
Core | PRU | Functional Pin | GPIO Pins | EVM Port | EVM Pin |
---|---|---|---|---|---|
ICSS1 | PRU1 |
|
pr1_pru0_pru_r30_4 | J3 | 41 |
pr1_pru0_pru_r30_5 | J3 | 42 | |||
pr1_pru0_pru_r30_6 | J3 | 39 | |||
pr1_pru0_pru_r30_7 | J3 | 40 | |||
pr1_pru0_pru_r30_9 | J3 | 29 | |||
pr1_pru0_pru_r30_10 | J3 | 28 | |||
pr1_pru0_pru_r30_0 | J3 | 45 | |||
pr1_pru0_pru_r30_1 | J3 | 46 | |||
pr1_pru0_pru_r30_2 | J3 | 43 | |||
pr1_pru0_pru_r30_3 | J3 | 44 | |||
pr1_pru0_pru_r30_8 | J3 | 27 | |||
pr1_pru0_pru_r30_11 | J3 | 30 | |||
A8 | n/a | Reset | GPIO_3_19 | J9 | 26 |
idkAM437x
Core | PRU | Functional Pin | GPIO Pins | EVM Port | EVM Pin |
---|---|---|---|---|---|
ICSS1 | PRU0 |
|
pr1_pru0_pru_r30_6 | P16 | 49 |
pr1_pru0_pru_r30_11 | P16 | 48 | |||
pr1_pru0_pru_r30_8 | P16 | 6 | |||
pr1_pru0_pru_r30_16 | P16 | 42 | |||
pr1_pru0_pru_r30_10 | P16 | 46 | |||
pr1_pru0_pru_r30_9 | P16 | 8 | |||
A9 | n/a | Reset | GPIO_5_9 | P16 | 32 |
7.6.5. eSPI Applications¶
We have included a simple example test application which handles PUT_IORD_SHORT, PUT_IOWR_SHORT, PUT_MEMRD32_SHORT, and PUT_MEMWR32_SHORT packets with expected address/data values. This can be used as a starting point to build your own applications, along with the following: - eSPI uses the MCSPI API
- Open as MCSPI instance 2
- HW interrupts must be enabled
- i.e. HwiP_enableInterrupt(espi_cfg.intNum)
- MCSPI_transfer() is blocking and takes a SPI_Transaction parameter which is used as follows:
- RX Transfer: - transaction.rxBuf = <some pre-allocated buffer> - transaction.txBuf = Null - transaction.count = max packet size
- TX Transfer: - transaction.rxBuf = Null - transaction.txBuf = <some pre-allocated buffer> - transaction.count = <size of packet>
The application must parse the full eSPI packet, and must respond with the full proper eSPI packet (the RSP code and CRC will be taken care of by the firmware)
example-application
/* Refer to eSPI FW Example for details */
Board_init(boardCfg);
...
/* Initialize the ESPI fw configuration */
ESPI_socInitFwCfg();
/* Get the default ESPI init configurations */
ESPI_socGetFwCfg(ESPI_INSTANCE, &espi_cfg);
/* Modify the default eSPI configurations if necessary */
/* Set the default ESPI init configurations */
ESPI_socSetFwCfg(ESPI_INSTANCE, &espi_cfg);
/* Set GPIO pin configurations */
GPIO_setConfig(ESPI_GPIO_PIN_RESET, GPIO_DEVICE_CONFIG(espi_cfg.resetPin.port,
espi_cfg.resetPin.pinNum) |
GPIO_CFG_IN_INT_RISING | GPIO_CFG_INPUT);
/* Initialize GPIO */
GPIO_init();
/* Initialize the MCSPI paramters */
MCSPI_Params_init(&mcspiParams);
/* Init SPI driver */
MCSPI_init();
/* Enable interrupts (necessary for */
HwiP_enableInterrupt(espi_cfg.intNum);
/* Grab ESPI handle from SoC config list */
fwHandle = (MCSPI_Handle)MCSPI_open(ESPI_INSTANCE, 0, &mcspiParams);
...
/* Read ESPI Packet */
transaction.txBuf = NULL; /* indicates we want RX */
transaction.rxBuf = (uint8_t*) rxBuf;
transaction.count = ESPI_PACKET_MAX_SIZE;
retVal = MCSPI_transfer(fwHandle, &transaction); /* blocking */
...
/* Prepare TX response */
transaction.txBuf = (uint8_t*) txBuf;
transaction.rxBuf = NULL; /* indicates we want TX */
transaction.count = ESPI_PACKET_MAX_SIZE;
...
/* Put response in TX queue */
retVal = MCSPI_transfer(fwHandle, &transaction);
...
Examples List
Refer to the Release Notes for details concerning eSPI support across different EVMs.
Name | Description | Expected Results |
---|---|---|
ESPI_FwExample | Driver Firmware example application for ESPI FW instances | A short write to 0xDEAD or 0x0D0E0A0D will not print or return anything. A short read from 0xDEAD or 0x0D0E0A0D will return the command opcode + the byte-number of the response. A read from any other address will return the opcode minus the byte-number of the response. |
Firmware Design Guide
Document | Location |
---|---|
eSPI FIRMWARE Design Guide | <PDK>/packages/ti/drv/spi/docs/ESPI_FW_DESIGN_GUIDE.doc |
NOTE: For normal use of eSPI FW, there is no need to refer to the design guide. This document can be cosulted in case of interest in details of internal firmware operation, or a desire to modify the firmware.
7.7. PRU-ICSS UART¶
7.7.1. Introduction¶
7.7.2. FIRMWARE FEATURES¶
The following UART specifications are supported by the PRU UART firmware:
- Up to 3 UARTs are supported per PRU with the following configuration options
- Baud rate: common baud rates up to 115200
- Bits per transfer: 5-9 bit characters
- Number of stop bits: 1, 1.5, 2
- Parity: even, odd, none
- Flow control: HW, none (SW flow control currently unsupported)
- Full-duplex communication
- Each UART can simultaneously support different configurations
- UART0 can have a different baud rate, number of stop bits, etc. when compared to UART1 or UART2 in the same PRU
- The firmware is self-contained in a single PRU
- The firmware does not use shared resources within an ICSS including IEP Timer and Scratchpad
- In case 3 or less UART instances are required, only one PRU core is required for the UART firmware
The table below shows a comparison of the features supported by the UART firmware with those available on hardware IP.
UART Supported Feature | Hardware IP | Software IP (Firmware) |
Number of hardware instances | SoC dependent | 3 (per PRU) |
Baud rates | SoC dependent (up to 12 Mbps) | All common baud rates between 300-115200 |
Bits per character | 5-8 bits | 5-9 bits |
Number of stop bits | 1, 1.5, 2 | 1, 1.5, 2 |
Parity types | Even, Odd, Mark, Space, none | Even, Odd, none |
Flow control types | HW, SW, none | HW, none |
7.7.3. Firmware Organization¶
FW Item | Directory |
Source code | <PDK>/packages/ti/drv/uart/firmware/icss_i2c/src |
Design Guide | <PDK>/packages/ti/drv/uart/docs |
7.7.4. Firmware Build Instructions¶
7.7.4.1. Build instructions from Processor SDK Release package¶
Pre-requisites to Building
Refer to the Processor SDK RTOS Building page for information on setting up the build environment.
Compiling UART Firmware
- cd <PDK>/packages/ti/drv/uart
- make firm
Compiling UART LLD
- cd <PDK>/packages/ti/drv/uart
- make lib
Compiling UART Driver & Firmware
- cd <PDK>/packages/
- make uart
Firmware binaries at the end of the firmware build will be located at:
- <PDK>/packages/ti/drv/uart/firmware/<FIRMWARE_TYPE>/bin/<SOC>/<HOST_CORE>/<REVISION>
- <FIRMWARE_TYPE> indicates the firmware type i.e. icss_uart
- <SOC> indicates the SOC type, e.g. am335x
- <HOST_CORE> indicates the Host core type on which the built binary can be loaded, e.g. a8host
- <REVISION> indicates the revision of the firmware binary based on core (there are 2 revision of PRU-ICSS core), e.g. REV1.
7.7.5. Supported EVMs¶
Supported EVMs and pin configurations for these EVMs are listed below. See the design document in <PDK>/packages/ti/drv/uart/docs/
for more information.
EVM Name | PRU-ICSS Instances | PRU-ICSS Revision |
---|---|---|
bbbAM335x | 6 | REV1 |
bbbAM335x
ICSS | PRU | Instance | Functional Pin | PRU GPIO Pins | EVM Port | EVM Pin |
---|---|---|---|---|---|---|
ICSS1 | PRU0 | UART0 | TX | pr1_pru0_pru_r30_0 | P9 | 31 |
RX | pr1_pru0_pru_r31_1 | P9 | 29 | |||
CTS | - | - | - | |||
RTS | - | - | - | |||
ICSS1 | PRU0 | UART1 | TX | pr1_pru0_pru_r30_2 | P9 | 30 |
RX | pr1_pru0_pru_r31_3 | P9 | 28 | |||
CTS | - | - | - | |||
RTS | - | - | - | |||
ICSS1 | PRU0 | UART2 | TX | pr1_pru0_pru_r30_5 | P9 | 27 |
RX | pr1_pru0_pru_r31_7 | P9 | 25 | |||
CTS | - | - | - | |||
RTS | - | - | - | |||
ICSS1 | PRU1 | UART0 | TX | pr1_pru0_pru_r30_0 | P8 | 45 |
RX | pr1_pru0_pru_r31_1 | P8 | 46 | |||
CTS | pr1_pru1_pru_r31_2 | P8 | 43 | |||
RTS | pr1_pru1_pru_r30_3 | P8 | 44 | |||
ICSS1 | PRU1 | UART1 | TX | pr1_pru0_pru_r30_4 | P8 | 41 |
RX | pr1_pru0_pru_r31_5 | P8 | 42 | |||
CTS | pr1_pru1_pru_r31_6 | P8 | 39 | |||
RTS | pr1_pru1_pru_r30_7 | P8 | 40 | |||
ICSS1 | PRU1 | UART2 | TX | pr1_pru0_pru_r30_8 | P8 | 27 |
RX | pr1_pru0_pru_r31_9 | P8 | 29 | |||
CTS | pr1_pru1_pru_r31_10 | P8 | 28 | |||
RTS | pr1_pru1_pru_r30_11 | P8 | 30 |
7.7.6. UART Firmware Example & Test¶
Example are test applications are available in the package for reference purpose and starting point.
The example application uses the UART stdio API to repeatedly read characters transmitted from a PC UART. The acquired characters are then written (echoed) back to the PC UART.
The test applications are more complex than the example application, and perform many more types of UART transfers than the example application. The test applications performs transfers using UART software IP (implemented in PRU firmware) and hardware IPs with different combinations of UART settings. Both the UART and UART stdio APIs are exercised (note the UART software and hardware IPs use the same UART-LLD API). The test applications are further described in the Firmware Design Guide.
Sample code for UART write & read:
/* Refer to UART FW example & tests for details */
...
/* Initialize the UART FW configuration */
UART_socInitFwCfg();
Board_init(boardCfg);
...
UART_init();
/* Get the default UART init configuration */
UART_socGetFwCfg(uartInst, &uart_cfg);
/* Modify the default UART configurations if necessary */
/* Set the default UART init configurations */
UART_socSetFwCfg(uartInst, &uart_cfg);
...
UART_Params_init(&uartParams);
uartParams.readCallback = UART_callback;
uartParams.readMode = UART_MODE_CALLBACK;
uartParams.writeCallback = UART_callback;
uartParams.writeMode = UART_MODE_CALLBACK;
uartParams.parityType = UART_PAR_NONE;
handle = UART_open(uartInst, &uartParams);
...
/* Initiate UART write */
UART_transactionInit(&wrCbTransaction);
wrCbTransaction.buf = (void *)wrBuff;
wrCbTransaction.count = sizeof(wrBuffer)/2;
if (UART_write2(handle, &wrCbTransaction) == UART_ERROR) {
/* UART write failed */
}
...
/* Initiate UART read */
UART_transactionInit(&rdCbTransaction);
rdCbTransaction.buf = (void *)rdBuff;
rdCbTransaction.count = sizeof(rdBuffer)/2;
if (UART_read2(handle, &callbackTransaction) == UART_ERROR) {
/* UART read failed */
}
List of Examples & Tests
Refer to the Release Notes for details concerning UART support across different EVMs.
Name | Description | Expected Results |
---|---|---|
UART_FwExample | Example application for PRU UART FW driver | Status messages will be displayed on console based based on pass/fail criteria: Pass criteria: All Passed |
UART_FwTest | Simple test application for PRU UART FW driver | Status messages will be displayed on console based on pass/fail criteria: Pass criteria: All tests have passed. |
UART_FwTestExtLb | More complex test test application for PRU UART FW driver, superset of UART_FwTest | Status messages will be displayed on console based on pass/fail criteria: Pass criteria: All tests have passed. |
Firmware Design Guide
Document | Location |
UART Firmware Design Guide | <PDK>/packages/ti/drv/uart/docs/UART_FW_DESIGN_GUIDE.pdf |
NOTE: Design document includes details for internal firmware implementation and can be used in case of modification required for firmware.