esp8266~SPI使用

前言

最近项目上遇到困难,esp8266的SPI用起来有点晕,这里先记录下来,后面再更新。

一. 官网硬件驱动的代码

esp8266外设
使用demo:

#include "gpio.h"
#include "spi_register.h"
#include "spi_interface.h"

void spi_initialize()
{
    //Initialze Pins on ESP8266
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_HSPIQ_MISO);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_HSPI_CS0);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_HSPID_MOSI);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_HSPI_CLK);

    SpiAttr pAttr;   //Set as Master/Sub mode 0 and speed 10MHz
    pAttr.mode = SpiMode_Master;
    pAttr.subMode = SpiSubMode_0;
    pAttr.speed = SpiSpeed_10MHz;
    pAttr.bitOrder = SpiBitOrder_MSBFirst;
    SPIInit(SpiNum_HSPI, &pAttr);
}

void Send_cmd(uint8 command)
{
    SpiData pDat;
    pDat.cmd = command;	   ///< Command value
    pDat.cmdLen = 1;       ///< Command byte length
    pDat.addr = NULL;      ///< Point to address value
    pDat.addrLen = 0; 	   ///< Address byte length
    pDat.data = NULL; 	   ///< Point to data buffer
    pDat.dataLen = 0; 	   ///< Data byte length.
    SPIMasterSendData(SpiNum_HSPI, &pDat);
}

/******************************************************************************
 * FunctionName : user_init
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
 *******************************************************************************/
void user_init(void)
{
    uint8 cmd = 0xaa;
    uint32 addr = 0xbbcc;
    uint32 data[2] = { 0x11223344, 0x55667788 };
    spi_initialize();
    printf("Starting SPI Communication\n");
    while (1) {
        Send_cmd(0x34);
        SpiData pDat;
        pDat.cmd = cmd;			      ///< Command value
        pDat.cmdLen = 1;		      ///< Command byte length
        pDat.addr = &addr; 		      ///< Point to address value
        pDat.addrLen = 2; 	          ///< Address byte length
        pDat.data = data; 		      ///< Point to data buffer
        pDat.dataLen = sizeof(data);  ///< Data byte length.
        SPIMasterSendData(SpiNum_HSPI, &pDat);
        vTaskDelay(100);
    }
}

hspi驱动代码:

/**
 *  spi_interface.c
 *
 * Defines and Macros for the SPI.
 *
 * Copyright @ 2015 Espressif System Co., Ltd.
 * All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are NOT permitted except as agreed by
 * Espressif System Co., Ltd.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 */
/**
 * @file spi_interface.c
 * @brief Defines and Macros for the SPI.
 */

#include "spi_interface.h"
#include "esp8266/eagle_soc.h"
#include "esp8266/ets_sys.h"
#include "esp_libc.h"
//*****************************************************************************
//
// Make sure all of the definitions in this header have a C binding.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C"
{
#endif

// Show the spi registers.
#define SHOWDEBUG

void __ShowRegValue(const char * func, uint32_t line)
{
#ifndef SHOWDEBUG
    int i;
    uint32_t regAddr = 0x60000140; // SPI--0x60000240, HSPI--0x60000140;
    printf("\r\n FUNC[%s],line[%d]\r\n", func, line);
    printf(" SPI_ADDR      [0x%08x]\r\n", READ_PERI_REG(SPI_ADDR(SpiNum_HSPI)));
    printf(" SPI_CMD       [0x%08x]\r\n", READ_PERI_REG(SPI_CMD(SpiNum_HSPI)));
    printf(" SPI_CTRL      [0x%08x]\r\n", READ_PERI_REG(SPI_CTRL(SpiNum_HSPI)));
    printf(" SPI_CTRL2     [0x%08x]\r\n", READ_PERI_REG(SPI_CTRL2(SpiNum_HSPI)));
    printf(" SPI_CLOCK     [0x%08x]\r\n", READ_PERI_REG(SPI_CLOCK(SpiNum_HSPI)));
    printf(" SPI_RD_STATUS [0x%08x]\r\n", READ_PERI_REG(SPI_RD_STATUS(SpiNum_HSPI)));
    printf(" SPI_WR_STATUS [0x%08x]\r\n", READ_PERI_REG(SPI_WR_STATUS(SpiNum_HSPI)));
    printf(" SPI_USER      [0x%08x]\r\n", READ_PERI_REG(SPI_USER(SpiNum_HSPI)));
    printf(" SPI_USER1     [0x%08x]\r\n", READ_PERI_REG(SPI_USER1(SpiNum_HSPI)));
    printf(" SPI_USER2     [0x%08x]\r\n", READ_PERI_REG(SPI_USER2(SpiNum_HSPI)));
    printf(" SPI_PIN       [0x%08x]\r\n", READ_PERI_REG(SPI_PIN(SpiNum_HSPI)));
    printf(" SPI_SLAVE     [0x%08x]\r\n", READ_PERI_REG(SPI_SLAVE(SpiNum_HSPI)));
    printf(" SPI_SLAVE1    [0x%08x]\r\n", READ_PERI_REG(SPI_SLAVE1(SpiNum_HSPI)));
    printf(" SPI_SLAVE2    [0x%08x]\r\n", READ_PERI_REG(SPI_SLAVE2(SpiNum_HSPI)));

    for (i = 0; i < 16; ++i) {
        printf(" ADDR[0x%08x],Value[0x%08x]\r\n", regAddr, READ_PERI_REG(regAddr));
        regAddr += 4;
    }
#endif
}

// Define SPI interrupt enable macro
#define ETS_SPI_INTR_ENABLE()  _xt_isr_unmask(1 << ETS_SPI_INUM)

/**
 * @brief Based on pAttr initialize SPI module.
 *
 */
void ICACHE_FLASH_ATTR SPIInit(SpiNum spiNum, SpiAttr* pAttr)
{
    if ((spiNum > SpiNum_HSPI)
        || (NULL == pAttr)) {
        return;
    }
    // SPI_CPOL & SPI_CPHA
    switch (pAttr->subMode) {
    case SpiSubMode_1:
        CLEAR_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE);
        SET_PERI_REG_MASK(SPI_USER(spiNum),  SPI_CK_OUT_EDGE); // CHPA_FALLING_EDGE_SAMPLE
        break;
    case SpiSubMode_2:
        SET_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE);
        SET_PERI_REG_MASK(SPI_USER(spiNum),  SPI_CK_OUT_EDGE); // CHPA_FALLING_EDGE_SAMPLE
        break;
    case SpiSubMode_3:
        SET_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE);
        CLEAR_PERI_REG_MASK(SPI_USER(spiNum),  SPI_CK_OUT_EDGE);
        break;
    case SpiSubMode_0:
    default:
        CLEAR_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE);
        CLEAR_PERI_REG_MASK(SPI_USER(spiNum),  SPI_CK_OUT_EDGE);
        // To do nothing
        break;
    }

    // SPI bit order
    if (SpiBitOrder_MSBFirst == pAttr->bitOrder) {
        CLEAR_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_WR_BIT_ORDER);
        CLEAR_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_RD_BIT_ORDER);
    } else if (SpiBitOrder_LSBFirst == pAttr->bitOrder) {
        SET_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_WR_BIT_ORDER);
        SET_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_RD_BIT_ORDER);
    } else {
        // To do nothing
    }

    // Disable flash operation mode
    // As earlier as better, if not SPI_CTRL2 can not to be set delay cycles.
    CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_FLASH_MODE);

    // SPI mode type
    if (SpiMode_Master == pAttr->mode) {
        // SPI mode type
        CLEAR_PERI_REG_MASK(SPI_SLAVE(spiNum), SPI_SLAVE_MODE);
        // SPI Send buffer
        CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO_HIGHPART );// By default slave send buffer C0-C7
        // SPI Speed
        if (1 < (pAttr->speed)) {
            CLEAR_PERI_REG_MASK(SPI_CLOCK(spiNum), SPI_CLK_EQU_SYSCLK);
            WRITE_PERI_REG(SPI_CLOCK(spiNum),
                           ((pAttr->speed & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) |
                           ((((pAttr->speed + 1) / 2 - 1) & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) |
                           ((pAttr->speed & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
        } else {
            WRITE_PERI_REG(SPI_CLOCK(spiNum), SPI_CLK_EQU_SYSCLK); // 80Mhz speed
        }
        // By default format:CMD+ADDR+DATA
        SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_CS_SETUP | SPI_CS_HOLD | SPI_USR_MOSI );

        //delay num
        SET_PERI_REG_MASK(SPI_CTRL2(spiNum), ((0x1 & SPI_MISO_DELAY_NUM) << SPI_MISO_DELAY_NUM_S));
    } else if (SpiMode_Slave == pAttr->mode) {
        // BIT19 must do
        SET_PERI_REG_MASK(SPI_PIN(spiNum), BIT19);

        // SPI mode type
        SET_PERI_REG_MASK(SPI_SLAVE(spiNum), SPI_SLAVE_MODE);
        // SPI Send buffer
        SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO_HIGHPART);// By default slave send buffer C8-C15

        SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI);

        // If do not set delay cycles, slave not working,master cann't get the data.
        SET_PERI_REG_MASK(SPI_CTRL2(spiNum), ((0x1 & SPI_MOSI_DELAY_NUM) << SPI_MOSI_DELAY_NUM_S)); //delay num
        // SPI Speed
        WRITE_PERI_REG(SPI_CLOCK(spiNum), 0);

        // By default format::CMD(8bits)+ADDR(8bits)+DATA(32bytes).
        SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN,
                          7, SPI_USR_COMMAND_BITLEN_S);
        SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_WR_ADDR_BITLEN,
                          7, SPI_SLV_WR_ADDR_BITLEN_S);
        SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_RD_ADDR_BITLEN,
                          7, SPI_SLV_RD_ADDR_BITLEN_S);
        SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_BUF_BITLEN,
                          (32 * 8 - 1), SPI_SLV_BUF_BITLEN_S);
        // For 8266 work on slave mode.
        SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_STATUS_BITLEN,
                          7, SPI_SLV_STATUS_BITLEN_S);
    } else {
        // To do nothing
    }

    //clear Daul or Quad lines transmission mode
    CLEAR_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_QIO_MODE | SPI_DIO_MODE | SPI_DOUT_MODE | SPI_QOUT_MODE);
}

/**
 * @brief Set address value by master mode.
 *
 */
void ICACHE_FLASH_ATTR SPIMasterCfgAddr(SpiNum spiNum, uint32_t addr)
{
    if (spiNum > SpiNum_HSPI) {
        return;
    }
    // Set address
    WRITE_PERI_REG(SPI_ADDR(spiNum), addr);
}

/**
 * @brief Set command value by master mode.
 *
 */
void ICACHE_FLASH_ATTR SPIMasterCfgCmd(SpiNum spiNum, uint32_t cmd)
{
    if (spiNum > SpiNum_HSPI) {
        return;
    }
    // SPI_USER2 bit28-31 is cmd length,cmd bit length is value(0-15)+1,
    // bit15-0 is cmd value.
    SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_VALUE, cmd, SPI_USR_COMMAND_VALUE_S);
}

/**
 * @brief Send data to slave.
 *
 */
int ICACHE_FLASH_ATTR SPIMasterSendData(SpiNum spiNum, SpiData* pInData)
{
    char idx = 0;
    if ((spiNum > SpiNum_HSPI)
        || (NULL == pInData)
        || (64 < pInData->dataLen)) {
        return -1;
    }
    uint32_t *value = pInData->data;
    while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR);
    // Set command by user.
    if (pInData->cmdLen != 0) {
        // Max command length 16 bits.
        SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN,
                          ((pInData->cmdLen << 3) - 1), SPI_USR_COMMAND_BITLEN_S);
        // Enable command
        SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND);
        // Load command
        SPIMasterCfgCmd(spiNum, pInData->cmd);
    } else {
        CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND);
        SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN,
                          0, SPI_USR_COMMAND_BITLEN_S);
    }
    // Set Address by user.
    if (pInData->addrLen == 0) {
        CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR);
        SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN,
                          0, SPI_USR_ADDR_BITLEN_S);
    } else {
        if (NULL == pInData->addr) {
            return -1;
        }
        SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN,
                          ((pInData->addrLen << 3) - 1), SPI_USR_ADDR_BITLEN_S);
        // Enable address
        SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR);
        // Load address
        SPIMasterCfgAddr(spiNum, *pInData->addr);
    }
    // Set data by user.
    if (pInData->dataLen != 0) {
        if (NULL == value) {
            return -1;
        }
        // Enable MOSI
        SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI);
        CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO);
        // Load send buffer
        do {
            WRITE_PERI_REG((SPI_W0(spiNum) + (idx << 2)), *value++);
        } while (++idx < (pInData->dataLen / 4));
        // Set data send buffer length.Max data length 64 bytes.
        SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MOSI_BITLEN, ((pInData->dataLen << 3) - 1), SPI_USR_MOSI_BITLEN_S);
    } else {
        CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI);
        SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MOSI_BITLEN,
                          0, SPI_USR_MOSI_BITLEN_S);
    }
    // Start send data
    SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR);

    SHOWREG();
    return 0;
}

/**
 * @brief Receive data from slave.
 *
 */
int ICACHE_FLASH_ATTR SPIMasterRecvData(SpiNum spiNum, SpiData* pOutData)
{
    char idx = 0;
    if ((spiNum > SpiNum_HSPI)
        || (NULL == pOutData)) {
        return -1;
    }

    uint32_t *value = pOutData->data;
    while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR);
    // Set command by user.
    if (pOutData->cmdLen != 0) {
        // Max command length 16 bits.
        SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN,
                          ((pOutData->cmdLen << 3) - 1), SPI_USR_COMMAND_BITLEN_S);
        // Enable command
        SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND);
        // Load command
        SPIMasterCfgCmd(spiNum, pOutData->cmd);
    } else {
        CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND);
        SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN,
                          0, SPI_USR_COMMAND_BITLEN_S);
    }
    // Set Address by user.
    if (pOutData->addrLen == 0) {
        CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR);
        SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN,
                          0, SPI_USR_ADDR_BITLEN_S);
    } else {
        if (NULL == pOutData->addr) {
            return -1;
        }
        SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN,
                          ((pOutData->addrLen << 3) - 1), SPI_USR_ADDR_BITLEN_S);
        // Enable address
        SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR);
        // Load address
        SPIMasterCfgAddr(spiNum, *pOutData->addr);
    }
    // Set data by user.
    if (pOutData->dataLen != 0) {
        if (NULL == value) {
            return -1;
        }
        // Clear MOSI enable
        CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI);
        // Enable MOSI
        SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO);
        // Set data send buffer length.Max data length 64 bytes.
        SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MISO_BITLEN, ((pOutData->dataLen << 3) - 1), SPI_USR_MISO_BITLEN_S);
    } else {
        CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI);
        CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO);
        SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MISO_BITLEN,
                          0, SPI_USR_MISO_BITLEN_S);
    }
    // Start send data
    SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR);

    while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR);
    // Read data out
    do {
        *pOutData->data++ = READ_PERI_REG(SPI_W0(spiNum) + (idx << 2));
    } while (++idx < (pOutData->dataLen / 4));

    SHOWREG();
    return 0;
}

/**
 * @brief Load data to send buffer by slave mode.
 *
 */
int ICACHE_FLASH_ATTR SPISlaveSendData(SpiNum spiNum, uint32_t *pInData, uint8_t outLen)
{
    if (NULL == pInData) {
        return -1;
    }
    char i;
    for (i = 0; i < outLen; ++i) {
        WRITE_PERI_REG((SPI_W8(spiNum) + (i << 2)), *pInData++);
    }
    return 0;
}

/**
 * @brief Configurate slave prepare for receive data.
 *
 */
int ICACHE_FLASH_ATTR SPISlaveRecvData(SpiNum spiNum, void(*isrFunc)(void*))
{
    if ((spiNum > SpiNum_HSPI)) {
        return -1;
    }

    SPIIntEnable(SpiNum_HSPI, SpiIntSrc_WrStaDoneEn
                 | SpiIntSrc_RdStaDoneEn | SpiIntSrc_WrBufDoneEn | SpiIntSrc_RdBufDoneEn);
    SPIIntDisable(SpiNum_HSPI, SpiIntSrc_TransDoneEn);

    // Maybe enable slave transmission liston
    SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR);
    //
     _xt_isr_attach(ETS_SPI_INUM, isrFunc, NULL);
   // ETS_SPI_INTR_ATTACH(isrFunc, NULL);
    // Enable isr
    ETS_SPI_INTR_ENABLE();


    SHOWREG();

    return 0;
}

/**
 * @brief Send data to slave(ESP8266 register of RD_STATUS or WR_STATUS).
 *
 */
void ICACHE_FLASH_ATTR SPIMasterSendStatus(SpiNum spiNum, uint8_t data)
{
    if (spiNum > SpiNum_HSPI) {
        return;
    }
    while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR);
    // Enable MOSI
    SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI);
    CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO | SPI_USR_DUMMY | SPI_USR_ADDR);

    // 8bits cmd, 0x04 is eps8266 slave write cmd value
    WRITE_PERI_REG(SPI_USER2(spiNum),
                   ((7 & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S)
                   | MASTER_WRITE_STATUS_TO_SLAVE_CMD);
    // Set data send buffer length.
    SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MOSI_BITLEN,
                      ((sizeof(data) << 3) - 1), SPI_USR_MOSI_BITLEN_S);

    WRITE_PERI_REG(SPI_W0(spiNum), (uint32)(data));
    // Start SPI
    SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR);

    SHOWREG();
}

/**
 * @brief Receive status register from slave(ESP8266).
 *
 */
int ICACHE_FLASH_ATTR SPIMasterRecvStatus(SpiNum spiNum)
{
    if (spiNum > SpiNum_HSPI) {
        return -1;
    }

    while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR);
    // Enable MISO
    SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO);
    CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI | SPI_USR_DUMMY | SPI_USR_ADDR);

    // 8bits cmd, 0x06 is eps8266 slave read status cmd value
    WRITE_PERI_REG(SPI_USER2(spiNum),
                   ((7 & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S)
                   | MASTER_READ_STATUS_FROM_SLAVE_CMD);
    // Set revcive buffer length.
    SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MISO_BITLEN,
                      7, SPI_USR_MISO_BITLEN_S);

    // start spi module.
    SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR);

    while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR);

    uint8_t data = (uint8)(READ_PERI_REG(SPI_W0(spiNum)) & 0xff);
    SHOWREG();

    return (uint8)(READ_PERI_REG(SPI_W0(spiNum)) & 0xff);
}

/**
 * @brief Select SPI CS pin.
 *
 */
void ICACHE_FLASH_ATTR SPICsPinSelect(SpiNum spiNum, SpiPinCS pinCs)
{
    if (spiNum > SpiNum_HSPI) {
        return;
    }
    // clear select
    SET_PERI_REG_BITS(SPI_PIN(spiNum), 3, 0, 0);
    SET_PERI_REG_MASK(SPI_PIN(spiNum), pinCs);
}

/**
 * @brief Enable SPI interrupt source.
 *
 */
void ICACHE_FLASH_ATTR SPIIntEnable(SpiNum spiNum, SpiIntSrc intSrc)
{
    if (spiNum > SpiNum_HSPI) {
        return;
    }
    SET_PERI_REG_MASK(SPI_SLAVE(spiNum), intSrc);
}

/**
 * @brief Disable SPI interrupt source.
 *
 */
void ICACHE_FLASH_ATTR SPIIntDisable(SpiNum spiNum, SpiIntSrc intSrc)
{
    if (spiNum > SpiNum_HSPI) {
        return;
    }
    CLEAR_PERI_REG_MASK(SPI_SLAVE(spiNum), intSrc);
}

/**
 * @brief Clear all of SPI interrupt source.
 *
 */
void ICACHE_FLASH_ATTR SPIIntClear(SpiNum spiNum)
{
    if (spiNum > SpiNum_HSPI) {
        return;
    }
    CLEAR_PERI_REG_MASK(SPI_SLAVE(spiNum), SpiIntSrc_TransDoneEn
                        | SpiIntSrc_WrStaDoneEn
                        | SpiIntSrc_RdStaDoneEn
                        | SpiIntSrc_WrBufDoneEn
                        | SpiIntSrc_RdBufDoneEn);
}


#ifdef __cplusplus
}
#endif

来自esp github
参考:

  1. stm32通过spi连接esp8266的hspi 开发
  2. WiFi-ESP8266入门开发(十三)-使用SPI
  3. esp8266 spi slave 驱动调试

猜你喜欢

转载自blog.csdn.net/Bluechalk/article/details/84428678