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.

[参考译文] TMS320F28027:在时钟速度大于1MHz 时、不会发生 SPI 同时发送和接收

Guru**** 2589275 points
Other Parts Discussed in Thread: C2000WARE, TMS320F28027

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/957822/tms320f28027-spi-simultaneous-transmit-and-receive-not-happening-at-clock-speeds-greater-than-1mhz

器件型号:TMS320F28027
主题中讨论的其他器件:C2000WARE


CCS -版本10.1.1
C2000Ware -版本3.03.00


问题说明:
在 TMS320F28027 (主器件)和 ST25R3916 (从器件- NFC 读取器 IC)之间建立 SPI 接口。
从器件可支持高达10MHz 的时钟、并具有512字节 FIFO 缓冲器。
对于我们的方案、我们至少需要同时通过 SPI 发送和接收数据
在10MHz SPICLK 上运行时、数据一次为200字节。

SYSCLK - 60MHz
SPI 配置:

void SPI_cfg (void)

EALLOW;
clk_handle->LOSPCP = 0;//Setting the peripheral clk freq to sys clk freq (60MHz)
EDIS;
CLK_enableSpiaClock (clk_handle);

SPI_setCharLength (SPI_Handle、SPI_CharLength _8_Bits);
SPI_setMode (SPI_Handle、SPI_Mode_Master);
SPI_enableTx (SPI_Handle);

SPI_Handle->SPIBRR = 59;

SPI_ENABLE (SPI_Handle);

//设置断点以使断点不会干扰 xmission
SPI_setPriority (SPI_Handle、SPI_Priority_freeRun);

SPI_enableChannels (SPI_Handle);
SPI_enableFifoEnh (SPI_Handle);
SPI_resetTxFifo (SPI_Handle);
SPI_clearTxFifoInt (SPI_Handle);
SPI_resetRxFifo (SPI_Handle);
SPI_clearRxFifoInt (SPI_Handle);

SPI_enableRxFifo (SPI_Handle);
SPI_enableTxFifo (SPI_Handle);

情况1:发送并等待 Rx 状态标志设置为读取、然后在读取后写入

void SPI_Transmit _Receive (uint16_t * tx_buff、uint16_t * rx_buff、uint16_t len)

volatile uint16_t remain_len = 0;

while (remain_len < len)

SPI_WRITE (SPI_Handle、((uint16_t) TX_buff [剩余_len])<< 8);

while (!(SPI_Handle->SPIFFRx & 0x1F00));//等待 Rx 状态标志被置位

RX_buff[Remain_len]=(uint8_t)(SPI_Read (SPI_Handle)& 0x00FF);

剩余_len++;


 

情况2:如果 Rx 状态标志被置位、则为只读

通过使用这种方法、我们能够同时发送和接收@1MHz SPICLK、而且这也只能达到60字节。
如果发送和接收缓冲区大于60、则少数字节不会更新到 Rx 缓冲区中、而是会更新
可以在逻辑分析仪中看到它。

void SPI_Transmit _Receive (uint16_t * tx_buff、uint16_t * rx_buff、uint16_t len)

volatile int TX_len = 0、RX_len = 0;

while (tx_len < len || rx_len < len)

if (tx_len < len)

SPI_WRITE (SPI_Handle、((uint16_t) TX_buff [TX_len])<< 8);
TX_Len++;

if (rx_len < len)

if (SPI_Handle->SPIFFRX & 0x1F00)

RX_buff[RX_len]=(uint8_t)(SPI_Read (SPI_Handle)& 0x00FF);
RX_Len++;



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

    您好、Akash、

    使用大于1MHz 的频率时、您观察到什么? 接收到的数据是否损坏?

    您是否检查  了状态寄存器中是否设置了溢出标志?

    此致、

    Veena

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

    您好、Veena、

    我正在使用 FIFO 模式、SPIFFRx 寄存器中的 RXFFOVF 标志以及 SPISTS 寄存器中的溢出标志始终为0。

    在频率大于1MHz 的情况下、SPI cock 在通信期间随机变为无效。

    PFA 逻辑分析仪的屏幕截图供您参考。

       

    在上面的图片中、您可以清楚地看到未激活的时间段。

    P.S:即使时钟@1MHz、如果从器件有50个字节的响应(在逻辑分析仪中观察到)、数据读取也不会被正确读取。 仅接收到大约37个字节、并且 SPIRXFFST 为0、这表明虽然 MISO 线路中有50个字节的响应、但没有挂起数据。  

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

    您好、Akash、

    SPI CLK 仅在存在有源传输时保持有效。 一旦一个传输完成、如果 TXBUF 中没有挂起的数据、SPICLK 和 STE 引脚将进入非活动状态。

    在您的代码中、我看到您是循环地连续发送和接收数据。 我想在使用1MHz 时钟时、即使在之前的数据完全传输之前、该函数也会更新 TXBUF 寄存器。 这是可以的、因为 SPI 将等待活动传输完成、然后开始在 TXBUF 中传输新数据。 因此 SPICLK 和 STE 引脚永远不会进入未激活状态。

    当您增加频率时、我相信只有在之前的数据完全传输后、SPI_WRITE 函数才会被调用、因此您会看到引脚在很短的时间内处于非活动状态。 在第一个迭代期间、您尝试在 TX 之后立即读取数据、检查 RX 状态可能返回 false、并且您更快地进入第二个迭代。 这可能是您在第一次传输后未看到引脚处于非活动状态的原因。 但从第二次迭代开始、您也开始读取 RXBUF、因此 SPI_WRITE 函数调用会延迟、数据传输可能在此时间内完成、引脚可能已进入非活动状态。

    此致、

    Veena

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

    你(们)好、Veena

    我们知道、由于您提到的延迟、这是无效的。 我们正在寻找一种解决方案来避免这种延迟并实现无中断的通信。

    正如我之前提到的、即使在1MHz 时也是如此、即使时钟没有被中断、但在 MISO 线路中观察到的所有数据都在 rxbuf 寄存器中被检测到。

    那么、您能否提供有关如何克服这一问题的见解?

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

    您好、Akash、

    为什么不使用 DMA 传输和接收多个数据? 因此可以避免软件延迟。

    此致、

    Veena

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

    您好、Akash、

    或者、如果您的发送长度小于 FIFO 大小、您可以尝试一次发送所有数据、然后开始从 RX FIFO 读取数据。

    此致、

    Veena

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

    您好、Veena、

    我们的问题声明要求传输长度可高达512字节(从 FIFO 缓冲区长度)、对于 tms320f28027、该长度大于 FIFO 缓冲区长度4x16位。

    F2802x 系列 MCU 参考手册中规定、可以同时接收和发送。 那么、如果我们在传输时读取 RXBUF、为什么会有延迟。  

    PFA 参考手册的屏幕截图、我们将其用于参考。

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

    您好、Veena、

    我相信 TMS320F29027处理器没有可用的 DMA 支持。

    如果我错了、请提供有关如何在 F28027上实现 DMA 的帮助

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

    您好、Akash、

    我很抱歉。 你是对的。 该器件不支持 DMA。 该器件支持同时发送和接收、因此您可以在 MOSI 和 MISO 线路上看到数据、并且 RXBUF 会在传输完成后立即更新。 延迟完全是由于写入 TXBUF 的软件延迟所致。

    您是否启用了优化?  

    此致、

    Veena

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

    您好、Veena、

    最初优化已关闭、即使在1MHz 下也无法正常工作。

    因此、在对优化和大小与速度水平的每种可能组合进行试错后、可以同时进行@1MHz 的传输和接收、并且使用相同的优化设置、如果我增加 SPI 时钟频率、问题仍然存在。

    目前最好的观察结果是使用--opt_level、-O0和--opt_for_speed、-mf 在0和5之间的任何值获得。

    是否希望我们仅尝试特定的优化设置?

     如果是、请说明我们需要设置的优化级别、我们将附上这些设置的观察结果。

    P.S:我们已经尝试了所有优化级别、但仍然没有令人满意的观察结果。  

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

    您好、Akash、

    如果一些 SPI 专家有任何建议、我将与他们联系。

    我想了解在传输之间使 SPICLK 处于非活动状态的后果是什么。 NFC 读取器是否希望时钟保持连续?

    我看到一些器件希望 STE 引脚在整个数据传输过程中处于活动状态。 在这种情况下、我们通常使用普通 GPIO 引脚并在软件中相应地进行切换、而不是使用 SPI 模块驱动该引脚。

    此致、

    Veena

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

    您好、Aksah、

    在查询 RXBUF 上缺失的数据时、它是像缺失的初始/最终字节、还是完全随机的?

    此致、

    Veena

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

    你(们)好、Veena  

    如果 SPICLK 未激活、NFC 读取器将被复位。 这不是首选。

    我们甚至尝试将 STE 引脚配置为 GPIO、并在整个操作过程中将其设置为低电平、但时钟在这两者之间变为空闲状态。 但即使 STE 引脚为低电平有效、时钟仍然处于非活动状态。

    关于 RXBUF 中丢失的数据、我们每次都能很好地接收前5到10个字节、但丢失的剩余数据是随机发生的。  

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

    您好、Akash、

    我相信您可以通过更高效地使用 SPI FIFO 来优化 SPI 传输。 您的目标应该是始终保持 TX FIFO 为满且 RX FIFO 为空。 您使用的 TX 和 RX FIFO 深度设置是什么?  

    我建议如下:

    -将 TX FIFO 深度设置为3。  当 TX FIFO 中包含3个或更少字符时、这将强制 SPI 设置 TXFFINT。 在调用 SPI_Transmit receive()的开始,向 TX FIFO 写入4个字符,然后在每次 TXFFINT 之后设置时向 TX FIFO 写入1个字符。 这应确保 TX FIFO 中至少装载3个字符。 使用 TXFFINTCLR 来清除标志。

    ——将 RX FIFO 深度设为1。 当 RX FIFO 中有1个或更多字符时、这将强制 SPI 设置 RXFFINT。 每次 RXFFINT 置位时从 RX FIFO 读取1个字符。 这应确保 RX FIFO 在大多数时间都是空的。 使用 RXFFINTCLR 来清除标志。

    或者、您可以查看 TXFFST 和 RXFFST 位来确定 TX 和 RX FIFO 中的确切字符数。 但同样、目的是保持 TX FIFO 满且 RX FIFO 为空。