Polling

This sample application note describes using SPI3W polling mode to read sensor ID.

Communicates with the sensor via SPI3W and reads the specified information by reading the data under the specified address.

Users can change the SPI3W pin configuration and other settings in the example through different macro configurations. For detailed macro configurations, see Configurations.

Requirements

For requirements, please refer to the Requirements.

Wiring

Connect the EVB to PWM3610DM-SUDU sensor, connect P2_2 and CLK, P2_3 and SDIO, P2_4 and CS#, and also connect GND and VDD.

Hardware Introduction

The PWM3610DM-SUDU is a laser sensor module. The PMW3610DM-SUDU registers are accessible through the serial port. The registers are used to read motion data and status, as well as to set the device configuration. In this sample, it is used to demonstrate communication with SPI3W.

Configurations

  1. The following macro can be configured to modify the pin definitions.

    #define SPI_3WIRE_CLK_PIN       P2_2
    #define SPI_3WIRE_DATA_PIN      P2_3
    #define SPI_3WIRE_CS_PIN        P2_4
    

Building and Downloading

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

Experimental Verification

  1. After the EVB starts, SPI3W begins communication with the mouse sensor. Once the communication ends, it prints the obtained ID information. If the ID is 0x3e and 0x01 (only for PWM3610DM-SUDU sensor), it means the test is successful.

    id[0] = 0x3e, id[1] = 0x01
    SPI3W test pass!
    

Code Overview

This section introduces the code and process description for initialization and corresponding function implementation in the sample.

Source Code Directory

The directory for project file and source code are as follows:

  • Project directory: sdk\samples\peripheral\spi3wire\polling\proj

  • Source code directory: sdk\samples\peripheral\spi3wire\polling\src

Initialization

The initialization flow for peripherals can refer to Initialization Flow in General Introduction.

  1. Call Pad_Config() and Pinmux_Config() to configure the PAD and PINMUX of the corresponding pins.

    void board_spi3wire_init(void)
    {
       Pad_Config(SPI_3WIRE_CLK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH);
       Pad_Config(SPI_3WIRE_DATA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH);
       Pad_Config(SPI_3WIRE_CS_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH);
    
       Pinmux_Config(SPI_3WIRE_CLK_PIN, SPI2W_CLK);
       Pinmux_Config(SPI_3WIRE_DATA_PIN, SPI2W_DATA);
       Pinmux_Config(SPI_3WIRE_CS_PIN, SPI2W_CS);
    }
    
  2. Call RCC_PeriphClockCmd() to enable the SPI3W clock.

  3. Initialize the SPI3W peripheral:

    1. Define the SPI3W_InitTypeDef type SPI3W_InitStruct, and call SPI3W_StructInit() to pre-fill SPI3W_InitStruct with default values.

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

    3. Call SPI3W_Init() to initialize the SPI3W peripheral.

SPI3W Initialization Parameters

SPI3W Hardware Parameters

Setting in the SPI3W_InitStruct

SPI3W

SPI3W Source Clock

SPI3W_InitTypeDef::SPI3W_SysClock

20000000

SPI3W Clock

SPI3W_InitTypeDef::SPI3W_Speed

800000

SPI3W Mode (3-Wire or 2-Wire)

SPI3W_InitTypeDef::SPI3W_Mode

SPI3W_3WIRE_MODE

Read Delay Cycle

SPI3W_InitTypeDef::SPI3W_ReadDelay

0x3

Functional Implementation

The process of reading data in polling mode for SPI3W is shown in the diagram:

Here should be SPI polling read flow

SPI3W polling read mode flow

  1. Execute the signal synchronization process before reading data. Set the resync time, send the resync signal, and disable the resync signal after it has finished outputting. Then call the SPI3W_Cmd() function to enable the three-wire SPI function.

    SPI3W_SetResyncTime(2);
    SPI3W_ResyncSignalCmd(ENABLE);
    while (SPI3W_GetFlagStatus(SPI3W_FLAG_RESYNC_BUSY) == SET);
    SPI3W_ResyncSignalCmd(DISABLE);
    SPI3W_Cmd(ENABLE);
    
  2. Call the spi3wire_readbyte function, passing in the address parameter to read the mouse ID information.

    1. Wait for the busy status flag to clear.

    2. Call SPI3W_ClearRxDataLen() to clear the received data length of SPI3W.

    3. Call SPI3W_StartRead(), passing in the address information and the length of data to be read, to start reading the data at that address. Wait for the busy status flag to clear.

    4. Continuously check if data has been received. If data is received, call SPI3W_ReadBuf() to read the data from the SPI3W receive FIFO.

    5. Return the read data and print it.

    uint8_t spi3wire_readbyte(uint8_t address)
    {
        uint8_t reg_value = 0;
        uint32_t timeout = 0;
    
        /* Check spi busy or not */
        while (SPI3W_GetFlagStatus(SPI3W_FLAG_BUSY) == SET)
        {
            timeout++;
            if (timeout > 0x1ffff)
            {
                break;
            }
        }
    
        /* Clear Receive data length */
        SPI3W_ClearRxDataLen();
    
        SPI3W_StartRead(address, 1);
    
        timeout = 0;
        while (SPI3W_GetFlagStatus(SPI3W_FLAG_BUSY) == SET)
        {
            timeout++;
            if (timeout > 0x1ffff)
            {
                break;
            }
        }
    
        /* Get the length of received data */
        while (SPI3W_GetRxDataLen() == 0);
        /* Read data */
        SPI3W_ReadBuf(&reg_value, 1);
    
        return reg_value;
    }