工具/软件:
您好、专家:
我们的客户尝试使用以下代码来检查 SPI 行为。

结果如下。

问题是、在 SPI CS 变为高电平后需要 30.214usec 的时间才能进行下一次 GPIO 切换 (DRDY)。
每次都会发生该问题、并且在 CS 到 GPIO 切换结束之间没有发生中断。
它们现在使用 SPI 阻塞模式。
您能否告知造成此延迟的原因是什么、以及如何解决?
一个想法是 使用回叫模式,但它需要许多资源,不想尽可能多地改变。
此致、
A. Fujinaka
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.
工具/软件:
您好、专家:
我们的客户尝试使用以下代码来检查 SPI 行为。

结果如下。

问题是、在 SPI CS 变为高电平后需要 30.214usec 的时间才能进行下一次 GPIO 切换 (DRDY)。
每次都会发生该问题、并且在 CS 到 GPIO 切换结束之间没有发生中断。
它们现在使用 SPI 阻塞模式。
您能否告知造成此延迟的原因是什么、以及如何解决?
一个想法是 使用回叫模式,但它需要许多资源,不想尽可能多地改变。
此致、
A. Fujinaka
您好:
在 SPI_MODE_BLOCKING 下运行后、在我的设置中需要 22 μ s 才能处理 GPIO_Toggle。 我尝试更改了软件中断优先级[SPI 使用 DMA 中断]、但此路径没有成功。
通过启用回调模式、您几乎可以在 CS 激活开始时执行 GPIO_TOGGLE。
第一个选项:
spiParams.transferMode = SPI_MODE_CALLBACK; .... transferOK = SPI_transfer(controllerSpi, &transaction); GPIO_toggle(CONFIG_GPIO_LED_1);

这将使 GPIO 几乎与 SPI_Transfer 并行切换。
“一个想法是 使用回叫模式,但它需要许多资源,不想尽可能多地改变“
我认为它不需要大量的资源。 再定义一个函数、将其作为函数指针传递到 SPI。 如果您需要知道 SPI_TRANSFER 是否已完成、可以使用类似 RTOS 的互斥量对象来同步进程。 在本例中、我使用了 volatile bool。
volatile bool transferComplete = false;
void spiCBFxn(SPI_Handle handle, SPI_Transaction *transaction)
{
transferComplete = false;
if (transaction->status == SPI_TRANSFER_COMPLETED)
{
transferComplete = true;
}
}
SPI_Params_init(&spiParams);
spiParams.transferMode = SPI_MODE_CALLBACK;
spiParams.transferCallbackFxn = spiCBFxn;
spiParams.frameFormat = SPI_POL0_PHA1;
/* See device-specific technical reference manual for supported speeds */
spiParams.bitRate = 1000000;
transferOK = SPI_transfer(controllerSpi, &transaction);
GPIO_toggle(CONFIG_GPIO_LED_1);
while(!transferComplete); // blocking.
第三个选项:此选项可以在 CS 停用后将 GPIO_TOGGLE 功能最小化。 在我的示例中、将时间从 22us 缩短到 10us。
volatile bool transferComplete = false;
void spiCBFxn(SPI_Handle handle, SPI_Transaction *transaction)
{
transferComplete = false;
if (transaction->status == SPI_TRANSFER_COMPLETED)
{
transferComplete = true;
GPIO_toggle(CONFIG_GPIO_LED_1);
}
}
....
SPI_Params_init(&spiParams);
spiParams.transferMode = SPI_MODE_CALLBACK;
spiParams.transferCallbackFxn = spiCBFxn;
spiParams.frameFormat = SPI_POL0_PHA1;
/* See device-specific technical reference manual for supported speeds */
spiParams.bitRate = 1000000;
....
transferOK = SPI_transfer(controllerSpi, &transaction);
while(!transferComplete); // blocking.

致幻:
-您可以决定并行运行 GPIO_TOGGLE 与 SPI_Transfer 或在 SPI_Callback 函数中,您可以决定根据 SPI_TRANSFER 状态切换 GPIO。 以下是您可以根据 SPI_Transfer 状态检查的状态代码。 根据 SPI 状态处理 GPIO 的最佳方法是使用回调函数。
SPI_TRANSFER_COMPLETED = 0、/*!< SPI 传输已完成*/
SPI_TRANSFER_STARTED、/*!< SPI 传输已开始并正在进行*/
SPI_TRANSFER_CANCELLED、/*!< SPI 传输被取消*/
SPI_TRANSFER_FAILED、/*!< SPI 传输失败*/
SPI_TRANSFER_CSN_DEASSERT、/*!< SPI 芯片选择被置为无效(仅限
适用于返回部分模式)*/
SPI_TRANSFER_PEND_CSn_ASSERT、/*!< SPI 传输在芯片之前挂起
选择生效*/
SPI_TRANSFER_QUEUTERED /*!< SPI 传输已添加到事务队列*/
-更改 SPI 中断优先级不会缩短执行时间。