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 的外部 EEPROM 25LC1024写入或读取数据

Guru**** 607075 points
Other Parts Discussed in Thread: CC3220SF-LAUNCHXL, CC3220SF
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1232746/cc3220sf-launchxl-unable-to-write-or-read-data-from-the-spi-based-external-eeprom-25lc1024

器件型号:CC3220SF-LAUNCHXL
主题中讨论的其他器件: CC3220SF

尊敬的社区:

我正在处理基于 SPI 的 EEPROM 写读操作。
使用 CC3220SF-LAUNCHXL Rev.A 在 simplelink cc32xx SDK 6.10.00.05的帮助下对基于25LC1024 SPI 的 EEPROM 进行写入和读取操作

在基于 SPI 的 EEPROM 操作的 NORTOS 示例代码中搜索、未找到。如果找到 SimpleLink CC3220SF 至 EEPROM 读取写入操作的任何示例代码、请分享。

因此、我根据要求修改了 TI RTOS 基础 SPI 主设备示例代码。  

在尝试将数据0xAA 写入 EEPROM 并从相同地址(0x0010FF)读回时进行此修改后、我将0xFF 作为输出、我将地址更改为0x001000、然后也是相同的输出。 有人能帮助我解决这个问题吗?

修改后的代码如下:

/*
 *  ======== spi_eeprom.c ========
 */
#include <stdint.h>
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>
#include <string.h>


/* Driver Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/SPI.h>


/* Driver configuration */
#include "ti_drivers_config.h"

#define SPI_MSG_LENGTH (8)


unsigned char controllerRxBuffer[SPI_MSG_LENGTH];
unsigned char controllerTxBuffer[SPI_MSG_LENGTH];

/* EEPROM instructions */
#define EEPROM_WRITE_ENABLE     (0x06)
#define EEPROM_WRITE_DISABLE    (0x04)
#define EEPROM_READ             (0x03)
#define EEPROM_WRITE            (0x02)
#define EEPROM_ID               (0xAB)
SPI_Handle      controllerSpi;

SPI_Handle Init_SPI(void){
    SPI_Params      spiParams;
    //printf("SPI initiating\n");
    SPI_Params_init(&spiParams);  // Initialize SPI parameters
    spiParams.dataSize = 8;       // 8-bit data size
    spiParams.frameFormat = SPI_POL0_PHA0;
    spiParams.bitRate     = 1000000;
    controllerSpi = SPI_open(CONFIG_SPI_0, &spiParams);
    if (controllerSpi == NULL)
        {
            printf("Error initializing controller SPI\n");
        }
        else
        {
            printf("SPI initialized\n");
        }
    return controllerSpi;
}


int writeToEEPROM(uint32_t address, uint8_t* data, uint32_t dataSize)
{
    SPI_Transaction spiTransaction;
    bool            transferOK;
    printf("To write\n");
    uint8_t tmp_txBuffer[SPI_MSG_LENGTH];
    tmp_txBuffer[0] = EEPROM_WRITE_ENABLE;          // EEPROM write enable latch
    tmp_txBuffer[1] = EEPROM_WRITE;                 // EEPROM write command
    tmp_txBuffer[2] = (address >> 16) & 0xFF;       // Address MSB
    tmp_txBuffer[3] = (address >> 8) & 0xFF;        // Address middle byte
    tmp_txBuffer[4] = address & 0xFF;               // Address LSB
    tmp_txBuffer[5] = data;                         // data to be written to 25LC1024

    strncpy((char *)controllerTxBuffer, tmp_txBuffer, sizeof(SPI_MSG_LENGTH));
    memset((void *)controllerRxBuffer, 0, SPI_MSG_LENGTH);

    spiTransaction.count = SPI_MSG_LENGTH;
    spiTransaction.txBuf = (void *)controllerTxBuffer;
    spiTransaction.rxBuf = (void *)controllerRxBuffer;

    /* Toggle user LED, indicating a SPI transfer is in progress */
    GPIO_toggle(CONFIG_GPIO_LED_1);

    /* Perform SPI transfer */
    transferOK = SPI_transfer(controllerSpi, &spiTransaction);
    if (transferOK)
    {
        printf("Master transmitted data: %x\n", *(char *)controllerTxBuffer);
        //printf("bufr address of transmitted data: %#x\n", controllerTxBuffer);
    }
    else
    {
        printf("Unsuccessful SPI transfer");
        return -1;
    }
    return 0;
}

int readFromEEPROM(uint32_t address, uint8_t* receiveBuffer, uint32_t dataSize)
{
    printf("To read\n");

    // Prepare the read command and address
    SPI_Transaction spiTransaction;
    bool            transferOK;
    uint8_t tmp_txBuffer[SPI_MSG_LENGTH];
    tmp_txBuffer[0] = EEPROM_READ;                     // Read command
    tmp_txBuffer[1] = (address >> 16) & 0xFF;       // Address MSB
    tmp_txBuffer[2] = (address >> 8) & 0xFF;        // Address middle byte
    tmp_txBuffer[3] = address & 0xFF;               // Address LSB
    tmp_txBuffer[4] = 0xBB;                         // dummy data

    strncpy((char *)controllerTxBuffer, tmp_txBuffer, sizeof(SPI_MSG_LENGTH-1));
    memset((void *)controllerRxBuffer, 0, SPI_MSG_LENGTH-1);

    spiTransaction.count = SPI_MSG_LENGTH - 1;          // Read command + address + dummy with dataSize
    spiTransaction.txBuf = (void *)controllerTxBuffer;
    spiTransaction.rxBuf = (void *)controllerRxBuffer;

    /* Toggle user LED, indicating a SPI transfer is in progress */
    GPIO_toggle(CONFIG_GPIO_LED_1);

    /* Perform SPI transfer */
    transferOK = SPI_transfer(controllerSpi, &spiTransaction);
    if (transferOK)
    {
        printf("Master received data: %x\n", *(char *)controllerRxBuffer);
        //printf("bufr address of received data : %#x\n", controllerRxBuffer);

    }
    else
    {
        printf("Unsuccessful SPI transfer");
        return -1;
    }
    return 0;
}

void *mainThread(void *arg0)
{
    uint8_t writeData[] = {0xAA};  // Data to write to the EEPROM
    uint32_t address = 0x000010FF;                  // Address to write to and read from
    uint32_t dataSize = sizeof(writeData);          // Size of data to write and read
    uint8_t receiveBuffer[dataSize];
    /* Call driver init functions. */
    GPIO_init();
    SPI_init();
    /* Configure the LED pins */
    GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_setConfig(CONFIG_GPIO_LED_1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    Init_SPI();
    /* Turn on user LED */
    GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);

    // Write data to the EEPROM
    writeToEEPROM(address, writeData, dataSize);

    // Read data from the EEPROM
    readFromEEPROM(address, receiveBuffer, dataSize);
    SPI_close(controllerSpi);

    printf("\nDone");
}

我针对上述代码获得的输出:

写入
主机发送的数据:6

读取
主机接收的数据:FF

这是 SimpleLink 板的 SPI 引脚配置

硬件配置如下:

简单链接 25个 LC1024
SCLK SCK
MISO 因此
穆西 Si
SS CS 条
第3版 VCC 电压
接地 VSS

谢谢。此致、

Ajaykumar V

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

    尊敬的  Ajaykumar V:

    从我提供的代码中可以看到、您将调用 包含 EEPROM 写入命令的 SPI 事务。

    然后、您编写一个  包含 EEPROM 读取命令的 SPI 事务。

    但是 EEPROM 尚未处理此请求并将其放置到 外设 SPI TX 上、因此您没有 从  SPI 控制器上的 EEPROM 读取任何内容 、得到0xff。

    Id 尝试2件事情:

    1) 1)确保 EEPROM 处理了您的读取请求并将其放置到 EEPROM SPI TX 上。

    2) 在控制器端再次向 SPI 转接添加另一个呼叫。

    希望这对您有所帮助。

    此致、Avi Epstein。

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

    您好、Avi:

    • strncpy (((char *) controllerTxBuffer、tmp_txBuffer、sizeof (SPI_MSG_LENGTH));这个 字符串复制指令从 tmp_txBuffer 将部分数据复制到 controllerTxBuffer (即、仅复制读取或写入指令)、不复制其余数据)、 因此使用以下指令
      memcpy (controllerTxBuffer、tmp_txBuffer、sizeof (tmp_txBuffer)/ sizeof (tmp_txBuffer[0]);
      可能解决了该问题。
    • 当我执行环回操作(Launchpad MOSI 到同一电路板上的 Launchpad MISO)时、CONTROLLERTxBuffer 中的数据 将传输 到 CONTROLLERxBuffer。

    • 如果我尝试读取制造 ID 25LC1024、我认为在存储器浏览器中查看的 IC 无响应正在响应、数据为  controllerRxBuffer、不在控制台上打印。 如下图所示

      对于以下代码:
      /*
       *  ======== eeprom_id_spi.c ========
       */
      #include <stdint.h>
      #include <stdio.h>
      #include <stddef.h>
      #include <unistd.h>
      #include <string.h>
      
      /* Driver Header files */
      #include <ti/drivers/GPIO.h>
      #include <ti/drivers/SPI.h>
      #include <ti/display/Display.h>
      
      /* Driver configuration */
      #include "ti_drivers_config.h"
      /*
       *  ======== spi.c ========
       */
      
      #define SPI_MSG_LENGTH (8)
      
      unsigned char controllerRxBuffer[SPI_MSG_LENGTH];
      unsigned char controllerTxBuffer[SPI_MSG_LENGTH];
      
      
      #define EEPROM_SIZE     131072  // Size of 25LC1024 in bytes
      #define WRITE_CMD       (0x02)
      #define READ_CMD        (0x03)
      #define WRITE_EN_CMD    (0x06)
      #define EEPROM_ID       (0xAB)
      
      
      void Read_MFGID_EEPROM(void)
      {
          SPI_Handle controllerSpi;
          SPI_Params spiParams;
          SPI_Transaction transaction;
          uint32_t i;
          bool transferOK;
          int32_t status;
          uint8_t tmp_txBuffer[SPI_MSG_LENGTH];
      
          /* Open SPI as controller (default) */
          SPI_Params_init(&spiParams);
          spiParams.frameFormat = SPI_POL0_PHA0;
          spiParams.dataSize = 8;       // 8-bit data size
      
          spiParams.bitRate     = 1000000;
          controllerSpi = SPI_open(CONFIG_SPI_CONTROLLER, &spiParams);
          if (controllerSpi == NULL)
          {
              printf("Error initializing controller SPI\n");
          }
          else
          {
              printf("SPI initialized\n");
          }
      
          tmp_txBuffer[0] = EEPROM_ID;                    // instruction for EEPROM MFG ID
          tmp_txBuffer[1] = 0x00;                         // Dummy Address 
          tmp_txBuffer[2] = 0x10;                         // 
          tmp_txBuffer[3] = 0xFF;                         // 
          tmp_txBuffer[4] = 0x00;                         // dummy data
      
          memcpy(controllerTxBuffer, tmp_txBuffer, sizeof(tmp_txBuffer) / sizeof(tmp_txBuffer[0]));
          memset(controllerRxBuffer, 0, sizeof(controllerRxBuffer));
      
          printf("Master before transmit: %#016X\n", *(int *)controllerTxBuffer);
          printf("Master before received: %#016X\n", *(int *)controllerRxBuffer);
      
              /* Initialize controller SPI transaction structure */
              transaction.count = SPI_MSG_LENGTH;
              transaction.txBuf = (void *)controllerTxBuffer;
              transaction.rxBuf = (void *)controllerRxBuffer;
      
              /* Toggle user LED, indicating a SPI transfer is in progress */
              GPIO_toggle(CONFIG_GPIO_LED_1);
      
              /* Perform SPI transfer */
              transferOK = SPI_transfer(controllerSpi, &transaction);
              if (transferOK)
              {
                  printf("Master transmitted addrs: %#X\n", controllerTxBuffer);
                  printf("Master transmitted: %016X\n", *(int *)controllerTxBuffer);
                  printf("Master receive addrs: %#X\n", controllerRxBuffer);
                  printf("Master received: %#016X\n", *(int *)controllerRxBuffer);
              }
              transferOK = SPI_transfer(controllerSpi, &transaction);
              if (transferOK)
              {
                  printf("Master transmitted addrs: %#X\n", controllerTxBuffer);
                  printf("Master transmitted: %#08X\n", *(int *)controllerTxBuffer);
                  printf("Master receive addrs: %#X\n", controllerRxBuffer);
                  printf("Master received: %#08X\n", *(int *)controllerRxBuffer);
      
              }
              else
              {
                  printf("Unsuccessful SPI transfer\n");
              }
                  printf("Master transmitted loop: %#016X\n", *(int *)controllerTxBuffer);
      
          SPI_close(controllerSpi);
      
          printf("\nDone");
      
      }
      
      /*
       *  ======== mainThread ========
       */
      void *mainThread(void *arg0)
      {
      
          /* Call driver init functions. */
      
          GPIO_init();
          SPI_init();
      
          /* Configure the LED pins */
          GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
          GPIO_setConfig(CONFIG_GPIO_LED_1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
      
      
          /* Turn on user LED */
          GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
      
          printf("Starting the SPI Transfer\n");
          
          /* Read MFG ID of EEPROM */
          Read_MFGID_EEPROM();
      }

    在上面的代码中、我自己尝试了您建议的内容

     在控制器端再次向 SPI 传输添加另一个调用
    • 在读取之前/写入操作之后对 EEPROM 过程发出一些延迟、在创建此线程时发送原始代码的读取操作时也称为 SPI 传输。  

    确保 EEPROM 处理了您的读取请求并将其放在 EEPROM SPI TX 上。


    此致、  
    Ajaykumar V

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

    尊敬的  Ajaykumar V:

    1) 1) 您能确切解释您想要实现的目标吗?

    2) 2)您当前的问题是什么?  

    3) 3)为什么要运行 回送?

     我 在代码更改中看到的内容来看、您 将使用控制器 TX 上的相同数据对 SPI 传输进行两次调用。 您想 通过此实现什么目标?

    SPI 传输(从控制器调用) 可同时 写入外 设并从外设读取数据(尽管 SPI 是双向的 、但我认为在应用中 它应该用作请求响应)。

    如果您希望 对 EEPROM 执行一个写入/读取周期、则需要:

    1) 1)写入 命令(来自控制器): 调用 包含 EEPROM 写入命令的 SPI 传输 、其中包含要写入的数据(EEPROM 将接收并将其保存在您指定的地址中)

    2) 读取命令(来自 控制器) 调用 包含 EEPROM 读取命令的 SPI 传输(EEPROM 将处理您的请求并将您请求的数据放在外设 TX 上、这可能不是立即实现的、这  就是您需要执行步骤3的原因)

    3) 读取操作(来自 控制器)现在、EEPROM 将数据放置在 外设 TX 上、控制器 已准备好 接收数据、因此再次调用 SPI 传输以获取数据。

    查看您的 EEPROM 数据表并查看确切的详细信息。

    此致、

    AVI Epstein.

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

    您好、Avi:

    您能解释一下您 到底想要实现什么吗?

    我想使用 SimpleLink CC3220SF Launch Pad 实现外部 EEPROM 写入/读取操作。

    您当前遇到什么问题?  [/报价]

    问题在于读取写入和读取未发生。

    为什么要运行 回送?

    仅用于测试传输的数据会通过 SPI 完全或不完全传输。 回送与 EEPROM 写入/读取操作无关。

     在控制器端再次向 SPI 转接添加另一个呼叫。

    我无法理解上述陈述。

    您 使用控制器 TX 上的相同数据调用 SPI 传输两次。 [/报价]

    下面的说明解决了我的问题。

    strncpy ((char *) controllerTxBuffer、tmp_txBuffer、sizeof (SPI_MSG_LENGTH);此 字符串复制指令从 tmp_txBuffer 将数据的一部分复制到 controllerTxBuffer (即、仅复制读取或写入指令)、 因此不会使用以下指令复制数据的其余部分)
    memcpy (controllerTxBuffer、tmp_txBuffer、sizeof (tmp_txBuffer)/ sizeof (tmp_txBuffer[0]);
    可以解决该问题。

    以下代码可以解决我的问题:

    SPI_Handle Init_SPI(void){
        SPI_Params      spiParams;
        printf("SPI initiating\n");
        SPI_init();  // Initialize the SPI driver
        SPI_Params_init(&spiParams);  // Initialize SPI parameters
        spiParams.dataSize = 8;       // 8-bit data size
        spiParams.frameFormat = SPI_POL0_PHA0;
        spiParams.bitRate     = 1000000;
        controllerSpi = SPI_open(CONFIG_SPI_0, &spiParams);
        if (controllerSpi == NULL)
            {
                printf("Error initializing controller SPI\n");
            }
            else
            {
                printf("Controller SPI initialized\n");
            }
        return controllerSpi;
    }
    int EEPROM_WriteLatch(void){
        SPI_Transaction spiTransaction;
        bool            transferOK;
        uint8_t tmp_txBuffer[SPI_MSG_LENGTH];
        tmp_txBuffer[0] = EEPROM_WRITE_ENABLE;          // EEPROM write enable latch
        spiTransaction.count = 1;
        memcpy(controllerTxBuffer, tmp_txBuffer, sizeof(tmp_txBuffer) / sizeof(tmp_txBuffer[0]));
        spiTransaction.txBuf = (void *)controllerTxBuffer;
        spiTransaction.rxBuf = NULL;
        SPI_transfer(controllerSpi, &spiTransaction);
        transferOK = SPI_transfer(controllerSpi, &spiTransaction);
        if (transferOK)
        {
            printf("EEPROM is ready to write data\n");
            return 0;
        }
        else
        {
            printf("Unsuccessful in Latching Write EEPROM\n");
            return -1;
        }
    }
    
    int writeToEEPROM(uint32_t address, uint8_t* data, uint32_t dataSize)
    {
        EEPROM_WriteLatch();
        SPI_Transaction spiTransaction;
        bool            transferOK;
        uint8_t tmp_txBuffer[SPI_MSG_LENGTH];
        int i;
        printf("To write\n");
    
        tmp_txBuffer[0] = EEPROM_WRITE;                 // EEPROM write command
        tmp_txBuffer[1] = (address >> 16) & 0xFF;       // Address MSB
        tmp_txBuffer[2] = (address >> 8) & 0xFF;        // Address middle byte
        tmp_txBuffer[3] = address & 0xFF;               // Address LSB
        tmp_txBuffer[4] = 0xAA;                         // data to be written to 25LC1024
        
    
        memcpy(controllerTxBuffer, tmp_txBuffer, sizeof(tmp_txBuffer) / sizeof(tmp_txBuffer[0]));
        memset((void *)controllerRxBuffer, 0, SPI_MSG_LENGTH);
    
        spiTransaction.count = SPI_MSG_LENGTH;
        spiTransaction.txBuf = (void *)controllerTxBuffer;
        spiTransaction.rxBuf = NULL;
    
        /* Toggle user LED, indicating a SPI transfer is in progress */
        GPIO_toggle(CONFIG_GPIO_LED_1);
    
        /* Perform SPI transfer */
        transferOK = SPI_transfer(controllerSpi, &spiTransaction);
        if (transferOK)
        {
            for(i = SPI_MSG_LENGTH -1 ; i > 3; i--){
            printf("Master transmitted data: %#X\n", *(char *)(controllerTxBuffer + i));
            }
            printf("bufr transmitted data: %#X\n", *(int *)(controllerTxBuffer + 4));
            printf("bufr address of transmitted data: %#X\n", controllerTxBuffer);
        }
        else
        {
            printf("Unsuccessful controller SPI transfer");
            return -1;
        }
        return 0;
    }
    
    int readFromEEPROM(uint32_t address, uint8_t* receiveBuffer, uint32_t dataSize)
    {
        printf("To read\n");
    
        /* Prepare the read command and address */
        SPI_Transaction spiTransaction;
        bool            transferOK;
        uint8_t tmp_txBuffer[SPI_MSG_LENGTH];
        int i;
        tmp_txBuffer[0] = EEPROM_READ;                  // Read command
        tmp_txBuffer[1] = (address >> 16) & 0xFF;       // Address MSB
        tmp_txBuffer[2] = (address >> 8) & 0xFF;        // Address middle byte
        tmp_txBuffer[3] = address & 0xFF;               // Address LSB
        tmp_txBuffer[4] = 0xBB;                         // dummy data
        
        memcpy(controllerTxBuffer, tmp_txBuffer, sizeof(tmp_txBuffer) / sizeof(tmp_txBuffer[0]));
        memset((void *)controllerRxBuffer, 0,SPI_MSG_LENGTH);
        spiTransaction.count = sizeof(tmp_txBuffer) / sizeof(tmp_txBuffer[0]);    // Read command + address + dummy data to transmit while receiving
        spiTransaction.txBuf = (void *)controllerTxBuffer;
        spiTransaction.rxBuf = (void *)controllerRxBuffer;
    
        /* Toggle user LED, indicating a SPI transfer is in progress */
        GPIO_toggle(CONFIG_GPIO_LED_1);
    
        /* Perform SPI transfer */
        transferOK = SPI_transfer(controllerSpi, &spiTransaction);
        if (transferOK)
        {
            for(i = SPI_MSG_LENGTH -1 ; i > 3; i--){
            printf("Master received data: %#X\n", *(char *)(controllerRxBuffer + i));
            }
            printf("bufr received data: %#X\n", *(int *)(controllerRxBuffer + 4));
            printf("bufr address of received data : %#X\n", controllerRxBuffer);
        }
        else
        {
            printf("Unsuccessful controller SPI transfer");
            return -1;
        }
        return 0;
    }

    感谢您在启动外部 EEPROM 25LC1024读写操作时的耐心和持续支持 Avi E.。

    谢谢。此致、

    Ajaykumar V

    [/quote][/quote]