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.

[参考译文] PROCESSOR-SDK-AM335X:不会发生 McSPI 中断

Guru**** 2539500 points


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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/859453/processor-sdk-am335x-mcspi-interrupts-do-not-occur

器件型号:PROCESSOR-SDK-AM335X

尊敬的 TI 支持社区:

我正在尝试修改(drivers/spi/spi-omap2-mcspi.c)
OMAP4 mcspi 驱动程序、以便使用中断而不是轮询。
我使用 BeagleBone Black。
 在我将 CS 置为活动状态并启用通道0和中断后、
我只接收两个中断(实际上是一对中断):
- tx0_empty 之后、我通过写入来填充 TX 缓冲器
mcspi TX reg n-times
然后在 IRQSTATUS 中复位标志
-作为对 tx0_empty 所采取操作的后续操作,
rx0_full 中断已上升、我读取了 mcspi Rx reg n 次
并在 IRQSTATUS 中复位标志。
之后没有中断(TX_EMPTY、RX_FULL 或 EOT 均无中断)
即使启用了中断和通道0并且 CS 处于活动状态、
因此我无法传输剩余的数据。
 FIFO 被启用并且 OMAP2_MCSPI_XFERLEVEL 被相应地设置(但是、如果 FIFO 被禁用的话、会发生类似的情况)。
 请注意、如果我要传输只需要一对的消息
中断、
然后 EOT 中断出现、这是预期的行为。
 我仅使用了小于 dma_min_Bytes (160)的传输长度、因此不使用 dma。
 如果我使用轮询方法来查看通道0上是否有挂起的内容
一切都运行良好(这是 SPI-OMAP2-mcspi.c 中的默认行为
OMAP2_mcspi_txrx_Pio())。

另一件事是:如果我将 CS 置为活动状态并启用通道0、则在 IRQSTATUS 中将会置位
向上计数 TX0_EMPTY、中断启用后、将发生 TX0_EMPTY 中断。
但是、如果我在启用中断前复位 IRQSTATUS 中的 TX0_EMPTY 位
(正如 AM335x 手册在第24.3.4.1章中所述、中断驱动操作:
中断状态位应在通道结束后始终复位
在事件作为中断源启用之前启用)
即使在此之后启用中断、也不会发生中断。

 是否有人在中断模式(无 DMA)下使用 OMAP4 mcspi?

谢谢、此致、
L-C. 杜卡


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

    尊敬的用户6230715:

    [引用 user6230715]\n 我正在尝试修改(drivers/spi/spi-omap2-mcspi.c)
    OMAP4 mcspi 驱动程序、以便使用中断而不是轮询。

    您是否使用 ti-processor-sdk-linux-am335x-evm-06.01.00.08/board-support/linux-4.19.59/drivers/spi/spi-omap2-mcspi.c 驱动程序?


    [引用 user6230715"]我使用 BeagleBone Black。

    您是否将 AM335x MCSPI 模块用作主设备? 您是否将任何芯片连接到 BBB AM335x McSPI 模块? 您是修改 Linux 内核 BBB DTS 文件还是使用默认文件?

    对于 AM335x McSPI 中断功能、我建议您检查 AM335x TRM 通道24 McSPI


    另请检查以下 e2e 线程是否会提供帮助:

    https://e2e.ti.com/support/legacy_forums/embedded/linux/f/354/t/259958

    此致、
    帕维尔

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

    您好、Pavel、

    我已经使用 ti-processor-sdk-linux-am335x-evm-06.01.00.08/board-support/linux-4.19.59/drivers/spi/spi-omap2-mcspi.c 以及 Linux 香草4.14.71进行了测试。

    我已经测试了以下场景:

    -MOSI-MISO 之间的 spi0环回

    - SPI1连接到与 OMAP2_mcspi_txrx_Pio()配合使用的 SPI FPGA 驱动程序

    在 OMAP2_mcspi_transfer_one ()中、我调用 OMAP2_mcspi_txrx_interrupts (SPI、t)
    而不是 OMAP2_mcspi_txrx_Pio (SPI、t)。

    我已添加到 SPI-OMAP2-mcspi.c 的模拟代码

    decled_wait_queue_head (omap_mcspi_wq);
    静态无符号字符*rx=NULL;
    静态常量无符号字符*TX=NULL;
    静态 int rx_len、tx_len;
    静态 int interrupt_done;

    静态 irqreturn_t omap_mcspi_irq_handler (int IRQ、void *dev_id)
    {    
       struct omap2_mcspi   *mcspi = dev_id;
       int ning=1;
       u32 l;
       U8字节;
       
       l = mcspi_read_reg (mcspi->master、OMAP2_MCSPI_IRQSTATUS);

       if (l & OMAP2_MCSPI_IRQSTATUS_TX0_EMPTY){
          如果(TX_Len <= 0)
             字节= 0;
          其他
             字节= TX? *TX++:0;
          mcspi_write_reg (mcspi->master、OMAP2_MCSPI_TX0、byte);
          TX_LEN --;
          无= 0;
       }

       if (l & OMAP2_MCSPI_IRQSTATUS_RX0_FULL){
          字节= mcspi_read_reg (mcspi->master、OMAP2_MCSPI_RX0);
          如果(Rx &&(Rx_len > 0))
             * Rx++=字节;
          RX_LEN --;
          无= 0;
       }
       
       /*向 OMAP2_MCSPI_IRQSTATUS 字段写入1以将其复位*/
       mcspi_write_reg (mcspi->master、OMAP2_MCSPI_IRQSTATUS、l);
       
       if (((TX_len <= 0)&&(RX_len <= 0))||无||
          (L 和 OMAP2_MCSPI_IRQSTATUS_EOW){
          /*禁用中断*/
          l = mcspi_read_reg (mcspi->master、OMAP2_MCSPI_IRQENABLE);
          L &=~(OMAP2_MCSPI_IRQENABLE_TX0_EMPTY | OMAP2_MCSPI_IRQENABLE_RX0_FULL |
               OMAP2_MCSPI_IRQENABLE_OOW);
          mcspi_WRITE_reg (mcspi->master、OMAP2_MCSPI_IRQENABLE、l);
          
          INTERRUPT_DONE = 1;
          WAKE_UP_interruptible (&omap_mcspi_wq);
       }    
       
       返回 IRQ_Handled;


    静态无符号
    OMAP2_mcspi_txrx_interrupts (struct spi_device * spi、struct spi_transfer * xfer)

       struct omap2_mcspi   *mcspi;
       u32 l;
       mcspi = SPI_MASTER_GET_DEVDATA (SPI->MASTER);

       RX_LEN = TX_LEN = xfer->Len;
       rx = xfer->rx_buf;
       TX = xfer->TX_Buf;    
       
       // CS 处于活动状态,通道处于启用状态。
       
       mcspi_WRITE_reg (mcspi->主器件、OMAP2_MCSPI_IRQSTATUS、
                        OMAP2_MCSPI_IRQSTATUS_TX0_EMPTY | OMAP2_MCSPI_IRQSTATUS_RX0_FULL |
                        OMAP2_MCSPI_IRQSTATUS_OOW);
       l = mcspi_read_reg (mcspi->master、OMAP2_MCSPI_IRQSTATUS);
       DEV_WARN (&SPI->DEV、"%s":OMAP2_MCSPI_IRQSTATUS=%x \n"、
             __function__,l);
       
       /*最后启用中断。 *
       INTERRUPT_DONE = 0;
       l = mcspi_read_reg (mcspi->master、OMAP2_MCSPI_IRQENABLE);
       L |= OMAP2_MCSPI_IRQENABLE_TX0_EMPTY | OMAP2_MCSPI_IRQENABLE_RX0_FULL;
             //|OMAP2_MCSPI_IRQENABLE_TX0_underflow;
             //| OMAP2_MCSPI_IRQENABLE_OOW;
       DEV_WARN (&SPI->DEV、"%s":OMAP2_MCSPI_IRQENABLE <-%x \n"、
             __function__,l);
       mcspi_WRITE_reg (mcspi->master、OMAP2_MCSPI_IRQENABLE、l);

       /*等待传输完成*/
       WAIT_EVENT_INTERRUPT (omap_mcspi_wq、(INTERRUPT_DONE > 0));
       DEV_WARN (&SPI->DEV、"%s":transfer_Done:TX_len=%d Rx_len=%d Rx[0]=%x\n"、
             __function__, tx_len,rx_len,rx[0]);
       
       返回 xfer->len - TX_len;



    有什么想法、为什么它不起作用? 我想没有中断发生。

    谢谢、

    L-C.

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

    是的、我使用主 SPI。

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

    我知道这个简单的代码需要同步(针对多个线程)、

    但我一次只使用一个 SPI 客户端对其进行了测试。

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

    user6230715、

    我看到您正在创建您的定制 IRQ 处理程序、OMA_mcspi_IRQ_handler。 我建议您检查和探索现有的 IRQ 处理程序 omap2_mcspi_irq_handler、并扩大其功能以处理更多的 IRQ 事件或使用 devm_request_irq()创建您自己的处理程序。

    https://patchwork.kernel.org/patch/10641191/

    当您在 IRQENABLE 寄存器中启用 McSPI 中断时、当您希望触发中断时(但不会触发)、您需要手动检查 IRQSTATUS、McSPI_TXx、McSPI_Rxx、MCSPI_CHxSTAT、MCSPI_XFERLEVEL、 MCSPI_DAFTX、MCSPI_DAFRX 寄存器。 如果这些 McSPI 寄存器(IRQSTATUS、McSPI_TXx 等)中的值指示到现在应该触发 IRQ、那么您很可能需要为此 MCSPI IRQ 配置 Cortex-A8 ARM 中断控制器。

    此致、
    帕维尔

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

    我知道 OMAP2_mcspi_IRQ_handler ()- 它在从模式下仅处理 OMAP2_MCSPI_IRQSTATUS_EOW

    (我使用主模式)

    我已经使用 devm_request_IRQ ()创建了我的处理程序、

    在论坛上打开此问题之前、我已经阅读了 OMAP2/4 mcspi 文档(bbb 使用 OMAP 4)、

    我已经在香草 Linux 和 TI Linux 中测试了代码

    这就是我发布代码示例的原因。

    您知道有人在 主控模式下测试了中断(OMAP2_MCSPI_IRQSTATUS_TX0_EMPTY、OMAP2_MCSPI_IRQSTATUS_RX0_FULL)吗?

    如果我缺少一些东西、请原谅我。

    谢谢

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

    [引用用户="user6230715"]您是否知道有人在 主控模式下测试了中断(OMAP2_MCSPI_IRQSTATUS_TX0_EMPTY、OMAP2_MCSPI_IRQSTATUS_RX0_FULL)?

    不、我不知道用于此用例的已准备好代码。

    我可以为您提供以下 e2e 线程:

    https://e2e.ti.com/support/processors/f/791/t/776784

    https://e2e.ti.com/support/processors/f/791/t/437886

    此致、
    帕维尔

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

    我在 TI 的 Vignesh 的帮助下找到了该解决方案:

    即使中断被启用(无论是否启用 FIFO)
    CPU 必须首先写入 TX_REG、以便中断到达:

    每个24.3.2.2.1 TX_EMPTY

     启用 FIFO 后、不会立即将新的 TX_EMPTY 事件置为有效
     CPU 尚未执行
     写入定义的发送器寄存器的次数
     MCSPI_XFERLEVEL[AEL]。 这是责任
     以执行正确的写入次数。

    谢谢、

    L-C 杜卡