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.

[参考译文] TDA3XEVM:SPI ISR 根据其与 AFL 触发电平相关的持续时间的意外行为。

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/655957/tda3xevm-unexpected-behaviour-of-an-spi-isr-based-on-its-duration-related-to-afl-trigger-level

器件型号:TDA3XEVM

您好!

我会尽量简洁地解释问题,但如果有问题不清楚,请问我。 我使用的是 TDA3x EVM 板、最近在一些代码中发现了一个错误、否则效果会很好。

一般的想法是使用 SPI 与某些外部器件进行双向通信。 传输的数据可以非常小、也可以具有几 KB 的大小、每个数据包大小的相关信息位于其标头中。 对于较大的数据传输、EDMA 用于释放处理器的这种不必要负载。 意识到数据包很大、需要由 EDMA 处理、这发生在 SPI ISR 内部的传输过程中。 在这种情况下,SPI 将禁用 SPI 模块中断,根据它需要传输的大小配置 EDMA, 将触发级别更改为1、以便它可以与 EDMA 控制器配合使用、然后启用对 EDMA 控制器的请求以处理其余传输。 当 EDMA 传输完成且 SPI 再次启用中断时、触发电平将恢复为原始值。 由于此过程非常快、McSPI FIFO 的大小可确保不会丢失任何数据。

 当我将某些日志函数放在此 ISR 中时,会发生意外行为。 根据我们的配置、一些计算表明、该打印函数消耗的时间超过14微秒(这是我们的触发级别)。 FIFO 内部大约为13.5微秒、因此如果 FIFO 缓冲区在我配置 EDMA 之前达到触发电平、一些数据将丢失、通信中断。 配置 EDMA 后从 ISR 内部打印日志不会产生任何问题。

据我所知、同一 ISR 本身不能中断、但我尝试在 ISR 内部手动禁用中断信号、但这无法解决问题(无论如何、硬件在处理中断时应禁用中断)。 当我在 ISR 持续时间内暂时将触发级别更改为更高的值并在退出 ISR 之前将其恢复为"已解决"问题。 我认为这不是一个好的解决方案、所以我想了解这个问题的原因、以便我可以集成一个更好的解决方案。 作为参考、我将粘贴 ISR 的某些部分(粘贴代码会破坏缩进、但 无论如何这只是一个示例)。

静态空 CustomSpiIsr (空)

  这里是变量声明
 {...
 
 }

 /*在此示例中,我仅使用 MCSPI_IRQENABLE_RX0_FULL 中断
 *因此、如果发生中断、我知道这是一个中断、但原始代码是
 *不同并也处理 WKE 中断
 *
   IRQ_STATUS = McSPIIntStatusGet (MCSPI1_BASE_ADDRESS);
 

 /*将 Rx 完全事件的触发级别提高到0x33以避免
  在 ISR 中重新触发事件
 *  
   McSPIFIFOTrigLvlSet (MCSPI1_base_address、
      0x33、
      0x0、
      MCSPI_TX_RX_MODE);
 
   /*这是自定义打印功能,植入细节并不重要
   *重要的是,它所需的时间比所需的时间要长
    *以使下一个 RX_FULL 事件发生
   *  
   CustomPrintFunction ("内部 ISR.\n");
 
  /*这是已删除的 ISR 使用的不相关部分的一些示例
   *因为我只想让您关注我在帖子中描述的内容
   *
   if (IRQ_STATUS 和 MCSPI_IRQENABLE_RX0_FULL_ENABLE_MASK)
   {        
  /*SPI_TRIGGER_LVL 的值为9*/
  对于(I = 0;I < SPI_TRIGGER_LVL;I++)
  {
   receiveBuffer[i]=(uint8_t) McSPIReceiveData (MCSPI1_base_address、gChNum);
  }

  #对接收到的数据进行计算
  如果(#使用 DMA 的条件)
  {
   McSPIIntDisable (MCSPI1_BASE_ADDRESS、MCSPI_IRQENABLE_RX0_FULL_ENABLE_MASK);

   
   McSPIFIFOTrigLvlSet (MCSPI1_base_address、
        0x1、
        0x0、
        MCSPI_TX_RX_MODE);

   在此处自定义配置 DMA 参数

   McSPIDMAEnable (MCSPI1_BASE_ADDRESS、
        MCSPI_CH0CONF_DMAR_MASK、
        MCSPI_CH_NUM);

  }   
  其他
  {
   否则
  }       
       
       McSPIIntStatusClear (MCSPI1_BASE_ADDRESS、MCSPI_IRQSTATUS_RX0_FULL_MASK);
   }

   /*将 Rx 完全事件的触发级别恢复为原始*/
   McSPIFIFOTrigLvlSet (MCSPI1_base_address、
      SPI_TRIGGER_LVL
        0x0、
        MCSPI_TX_RX_MODE);
 

提前感谢、

Theodore

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

    我已将您的问题转交给驾驶员专家。

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

    您好、Theodore、

    如果我理解得好、您只在添加打印例程时遇到问题、对吧?

    ISR 内部的打印速度通常非常慢。 例如、您可以在全局变量中传递标志(要打印的内容)、并仅在完成更重要的所有操作后在主例程中调用打印函数。

    另一种方法是修改打印功能、确保它只填充 UART FIFO、而不是退出离开 UART 硬件来执行其任务。

    此致、

    STAN

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

    您好、Stan、

    是只有在 ISR 内部(但仅在 EDMA 部件之前)添加打印函数时、才会出现此问题。 打印功能已按照您的建议进行了优化、但我的问题主要在于防止产品投入生产时出现一些错误。 我想了解为什么在配置 DMA 之前引入一些延迟(将触发电平更改为1等)、如果这个延迟足够大、那么足够大的字节将在 MCSPI FIFO 中累积(大于我使用的触发电平、即9) 我没有通过 DMA 接收所有数据、数据包已损坏。  配置 EDMA 后添加延迟(打印、计算等)不会带来任何问题。

    我的理论是、可能是因为我必须将触发电平更改为1、以便 EDMA 能够在配置未正确发生之前已达到触发(即处于活动状态)的情况下使用 SPI。  

    最后、我想知道这种将 FIFO 触发电平临时更改为更高值的快速修复(因此、直到 EDMA 配置完毕为止的 ISR 持续时间足够短、无法达到触发电平) 问题、或者是否有更干净的解决方案。  

    此致、

    Theodore

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    TDA3x 角色是什么-主器件还是从器件?

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

    TDA3x 是从器件。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我认为在数据传输过程中更改 FIFO 深度不是一个好主意。 至少在从较大值更改为较小值时。
    您可以改为尝试使用字计数器函数吗? 我不确定它在 DMA 模式下是否工作、但如果工作正常、它应该工作得更合适。


    "24.4.7.2.5字数统计结束
    启用通道后、MCSPI_IRQSTATUS[17] OOW 事件(字计数结束)将激活
    并配置为使用内置 FIFO。 当控制器执行的数量为时、会产生该中断
    在 MCSPI_XFERLEVEL[31:16] WCNT 位域中定义的传输。 如果 WCNT 设置为0x0000、则计数器
    未启用、并且不会生成该中断。
    字结束计数中断还指示使用的 SPI 传输在通道上停止
    一旦 WCNT 未重新加载且通道未重新启用、就会立即启用 FIFO 缓冲区。
    MCSPI_IRQSTATUS[17] OOW 中断状态位必须清除才能使中断线路失效(如果是
    启用事件作为中断源)。"