4.15. SPI

4.15.1. Introduction

SPI driver enables communication for general SPI, MCSPI (Multichannel SPI), QSPI (Quad SPI) and OSPI (Octal SPI) based peripherals on board through common API to application. MCSPI is a generic full-duplex interface supporting transmit and receive of data over SPI bus. QSPI/OSPI is a variant of SPI supports four receive data lanes. Driver supports configuration for either single, dual, quad or octal data lines

4.15.1.1. Modes of Operation

Following modes of operations are supported:

SPI_MODE_BLOCKING SPI_transfer() API blocks code execution until transaction has completed. By default, SPI driver operates in blocking mode. This ensures only one SPI transaction operates at a given time. This mode is supported in both interrupt or non-interrupt configurations.

SPI_MODE_CALLBACK SPI_transfer() API returns without waiting for completion of transaction in this case. Callback function registered by application is invoked once transaction is complete.This mode is supported only in interrupt configuration.

4.15.2. Driver Configuration

4.15.2.1. Board Specific Configuration

All board specific configurations eg:enabling clock and pin-mux for SPI pins are required before calling any driver APIs.By default Board_Init() API supports all initialization sequence for TI supported EVMs. In addition it initializes UART instance for Console/STDIO.Refer PDK Board Support for additional details.Once board specific configuration is complete SPI_init() API should be called to initialize driver.

4.15.2.2. SoC Specific Configuration

All SoC specific configurations (eg: SPI module registers base address, interrupt configurations, etc.) can be set using SPI_socSetInitCfg() SoC driver API before calling any SPI driver APIs. The default SoC specific configurations can be retrieved using SPI_socGetInitCfg() SoC driver API.

4.15.2.3. SPI Configuration Structure

The SPI_soc.c file binds driver with hardware attributes on the board through SPI_config[] structure. This structure must be provided to the SPI driver. It must be initialized before the SPI_init() function is called and cannot be changed afterwards.

Driver  requires common SPI_config[]  to configure hardware attributes of MCSPI and QSPI/OSPI peripherals on SOC and board. First all MCSPI related hardware attributes is defined followed by QSPI/OSPI hardware attributes. Application will need to include appropriate offset to instance while invoking SPI_open() API..

For details about individual fields of this library structure, see the PDK doxygen documentation

4.15.3. APIs

API Reference for application:

#include <ti/drv/spi/SPI.h>

SPI IP V1 driver also supports multi-channel API’s:

#include <ti/drv/spi/MCSPI.h>

Description

4.15.3.1. Open SPI

...
Board_init(boardCfg);
...
SPI_socGetInitCfg(peripheralNum, &spi_cfg);
...
SPI_socSetInitCfg(peripheralNum, &spi_cfg);
SPI_Params_init(&spiParams);
spiParams.transferMode = SPI_MODE_BLOCKING;
spiParams.transferCallbackFxn = NULL;
handle = SPI_open(peripheralNum, &spiParams);

SPI IP V1 driver also supports multi-channel open API’s:

...
Board_init(boardCfg);
...
MCSPI_Params_init(&spiParams);
spiParams.transferMode = SPI_MODE_BLOCKING;
spiParams.transferCallbackFxn = NULL;
handle = MCSPI_open(peripheralNum, channel, &spiParams);

At this point SPI driver is ready for data transfer in blocking mode on specific instance identified by handle. Pseudo/Sample code for SPI read/write transaction is included below. Refer example for additional details

...
spiTransaction.count = n;    /* Transfer Length */
spiTransaction. txBuf = transmitBuffer; /* Buffer to be written */
spiTransaction.rxBuf = NULL;  /* Buffer holding the received data */
transferOK = SPI_transfer(spi, &spiTransaction); /* Perform SPI transfer */
if (!transferOK) {
/* SPI transaction failed */
}

SPI IP V1 driver also supports multi-channel transfer API’s:

...
spiTransaction.count = n;    /* Transfer Length */
spiTransaction. txBuf = transmitBuffer; /* Buffer to be written */
spiTransaction.rxBuf = NULL;  /* Buffer holding the received data */
transferOK = MCSPI_transfer(spi, &spiTransaction); /* Perform SPI transfer */
if (!transferOK) {
/* SPI transaction failed */
}

Note

SPI_open API supports configuration of data word length in the SPI_Params. Currently IP V1 driver (for AM3/4/5 devices) supports 8/16/32-bit word length, IP V0 driver (for Keystone devices) supports 8/16-bit word length.

4.15.4. Examples

4.15.4.1. SPI

Name Description Expected Results SoC Supported Build Type

SPI_FlashReadWrite

Example application

Sample application demonstrating read and write of data to a NOR flash device connected over SPI interface. By default, write test is disabled, user can enable write test by defining TEST_SPI_NOR_WRITE in test/src/SPI_board.h

If write test is enabled, write transaction is verified for correctness by reading contents back.

Following prints on console expected: Pass criteria:

All tests have passed.

k2g, k2hk, k2l, k2e, c6657, c6678, omapl137, CCS project
SPI_TestApplication Driver unit test application to validate features and interfaces for SPI driver Following prints on console expected: Pass criteria: All tests have passed. am335x AM437x, AM571x, AM572x, AM574x, CCS project
spiLoopback example

Example application to validate features and interfaces for SPI driver in loopback mode. Configures the SPI in loopback mode, transmits a test pattern and receives it back from SPI.

Note: This example is intended to demonstrate the SPI LLD API usage on the HW platforms where SPI memory is not available. Currently this example is supported on OMAPL138/C6748 platforms.

Following prints on console expected: Pass criteria: All tests have passed. k2g, k2l, k2e, omapl138, AM335x, AM437x, AM571x, AM572x, AM574x, CCS project

4.15.4.2. QSPI

Name Description Expected Results SoC Supported Build Type

QSPI_FlashReadWrite

Example application

Sample application demonstrating read and write of data to a flash device connected over QSPI interface. Write transaction is verified  for correctness by reading contents back.

Following prints on console expected: Pass criteria:

All tests have passed.

AM437x, AM571x, AM572x, AM574x, k2g, CCS project
QSPI_TestApplication Driver unit test application to validate features and interfaces for QSPI driver Following prints on console expected: Pass criteria: All tests have passed. AM437x, AM571x, AM572x, AM574x, k2g, CCS project

4.15.4.3. OSPI

Name Description Expected Results SoC Supported Build Type
OSPI_TestApplication Driver unit test application to validate features and interfaces for OSPI driver Following prints on console expected: Pass criteria: All tests have passed. am65xx j721e j7200 am64x makefile
OSPI_SMP_Test Application Driver unit test application to validate features and interfaces for OSPI driver in SMP mode. (A53 core) Following prints on console expected: Pass criteria: All tests have passed. am65xx makefile

4.15.4.4. MCSPI

Name Description Additional EVM Configuration Expected Results SoC Supported Build Type
MCSPI_Serialize r Example application Sample Application demonstrating reading data generated from industrial input module. Application uses GPIO pins to assert load signal in order to generate date from industrial input module.

AM57x IDK EVM:

Short pins 1 and 2 on header J37(Industrial I/O)

AM335x ICE v2: Short pins 1 and 2 on header J14(Industrial I/O)

AM437x IDK EVM: Short pins 1 and 2 on header J1(Industrial I/O)


Following prints  on console expected:

Pass criteria:

All tests have passed.

AM335x, AM437x, AM571x, AM572x, AM574x, CCS project
MCSPI_Dma_Seria lizer Example application Sample Application demonstrating reading data generated from industrial input module through EDMA. Application uses GPIO pins to assert load signal in order to generate date from industrial input module.

AM57x IDK EVM: Short pins 1 and 2 on header J37(Industrial I/O)

AM437x IDK EVM: Short pins 1 and 2 on header J1(Industrial I/O)


Following prints  on console expected:

Pass criteria:

All tests have passed.

AM437x, AM571x, AM572x, AM574x, CCS project
MCSPI_SerialFla sh Sample Application demonstrating writing and reading data from the serial flash through MCSPI EDMA interface. AM335x GP EVM: Set the EVM in profile 2 (SW8[1] = OFF, SW8[2] = ON, SW8[3:4] = OFF)

Following prints  on console expected:

Pass criteria:

All tests have passed.

AM335x CCS project
MCSPI_slavemode example application

Application demonstrates slave recieve and transmit features of McSPI. Application use case requires two EVMs. One acts as Master and Another as slave. McSPI connections information and addtional details are as follows.

No of Boards Required: 2

Connection requirements:

Consider EVM1 as Master and EVM2 as slave.

Master SPI_CLK - Slave SPI_CLK Master SPI_D0 - Slave SPI_D1 Master SPI_D1 - Slave SPI_D0 Master SPI_CS0 - Slave SPI_CS0 DGND - DGND

Additional Requirements:

Run “MCSPI_SlaveMod e_SlaveExample <BoardType><arm /c66x/m4>Exampl eProject” first on Slave EVM and then “MCSPI_SlaveMode _MasterExample <BoardType>_<ar m/c66x/m4>Examp leProject” on Master EVM.


Note:

A DGND connection may be required from expansion connector on each board to make sure the data transfer is proper.

For AM6 or J7, only one EVM is required. Slave is run on MPU1_0 core and Master is run on MCU1_0 core

Pin Connections:

IDK AM571x,
IDK AM572x or IDK AM574x:
EVM1(master) ==== EVM2(slave)
J21-Pin24(CLK)—J21-Pin24(CLK)
J21-Pin26(MISO)—J21-Pin28(MISO)
J21-Pin28(MOSI)—J21-Pin26(MOSI)
J21-Pin30(CS)——J21-Pin30(CS)
J21-Pin22(DGND)–J21-Pin22(DGND)

IDK AM437x:
EVM1(master) ==== EVM2(slave)
J16-Pin24(CLK)—–J16-Pin24(CLK)
J16-Pin26(MISO)—J16-Pin28(MISO)
J16-Pin28(MOSI)—J16-Pin26(MOSI)
J16-Pin30(CS)——J16-Pin30(CS)
J16-Pin22(DGND)–J16-Pin22(DGND)

ICEv2AM335x:
EVM1(master) ========= EVM2(slave)
J3-Pin12(CLK)———J3-Pin12(CLK)
J3-Pin14(MIS0)——-J3-Pin16(MISO)
J3-Pin16(MOSI)——-J3-Pin14(MOSI)
J3-Pin18(CS)———–J3-Pin18(CS)
J3-Pin2(DGND)——–J3-Pin2(DGND)

BBB AM335x:
EVM1(master) ===== EVM2(slave)

P9-Pin31(CLK)——-P9-Pin31(CLK)
P9-Pin29(MISO)——P9-Pin30(MISO)
P9-Pin30(MOSI)——P9-Pin29(MOSI)
P9-Pin28(CS)———P9-Pin28(CS)
P9-Pin1(DGND)——-P9-Pin1(DGND)
K2G EVM:
EVM1(master) ======= EVM2(slave)
J12-Pin9(MISO)——-J12-Pin9(MISO)
J12-Pin11(MOSI)—-J12-Pin11(MOSI)
J12-Pin13(CLK)——J12-Pin13(CLK)
J12-Pin15(CS0)——J12-Pin15(CS0)
J12-Pin49(DGND)–J12-Pin49(DGND)

icev2AMIC110 EVM:
EVM1(master) ======= EVM2(slave)
J5-Pin12(MISO)——-J5-Pin14(MISO)
J5-Pin14(MOSI)——J5-Pin12(MOSI)
J4-Pin13(CLK)——J4-Pin13(CLK)
J5-Pin4(CS)———J5-Pin4(CS)
J5-Pin2(DGND)——-J5-Pin2(DGND)
am65xx EVM/IDK:
MCU1_0 (master) ====== MPU1_0(slave)
J721e EVM:
MCU1_0 (master) ====== MPU1_0(slave)
J7200 EVM:
MCU1_0 (master) ====== MPU1_0(slave)
On slave EVM console: SPI initialized
Slave: PASS: Txd from master SPI

On Master EVM console: initialized
Master: PASS: Txd from slave SPI
Done
AM335x, AM437x, AM571x, AM572x, AM574x, k2g, CCS project
am65xx j721e j7200 makefile
MCSPI_SMP_Basic Example application Sample Application demonstrating reading data generated from industrial input module. Application uses GPIO pins to assert load signal in order to generate date from industrial input module in SMP mode. (A15 core)  

 

Following prints  on console expected:

Pass criteria:

All tests have passed.

AM572x-EVM CCS project

4.15.5. OSPI Driver Configuration to support QSPI flash

If the board has a QSPI flash, the PDK driver needs to be updated to support the QSPI flash:

  • Board QSPI Flash Instance Configuration in board_cfg.h
#define BOARD_QSPI_NOR_INSTANCE  <OSPI instance connected to QSPI flash>
  • SPI SoC Driver Configurations:
...
OSPI_v0_HwAttrs ospi_cfg;

SPI_init();

OSPI_socGetInitCfg(BOARD_QSPI_NOR_INSTANCE, &ospi_cfg);
ospi_cfg.xferLines      = OSPI_XFER_LINES_QUAD;
ospi_cfg.pageSize       = <QSPI flash page size>;
ospi_cfg.devDelays[0]   = <QSPI device delay>;
ospi_cfg.devDelays[1]   = <QSPI device delay>;
ospi_cfg.devDelays[2]   = <QSPI device delay>;
ospi_cfg.devDelays[3]   = <QSPI device delay>;
ospi_cfg.rdDataCapDelay = <QSPI read capture delay>;
OSPI_socSetInitCfg(BOARD_OSPI_NOR_INSTANCE, &ospi_cfg);

4.15.6. Support for Benchmark Testing

Name Description Expected Results SOC/Core Suppported Build Type
OSPI flash Test App Test application used for performance benchmarking

Test application will print on the UART console:

Board_flashWrite ### bytes at transfer rate #### Kbps

Board_flashRead ### bytes at transfer rate #### Mbps

Board_flashWrite CPU Load %##

Board_flashRead CPU Load %##

am65xx/A53 am65xx/R5 j721e/mpu1_0 j721e/mcu1_0 j7200/mpu1_0 j7200/mcu1_0 am64x/mpu1_0 am64x/mcu1_0 make

Note

  1. Data transfer between DDR and OSPI flash memory, performance measurement does not include time to invalidate/write back cache
  2. GTC counter (200MHz) used for throughput measurement on A53, and PMU cycle counter (400MHz) on R5
  3. sysbios load moduel used for load measurement
  4. Pipeline PHY enabled, DDR mode enabled in DAC mode
  5. Pipeline PHY disabled, DDR mode disabled in INDAC mode with ospi clock divider of 32
  6. Read/write transfer size of 1M bytes
  7. Write transfer size 1M bytes with DMA chunk size of 16 bytes in DAC DMA mode