7. PRU-ICSS Firmware

7.6. PRU-ICSS ESPI

7.6.1. Introduction

PRU-ICSS eSPI serves as an example for firmware-based eSPI peripheral support. The Processor SDK package includes full source code for eSPI FW.

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

  1. 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

OUT[0]

pr1_pru0_pru_r30_4

J3

41

OUT[1]

pr1_pru0_pru_r30_5

J3

42

OUT[2]

pr1_pru0_pru_r30_6

J3

39

OUT[3]

pr1_pru0_pru_r30_7

J3

40

Alert

pr1_pru0_pru_r30_9

J3

29

EN

pr1_pru0_pru_r30_10

J3

28

IN[0]

pr1_pru0_pru_r30_0

J3

45

IN[1]

pr1_pru0_pru_r30_1

J3

46

IN[2]

pr1_pru0_pru_r30_2

J3

43

IN[3]

pr1_pru0_pru_r30_3

J3

44

SCL

pr1_pru0_pru_r30_8

J3

27

CS

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

OUT[0]

pr1_pru0_pru_r30_6

P16

49

Alert

pr1_pru0_pru_r30_11

P16

48

EN

pr1_pru0_pru_r30_8

P16

6

IN[0]

pr1_pru0_pru_r30_16

P16

42

SCL

pr1_pru0_pru_r30_10

P16

46

CS

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

PRU-ICSS UART serves as an example for PRU firmware-based UART peripheral support. The UART firmware (UART FW) allows additional UART instances for SOCs beyond those supported by SOC hardware. The Processor SDK package includes full source code for UART FW.

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.