This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC3220SF-LAUNCHXL:通过 SPI 传输到外部 SFLASH 无法接收数据

Guru**** 2539500 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1062527/cc3220sf-launchxl-not-receiving-data-with-spi-transfer-to-external-sflash

器件型号:CC3220SF-LAUNCHXL

大家好!

当挤占通过 Launchpad 中提供的 SPI 通道将数据传输到外部 SFLASH (与安装在 Launchpad 中的通道相同)时、我目前面临着一些问题。 我已经创建了我自己的例程、以使用 SFLASH 制造商提供的规范与 SPI.h 库相结合、在 SFLASH 中写入、擦除和读取数据。 此外、我使用的是 TIRTOS。

以下代码包括我的代码的初始版本、因此未进行完美优化。 但是、我能够使用示波器看到信号是正确的。 总之、我要尝试使用 SPI_TRANSFH 将命令发送到 SFLASH 进行读取(0x03)、后跟24位地址、然后从 SFLASH 读取大量字节。

void SFLASHRead(uint32_t address, SPI_Params *spiParams, uint16_t readDataSize){

    uint8_t R_MSGSIZE = 4, transmitBuffer[R_MSGSIZE];
    uint8_t receiveBuffer[readDataSize*2]; //Multiplico por 2 para tener bytes
    SPI_Handle spiMaster;
    SPI_Transaction spiTransaction;
    bool transferOK = 0;
    uint16_t i;
    uint8_t *pAddress;

    spiMaster = SPI_open(CONFIG_SPI_Master, spiParams);
    if (spiMaster == NULL) {
        UART_PRINT("[SFLASH-SPI task] (SFLASHSectorErase) Failed to initialize SPI\n\r");
    }

    transmitBuffer[0] = SFLASH_READ;
    pAddress = &address;
    transmitBuffer[1] = *(pAddress + 2);
    transmitBuffer[2] = *(pAddress + 1);
    transmitBuffer[3] = *(pAddress);

    spiTransaction.count = R_MSGSIZE + readDataSize;
    spiTransaction.txBuf = (void *)transmitBuffer;
    spiTransaction.rxBuf = (void *)receiveBuffer;
    spiTransaction.arg = NULL;

    transferOK = SPI_transfer(spiMaster, &spiTransaction);
    if (transferOK){
        UART_PRINT("[SFLASH task] (SFLASHRead) Transfer Read OK\n\r");
    }
    else{
        UART_PRINT("[SFLASH task] (SFLASHRead) Transfer Read Error\n\r");
    }

    SPI_close(spiMaster);

    //Guardado en variable global del contenido leido de SFLASH
    for (i=0; i<readDataSize; i++){
        gSFLASHReadBuff[i] = (receiveBuffer[i*2] << 8) + receiveBuffer[i*2 + 1];
    }
    UART_PRINT("[SFLASH task] (SFLASHRead) Se ha leido %s de la SFLASH\n\r", gSFLASHReadBuff[0]);
}

我在示波器上看到的内容如下(黄色的片选信号、蓝色的 SCLK、紫色的 MOSI 和绿色的 MISO):

检查信号时、代码在硬件方面运行良好、但我无法存储接收到的数据、这只是一个不断增加的变量、我将写入 SFLASH。  

当我使用 CCS 进行调试时、我看到我在函数上使用的缓冲区(spiTransaction.rxBuf =(void *) receiveBuffer;)按应有的方式传递到 SPI_transfer (使用 SPI_Transaction 结构)、然后传递到 SPICC32XXDMA.c 文件中的函数 SPICC32XXDMA_transfer (请参阅下面的函数)。 此函数再次将该结构体传递到 同一文件(下面包含的代码)中的 spPollingTransfer 函  数、该文件执行函数 MAP_SPIDataPut 和 MAP_SPIDataGet。 我看到稍后的函数是将传入数据保存到 dummyBuffer、然后保存到 rxBuf 的函数。 但是、我看不到缓冲区填满。 我看到的是、这个 dummyBuffer 被本地声明、其地址被分配为0x00000000、我不确定它是否正常、而且、rxBuf 确实通过  rxBuf =(void *)((((uint32_t) rxBuf)+ Increment)正确递增;

static inline void spiPollingTransfer(SPICC32XXDMA_Object *object,
    SPICC32XXDMA_HWAttrsV1 const *hwAttrs, SPI_Transaction *transaction)
{
    uint8_t   increment;
    uint32_t  dummyBuffer;
    size_t    transferCount;
    void     *rxBuf;
    void     *txBuf;

    if (transaction->rxBuf) {
        rxBuf = transaction->rxBuf;
    }
    else {
        rxBuf = hwAttrs->scratchBufPtr;
    }

    if (transaction->txBuf) {
        txBuf = transaction->txBuf;
    }
    else {
        *hwAttrs->scratchBufPtr = hwAttrs->defaultTxBufValue;
        txBuf = hwAttrs->scratchBufPtr;
    }

    if (object->dataSize < 9) {
        increment = sizeof(uint8_t);
    }
    else if (object->dataSize < 17) {
        increment = sizeof(uint16_t);
    }
    else {
        increment = sizeof(uint32_t);
    }

    transferCount = transaction->count;

    /*
     * Start the polling transfer - we MUST set word count to 0; not doing so
     * will raise spurious RX interrupts flags (though interrupts are not
     * enabled).
     */
    MAP_SPIWordCountSet(hwAttrs->baseAddr, 0);
    MAP_SPIEnable(hwAttrs->baseAddr);
    MAP_SPICSEnable(hwAttrs->baseAddr);

    while (transferCount--) {
        if (object->dataSize < 9) {
            MAP_SPIDataPut(hwAttrs->baseAddr, *((uint8_t *) txBuf));
            MAP_SPIDataGet(hwAttrs->baseAddr, (unsigned long *)&dummyBuffer);
            *((uint8_t *) rxBuf) = (uint8_t) dummyBuffer;
        }
        else if (object->dataSize < 17) {
            MAP_SPIDataPut(hwAttrs->baseAddr, *((uint16_t *) txBuf));
            MAP_SPIDataGet(hwAttrs->baseAddr, (unsigned long *) &dummyBuffer);
            *((uint16_t *) rxBuf) = (uint16_t) dummyBuffer;
        }
        else {
            MAP_SPIDataPut(hwAttrs->baseAddr, *((uint32_t *) txBuf));
            MAP_SPIDataGet(hwAttrs->baseAddr, (unsigned long * ) rxBuf);
        }

        /* Only increment source & destination if buffers were provided */
        if (transaction->rxBuf) {
            rxBuf = (void *) (((uint32_t) rxBuf) + increment);
        }
        if (transaction->txBuf) {
            txBuf = (void *) (((uint32_t) txBuf) + increment);
        }
    }

    MAP_SPICSDisable(hwAttrs->baseAddr);
    MAP_SPIDisable(hwAttrs->baseAddr);
}

有人可以给我任何建议吗?

谢谢你  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您是否尝试在主机驱动程序中使用文件系统模块? 在我看来、这将完全满足您的需求。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我发现了这个问题、它与  spiPollingTransfer 增加缓冲区的方式有关。 在本例中、我使用  SPI_transfer 命令+ address 进行发送、然后接收数据。 但是、我没有意识 到每次 发送或接收字节时 spiPollingTransfer 都在递增两个缓冲区、因此我在其分配的内存之外读取我的 rxBuf。