SPI 2SPI DMA Write Read

This document introduces two SPI communication samples. The sample1 demonstrates how SPI0 reads data and SPI1 sends data by GDMA. The sample2 demonstrates how SPI0 reads data and SPI1 sends data by auto-reload GDMA. In both examples, SPI is configured as a master, and operates in GDMA mode. The direction of SPI0 is EEPROM read, the direction of SPI1 is TX only. The chip reads data from the SPI slave device0 and writes data to the SPI slave device1.

Requirements

For hardware requirements, please refer to the Requirements.

Wiring

Connect P1_7 to CS of SPI slave device 0, connect P1_4 to SCK of SPI slave device 0, connect P1_5 to MISO of SPI slave device 0, and connect P1_6 to MOSI of SPI slave device 0. Connect P2_5 to CS of SPI slave device 1, connect P2_2 to SCK of SPI slave device 1, connect P2_3 to MISO of SPI slave device 1, and connect P2_4 to MOSI of SPI slave device 1. The hardware connection of SPI sample code is shown in the figure below.

../../../_images/SPI_Demo_6_1_Hardware_Connection_Diagram.png

SPI Sample Code Hardware Connection Diagram

Configurations

  1. The following macros can be configured to modify pin definitions.

    • #define PIN_SPI0_SCK P1_4

    • #define PIN_SPI0_MOSI P1_5

    • #define PIN_SPI0_MISO P1_6

    • #define PIN_SPI0_CS P1_7

    • #define PIN_SPI1_SCK P2_2

    • #define PIN_SPI1_MOSI P2_3

    • #define PIN_SPI1_MISO P2_4

    • #define PIN_SPI1_CS P2_5

  2. The entry function are as follows, call this function in main() to run this sample code. For more details, please refer to the Initialization.

    For sample 1, use the following entry function:

    spi2spi_dma_demo();
    

    For sample 2, use the following entry function:

    spi2spi_auto_reload_dma_demo();
    

Building and Downloading

For building and downloading, please refer to the Building and Downloading.

Experimental Verification

Sample Verification

  1. Press the Reset button on the EVB.

  2. SPI0 reads data from SPI slave device 0 and SPI1 sends the same data to SPI slave device 1.

Code Overview

Source Code Directory

For both samples, please refer to the Source Code Directory for the project directory.

Sample 1 source code:

  • Source code directory: sdk\src\sample\io_demo\spi\spi2spi_dma\spi2spi_dma_demo.c .

Sample 2 source code:

  • Source code directory: sdk\src\sample\io_demo\spi\spi2spi_auto_reload_dma\spi2spi_auto_reload_dma_demo.c .

2SPI Initialization Flow

The initialization flow for peripherals can refer to Initialization Flow.

The SPI initialization flow can refer to SPI Initialization Flow Chart.

  1. Call Pad_Config() and Pinmux_Config() to initialize the SPI0 and SPI1 pins.

    static void board_spi_init(void)
    {
       Pinmux_Config(PIN_SPI0_SCK,  SPI0_CLK_MASTER);
       Pinmux_Config(PIN_SPI0_MOSI, SPI0_MO_MASTER);
       Pinmux_Config(PIN_SPI0_MISO, SPI0_MI_MASTER);
       Pinmux_Config(PIN_SPI0_CS,   SPI0_SS_N_0_MASTER);
    
       Pinmux_Config(PIN_SPI1_SCK,  SPI1_CLK_MASTER);
       Pinmux_Config(PIN_SPI1_MOSI, SPI1_MO_MASTER);
       Pinmux_Config(PIN_SPI1_MISO, SPI1_MI_MASTER);
       Pinmux_Config(PIN_SPI1_CS,   SPI1_SS_N_0_MASTER);
    
       Pad_Config(PIN_SPI0_SCK,  PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
                   PAD_OUT_HIGH);
       Pad_Config(PIN_SPI0_MOSI, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
                   PAD_OUT_HIGH);
       Pad_Config(PIN_SPI0_MISO, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
                   PAD_OUT_HIGH);
       Pad_Config(PIN_SPI0_CS,   PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
                   PAD_OUT_HIGH);
    
       Pad_Config(PIN_SPI1_SCK,  PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
                   PAD_OUT_HIGH);
       Pad_Config(PIN_SPI1_MOSI, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
                   PAD_OUT_HIGH);
       Pad_Config(PIN_SPI1_MISO, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
                   PAD_OUT_HIGH);
       Pad_Config(PIN_SPI1_CS,   PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
                   PAD_OUT_HIGH);
    }
    
  2. Call RCC_PeriphClockCmd() to enable the SPI0 and SPI1 clock and function.

  3. Define the SPI_InitTypeDef type SPI_InitStructure, and call SPI_StructInit() to pre-fill SPI_InitStructure with default values.

  4. Initialize the SPI0 peripheral:

    1. Modify the SPI_InitStructure parameters as needed. The SPI initialization parameter configuration is shown in the table below.

    2. Call SPI_Init() to initialize the SPI peripheral.

    3. Call SPI_Cmd() to enable SPI0.

    SPI Initialization Parameters

    SPI Hardware Parameters

    Setting in the SPI_InitStructure

    SPI

    Direction

    SPI_InitTypeDef::SPI_Direction

    SPI_Direction_EEPROM

    Device Role (SPI Master or SPI Slave)

    SPI_InitTypeDef::SPI_Mode

    SPI_Mode_Master

    Data Frame Size

    SPI_InitTypeDef::SPI_DataSize

    SPI_DataSize_8b

    Clock Polarity

    SPI_InitTypeDef::SPI_CPOL

    SPI_CPOL_High

    Clock Phase

    SPI_InitTypeDef::SPI_CPHA

    SPI_CPHA_2Edge

    Clock Div

    SPI_InitTypeDef::SPI_BaudRatePrescaler

    100

    Frame Format

    SPI_InitTypeDef::SPI_FrameFormat

    SPI_Frame_Motorola

    RX Number of Data Frames

    SPI_InitTypeDef::SPI_NDF

    255

    RX DMA Enable

    SPI_InitTypeDef::SPI_RxDmaEn

    ENABLE

    RX Water Level

    SPI_InitTypeDef::SPI_RxWaterlevel

    8

  5. Initialize the SPI1 peripheral:

    1. Modify the SPI_InitStructure parameters as needed. The SPI initialization parameter configuration is shown in the table below.

    2. Call SPI_Init() to initialize the SPI peripheral.

    3. Call SPI_Cmd() to enable SPI1.

    SPI Initialization Parameters

    SPI Hardware Parameters

    Setting in the SPI_InitStructure

    SPI

    Direction

    SPI_InitTypeDef::SPI_Direction

    SPI_Direction_TxOnly

    Device Role (SPI Master or SPI Slave)

    SPI_InitTypeDef::SPI_Mode

    SPI_Mode_Master

    Data Frame Size

    SPI_InitTypeDef::SPI_DataSize

    SPI_DataSize_8b

    Clock Polarity

    SPI_InitTypeDef::SPI_CPOL

    SPI_CPOL_High

    Clock Phase

    SPI_InitTypeDef::SPI_CPHA

    SPI_CPHA_2Edge

    Frame Format

    SPI_InitTypeDef::SPI_FrameFormat

    SPI_Frame_Motorola

    RX DMA Enable

    SPI_InitTypeDef::SPI_TxDmaEn

    ENABLE

    RX Water Level

    SPI_InitTypeDef::SPI_TxWaterlevel

    35

2SPI DMA Initialization Flow

The initialization flow for peripherals can refer to Initialization Flow.

  1. Call RCC_PeriphClockCmd() to enable the GDMA clock and function.

  2. Call GDMA_channel_request to request a free GDMA channel and register the GDMA interrupt handler.

  3. Initialize the GDMA peripheral:

    1. Define the GDMA_InitTypeDef type GDMA_InitStruct, and call GDMA_StructInit() to pre-fill GDMA_InitStruct with default values.

    2. Modify the GDMA_InitStruct parameters as needed. The GDMA initialization parameter configuration is shown in the table below.

    3. Call GDMA_Init() to initialize the GDMA peripheral.

    GDMA Initialization Parameters

    GDMA Hardware Parameters

    Setting in the GDMA_InitStruct

    GDMA

    Channel Num

    GDMA_InitTypeDef::GDMA_ChannelNum

    SPI2SPI_DMA_CHANNEL_NUM

    Transfer Direction

    GDMA_InitTypeDef::GDMA_DIR

    GDMA_DIR_PeripheralToPeripheral

    Buffer Size

    GDMA_InitTypeDef::GDMA_BufferSize

    256

    Source Address Increment or Decrement

    GDMA_InitTypeDef::GDMA_SourceInc

    DMA_SourceInc_Fix

    Destination Address Increment or Decrement

    GDMA_InitTypeDef::GDMA_DestinationInc

    DMA_DestinationInc_Fix

    Source Data Size

    GDMA_InitTypeDef::GDMA_SourceDataSize

    GDMA_DataSize_Byte

    Destination Data Size

    GDMA_InitTypeDef::GDMA_DestinationDataSize

    GDMA_DataSize_Byte

    Source Burst Transaction Length

    GDMA_InitTypeDef::GDMA_SourceMsize

    GDMA_Msize_1

    Destination Burst Transaction Length

    GDMA_InitTypeDef::GDMA_DestinationMsize

    GDMA_Msize_1

    Source Address

    GDMA_InitTypeDef::GDMA_SourceAddr

    SPI0->DR

    Destination Address

    GDMA_InitTypeDef::GDMA_DestinationAddr

    SPI1->DR

    Source Handshake

    GDMA_InitTypeDef::GDMA_SourceHandshake

    GDMA_Handshake_SPI0_RX

    Destination Handshake

    GDMA_InitTypeDef::GDMA_DestHandshake

    GDMA_Handshake_SPI1_TX

  4. Call GDMA_INTConfig() to enable GDMA transfer complete interrupt GDMA_INT_Transfer.

  5. Call NVIC_Init() to enable NVIC of GDMA.

2SPI Auto-Reload DMA Initialization Flow

The initialization flow for peripherals can refer to Initialization Flow.

  1. Call RCC_PeriphClockCmd() to enable the GDMA clock and function.

  2. Call GDMA_channel_request to request a free GDMA channel and register the GDMA interrupt handler.

  3. Initialize the GDMA peripheral:

    1. Define the GDMA_InitTypeDef type GDMA_InitStruct, and call GDMA_StructInit() to pre-fill GDMA_InitStruct with default values.

    2. Modify the GDMA_InitStruct parameters as needed. The GDMA initialization parameter configuration is shown in the table below.

    3. Call GDMA_Init() to initialize the GDMA peripheral.

    GDMA Initialization Parameters

    GDMA Hardware Parameters

    Setting in the GDMA_InitStruct

    GDMA

    Channel Num

    GDMA_InitTypeDef::GDMA_ChannelNum

    SPI_AUTO_RELOAD_DMA_CHANNEL_NUM

    Transfer Direction

    GDMA_InitTypeDef::GDMA_DIR

    GDMA_DIR_PeripheralToPeripheral

    Buffer Size

    GDMA_InitTypeDef::GDMA_BufferSize

    256

    Source Address Increment or Decrement

    GDMA_InitTypeDef::GDMA_SourceInc

    DMA_SourceInc_Fix

    Destination Address Increment or Decrement

    GDMA_InitTypeDef::GDMA_DestinationInc

    DMA_DestinationInc_Fix

    Source Data Size

    GDMA_InitTypeDef::GDMA_SourceDataSize

    GDMA_DataSize_Byte

    Destination Data Size

    GDMA_InitTypeDef::GDMA_DestinationDataSize

    GDMA_DataSize_Byte

    Source Burst Transaction Length

    GDMA_InitTypeDef::GDMA_SourceMsize

    GDMA_Msize_1

    Destination Burst Transaction Length

    GDMA_InitTypeDef::GDMA_DestinationMsize

    GDMA_Msize_1

    Source Address

    GDMA_InitTypeDef::GDMA_SourceAddr

    SPI0->DR

    Destination Address

    GDMA_InitTypeDef::GDMA_DestinationAddr

    SPI1->DR

    Source Handshake

    GDMA_InitTypeDef::GDMA_SourceHandshake

    GDMA_Handshake_SPI0_RX

    Destination Handshake

    GDMA_InitTypeDef::GDMA_DestHandshake

    GDMA_Handshake_SPI1_TX

    Multi Block Enable

    GDMA_InitTypeDef::GDMA_Multi_Block_En

    ENABLE

    Multi Block Mode

    GDMA_InitTypeDef::GDMA_Multi_Block_Mode

    AUTO_RELOAD_TRANSFER

Functional Implementation

2SPI DMA Interupt Handle

When GDMA transfer is completed, transfer complete interrupt is triggered.

  1. Call GDMA_ClearAllTypeINT() to clear the all GDMA channel interrupt.

  2. Call GDMA_channel_release() to release the used GDMA channel.