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.

[参考译文] TMS320F28386S:SPI 和 CM-SSI 行为相同。 阶段问题。

Guru**** 2535650 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1553939/tms320f28386s-spi-and-cm-ssi-behaviour-is-the-same-phase-issue

部件号:TMS320F28386S


工具/软件:

目前、我有 5 个 SPI 器件连接到 MCU:

  • 2xADS8900B ADC
  • AD5293 数字电位计
  • FM25V02A FRAM 存储
  • 连接到 CM SSI 的基于 BT815 的显示模块。

所有这些都有相同的问题:

根据数据表、所有器件都在 SPI 模式 0 (CPOL=0、CPHA=0) 下运行、但 AD5293 除外、它是模式 1 (CPOL=0、CPHA=1) 器件。

因此、当我将 SPI 端口配置为这些设置时、除 BT815 之外、什么都不起作用、至少它接受发送的数据。

因此、我将 SPI 端口的设置更改为相反的设置、AD5293 的模式 0 和其他端口的模式 1。 此后、所有器件都接受命令。 但是:

当我从器件读回数据时、它会移位 1 位! AD5293 正常、因为不需要读取它。

因此对于 BT815、我在读取前将 SSI 端口更改为模式 1、之后将更改为模式 0。

对于 SPI 端口上的其他 3 个器件、我在读取前将 SPI 端口更改为模式 0、然后重新更改为模式 1。

因此、除 AD5293 外、所有 SPI 器件的常见工作流程是:

(无论器件是模式 0、端口都初始配置为模式 1)

  1. 发送命令
  2. 更改为 MODE 0
  3. 读取响应
  4. 更改为模式 1

现在一切都正常。 但这是奇怪的!

适用于 FRAM 的代码为:

static void SPI_setReadMode(bool read)
{
    SPI_disableModule(FRAM_SPI_BASE);
    SPI_setConfig(FRAM_SPI_BASE, DEVICE_LSPCLK_FREQ, read ? SPI_PROT_POL0PHA0 : SPI_PROT_POL0PHA1,
                  SPI_MODE_CONTROLLER, FRAM_SPI_BITRATE, FRAM_SPI_DATAWIDTH);
    SPI_setPTESignalPolarity(FRAM_SPI_BASE, SPI_PTE_ACTIVE_LOW);
    SPI_enableModule(FRAM_SPI_BASE);

}

void FRAM_Read(uint32_t addr, void *buf, uint32_t len) {
    FRAM_CS_LOW();
    SPI_WriteByte(FRAM_SPI_HANDLE, 0x03); // READ
    SPI_WriteByte(FRAM_SPI_HANDLE, (addr >> 8) & 0xFF);
    SPI_WriteByte(FRAM_SPI_HANDLE, addr & 0xFF);
    uint8_t *p = (uint8_t*)buf;
    uint32_t i;
    SPI_setReadMode(true);
    for (i = 0; i < len; i += 2)
    {
        uint8_t w = SPI_ReadByte(FRAM_SPI_HANDLE);
        p[i / 2] = w << 8;
        w = SPI_ReadByte(FRAM_SPI_HANDLE);
        p[i / 2] |= w;
    }
    while (SPI_isBusy(FRAM_SPI_HANDLE));
    FRAM_CS_HIGH();
    SPI_setReadMode(false);
}

对于 CM 上的 BT815:

void HAL_SPI_ReadBuffer(uint8_t *Buffer, uint32_t Length)
{
    HAL_SPI_Write(0);
    SSI_disableModule(SSI0_BASE);
    SSI_setConfig(SSI0_BASE, CM_CLK_FREQ, SSI_FRF_MOTO_MODE_1, SSI_MODE_MASTER, 12000000, 8);
    SSI_enableModule(SSI0_BASE);
    for(; Length; Buffer++, Length--)
    {
        *Buffer = HAL_SPI_Write(0);
    }
    SSI_disableModule(SSI0_BASE);
    SSI_setConfig(SSI0_BASE, CM_CLK_FREQ, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 12000000, 8);
    SSI_enableModule(SSI0_BASE);
}

使用此代码时、示波器显示 SPI 线路上的覆盖正常、但没有移动 1 位。

更改端口的比特率不会影响此行为。 (数据表中 FRAM 芯片的比特率为 40MHz、我尝试将其降低到 400kHz,结果相同)。

我之前在 F2837x 器件上注意到了相同的问题。

重要声明

我稍后会附加示波器截图、因为现在我不在设备上、但示波器在所有设备的模式 0 和 AD5293 的模式 1 中都显示了正确的数据。

因此、这个问题在 MCU 的 SPI/SSI 硬件中是有限的。

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

    您好、Oleg、

    能否分享示波器屏幕截图? 为了进行澄清、您是否说您看到数据是一位移出的、因此总线上有一个额外的 0/1? 我可以看到该命令结构包括在发送 6 位命令之前发送“0"和“和“1",“,然后、然后在发送第二个和第三个字节之前发送“00"。“。  

    此致、

    Aishwarya

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

    关于 BT815 符合 CM 的 SSI、从主机发送的数据处于模式 0、但从 BT815 发送的数据被 SSI 硬件移动一位(示波器显示两个方向都是正常模式 0)、因此我必须在接收期间切换到模式 1。

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

    Oleg、

    您能否分享示波器截图? [/报价]

    该 SPI 针对 16 位读取/写入进行了优化、因此任何低于/高于该值的内容都需要特别注意。 当您一次写入一个字节时、FRAM 函数看起来正常。 另一个代码也应该一次写入一次、如 driverlib 中的 spi_receive24Bits () 函数所示。 下面是一个片段:

    此致、

    Aishwarya

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

    我在字节顺序方面没有问题、但在任何字大小(8 位、16 位或 20 位)下移位 1 位。

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

    Oleg、

    根据我在第一次答复中的要求、您能否分享示波器截图?  

    我提到了上述情况、因为 SPI 是一种发送 — 接收协议,因此,对于发送的每个位,也应该接收它。    我们可以确认的时钟也可能存在问题。

    此致、

    Aishwarya