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.

[参考译文] Linux/AM4376:某些 McSPI 的 PRU 访问失败

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/669337/linux-am4376-pru-access-of-some-mcspi-fails

器件型号:AM4376

工具/软件:Linux

团队、

我的客户正在尝试从 PRU 访问 MCSPI 外设。 它们正在测试地址处的所有5个 McSPI 实例

0x4803 0000

0x481A 0000

0x481A 2000

0x481A 4000

0x4834 5000

但只有第一个可以正常工作。 如果他们从 PRU 访问其他寄存器(到目前为止只读)、他们会在 Linux 中看到访问冲突。 我不知道 Linux 甚至能够检测 PRU 访问... 根据客户、在器件树中启用所有 McSPI。 外设上电是否需要任何其他操作?

启用常规 PRU 内存访问:

              /*清除 SYSCFG[STANDBY_INIT]以启用 OCP 主端口*/

              CT_CFG.SYSCFG_BIT.STANDBY_INIT = 0;

这应允许 PRU 进入 SoC 的完整内存范围。 还是 Linux 使用硬件防火墙保护某些外设?

如果需要客户提供更多信息、请在此告知我们。

此致、

弗兰克

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

    我不知道有什么防火墙只能保护部分 McSPI 外设免受 PRU 的影响。 PRU 应该能够访问所有 McSPI。 您可以从客户那里获得这些信息吗?

    1) 1)处理器 SDK 版本/HW (如果使用 TI 板)
    2) 2)他们用于从 PRU 访问 McSPI 的代码
    3)输出误差

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

    您好、Nick、

    我们使用自己的硬件、可以通过 Linux 与 McSPI 配合使用。 我n´t、当我尝试从 PRU 访问 McSPI 时、McSPI 没有打开、我无法确定缺少什么。 错误消息(在 Linux 端)类似于

    L3自定义错误:主 ICSS0目标 L4_PER_1 (读取):在功能访问期间以用户模式访问数据

    我从相应的 McSPI 读取地址0x4硬件信息、只是为了确定我是否可以访问该接口。 第一个 MCSPI 就可以这样做、然后从 Linux 端积极使用该 MCU。

    n´t 可以通过 PRU 访问所有地址、我应该能够打开 MCSPI、但我找不到怎么做。

    此致、Annette

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

    您是否在尝试读取地址之前启用了其他 McSPI 模块的时钟? 这位于技术参考手册 McSPI 一章的"模块初始化"部分。

    此致、
    Nick
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    其他信息:
    使用 PRCM 时钟模块中的 PRCM_CM_PER_SPIN_CLKCTRL 寄存器启用时钟、其中 n = 0、1、2、3、4。

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

    您好、Nick、

    我认为时钟初始化是问题所在。 我现在有时可以通过 SPI 发送数据、但它不可靠。 您是否有一个示例代码、完整的初始化序列、可用于 PRU?

    此致、Annette

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

    您好、Nick、

    感谢你的帮助。

    我的理解是、器件树文件用于启用外设(包括时钟)。 还是需要使用低级寄存器写入来启用时钟、即使在 Linux 中也是如此?

    我不是器件树专家、我想看一个如何实现这一点的示例。

    安妮特

    您能否在此处发布您的 DTB 以便我们进行检查? 谢谢。


    弗兰克  

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

    我想知道、我们是否需要在 SPI 的器件树中设置 STATUS=DISABLED、以确保在 PRU 尝试与其通信时 Linux 内核不会与 SPI 混淆。

    我将在本周结束前在这里提供一些示例代码。

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

    您好、Annette、  

    这是我使用的测试代码。 如果我在启用时钟之前尝试从寄存器读取数据、我就能够复制您的错误。

    #include 
    #include 
    #include "resource_table_empty.h"
    
    #define PCRM_CM_per_SPI0_CLKCTRL (*(volatile unsigned int *) 0x44DF8D00)
    #define PCRM_CM_PER_SPI1_CLKCTRL (* unsigned unsigned d4dDF8int *)#define PCRM_CL0004
    
    
    
    
    
    
    (#volatile DFR_CL4)*(#volatile D4_CL0_CLINT_SPI4)*(#volatile C2000_volatile D20*(#volatile DFR_CL0_CLINT_CL0*)*#volatile D40_CLINT_CLINT_CLINT_CLINT_CLINT_CLINT_CLINT_CLINT_CLINT_CLINT_24*(#volatile #volatile D20*(#volatile D40#volatile)*(#volatile D20*)#volatile D20*(#volatile DCM_CLINT_SPI4)#volatile D40#vol
    #define McSPI3_HL_hwinfo (*(volatile unsigned int *) 0x481A4004)
    )#define McSPI4_HL_hwinfo (*(volatile unsigned int *) 0x48345004)
    
    )/*函数*/
    void init_spi ();
    void test_spi ();
    
    int main (void)
    {
    /*允许 PRU 访问 OCP 主端口、以便 PRU 可以读取外部存储器*/
    CT_CFG.SYSCFG_BIT.STANDBY_INIT = 0;
    
    /*初始化5个 McSPI */
    init_spi();
    
    /*尝试从每个 SPI 读取偏移量0x4 (HW 信息)*/
    test_spi ();
    
    }
    
    //
    * Init McSPI
    */
    void init_spi (){
    
    /*启用 SPI0的时钟:PRCM_CM_PER_SPI0_CLKCTRL *
    while (!(PCRM_CM_PER_SPI0_CLKCTRL = 0x02)){
    PCRM_CM_PER_SPI0_CLKCTRL = 0x02;
    }
    
    /*启用 SPI1的时钟:PRCM_CM_PER_SPI1_CLKCTRL *
    while (!(PCRM_CM_PER_SPI1_CLKCTRL = 0x02)){
    PCRM_CM_PER_SPI1_CLKCTRL = 0x02;
    }
    
    /*启用 SPI2的时钟:PRCM_CM_PER_SPI2_CLKCTRL *
    while (!(PCRM_CM_PER_SPI2_CLKCTRL = 0x02)){
    PCRM_CM_PER_SPI2_CLKCTRL = 0x02;
    }
    
    /*启用 SPI3的时钟:PRCM_CM_PER_SPI3_CLKCTRL *
    while (!(PCRM_CM_PER_SPI3_CLKCTRL = 0x02)){
    PCRM_CM_PER_SPI3_CLKCTRL = 0x02;
    }
    
    /*启用 SPI4的时钟:PRCM_CM_PER_SPI4_CLKCTRL *
    while (!(PCRM_CM_PER_SPI4_CLKCTRL = 0x02)){
    PCRM_CM_PER_SPI4_CLKCTRL = 0x02;
    }
    }/*
    
    
    测试是否可以读取 McSPI
    */
    void test_spi(){
    unsigned int test;
    TEST = McSPI0_HL_hwinfo;
    TEST = McSPI1_HL_hwinfo;
    TEST = McSPI2_HL_hwinfo;
    TEST = McSPI3_HL_hwinfo;
    TEST = McSPI4_HL_hwinfo;
    } 

    请告诉我、如果还有其他需要、  

    Nick

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

    我将把这个标记为"已解决"。 如果我们可以提供任何其他帮助、请发表评论!

    此致、
    Nick