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/AM3358:PRU 的 PWM 初始化

Guru**** 2609285 points
Other Parts Discussed in Thread: SYSCONFIG

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/653389/linux-am3358-pwm-initialization-from-pru

器件型号:AM3358
Thread 中讨论的其他器件:SysConfig

工具/软件:Linux

我们正在尝试使用 BeagleBone Black 上的 PRU 来使用 ePWM1生成 PWM。  我已经修改了 DTB 以包含引脚。

最初、PWMSS1.ePWM_TBCTL 为131、初始化后为128。 我认为这是正确的。  CTRMODE 从冻结计数变为递增计数、其他位保持不变。

此外、如果我将 PWMSS1.ePWM_TBCNT 设置为类似100的值、那么在后续读取时它永远不会改变。

我已经验证了

PWMSS1.EPQM_TBPRD、PWMSS1.ePWM_CMPA 和 PWMSS1.ePWM_CMPB 都设置为 I 设置的值。

就好像时钟不会运行一样。 详细信息如下:

      Brake _Bon_PINS:Brake _Bone_PINS{

                      pinctrl-single、pins =<

                      0x0A0 (MUX_MODE5)/* pr1_pru1_PRU_r30_0、 P8->45、调试引脚 A *

                      0x0A4 (MUX_MODE5)/* pr1_pru1_PRU_r30_1、 P8->46、调试引脚 b*/

 

                      0x0AC (MUX_MODE5)/* pr1_pru1_PRU_r30_3, P8->44,QEI 使能*/

 

                      0x0E0 (PIN_INPUT 下拉| MUX_MODE6)/* pr1_pru1_PRU_R31_8、P8->27、FAULT */

 

                      0x0D0 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* eQEP1A_IN P8->35 */

                      0x0D4 (PIN_INPUT_PULLUX | MUX_MODE2) /* eQEP1B_IN P8->33 */

                      0x0D8 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* eQEP1_INDEX        P8->31 *

                      0x0DC (PIN_INPUT_PULLDOWN | MUX_MODE2) /* eQEP1_STROBE      P8->32 *

 

                      0x0E8 (MUX_MODE5)/* pr1_pru1_PRU_r30_10、P8->28、电机触发器1 */

                      0x0E4 (MUX_MODE5)/* pr1_pru1_PRU_r30_9、 P8->29、PWM 启用 A *

                      0x0EC (MUX_MODE5)/* pr1_pru1_PRU_r30_11,P8->30,PWM 使能 B */

 

                       0x048 (PIN_OUTPUT 下拉| MUX_MODE6)/* ePWM1A、P9.14、制动电流 A *

                       0x04C (PIN_OUTPUT 下拉| MUX_MODE6)/* ePWM1B、P9.16、制动电流 B *

                      >;

          };

我将 PRU 代码基于该 GitHub 项目:

https://github.com/mhaberler/BBBIOlib/blob/master/BBBio_lib/BBBiolib_PWMSS.c

在 PRU 代码中、我有以下例程 PWM_Init 和 PWM_Enable。 我先调用 PWM_Init、然后调用 PWM_Enable (1)。 我确定周期和占空比不正确、但现在我只想在输出引脚上看到一些东西。 我捕获了一些寄存器、以便您可以看到它们的样子。 正如您看到的、我显式设置了 TBCNT、但它总是返回0 (下面的值为十进制)。 我每10ms 读取一次以下寄存器--总是具有相同的结果。

CM_PER_EPWMSS1 = 2

PWMSS1.ePWM_TBCTL = 128

PWMSS1.CLKSTATUS = 273

PWMSS1.ePWM_TBSTS = 1.

PWMSS1.ePWM_TBCNT = 0

 

void PWM_Init (void)

   /*启用 PWMSS1时钟信号生成*/

   while (!(CM_PER_EPWMSS1 & 0x2))

       CM_PER_EPWMSS1 |= 0x2;

 

   PWMSS1.SysConfig =

             (2 < 4)          //智能待机模式

           |(2 << 2);         //智能空闲模式

 

   PWMSS1.ePWM_TBCTL |= 0x3;  //冻结

 

   PWMSS1.ePWM_TBPRD = 50000;

   PWMSS1.ePWM_CMPA = 30000;

   PWMSS1.ePWM_CMPB = 20000;

 

   PWMSS1.ePWM_TBCNT = 100;

 

void PWM_Enable (bool 启用)

           if (启用)

           {

          PWMSS1.ePWM_AQCTLA =

                      (0x3 << 4)     // cmpa = set

                      |(0x2 << 0);   //零=高电平

 

          PWMSS1.ePWM_AQCTLB =

                      (0x3 << 8)     // cmpa = set

                      |(0x2 << 0);   //零=高电平

 

          PWMSS1.ePWM_TBCNT = 0;

 

          PWMSS1.ePWM_TBCTL &=~0x3;  //向上计数模式

           }

           其他

           {

          PWMSS1.ePWM_TBCTL |= 0x3;     //冻结

          PWMSS1.ePWM_AQCTLA =

                      (0x3 << 4)     // cmpa = set

                      |(0x1 << 0);   //零=强制为低电平

 

          PWMSS1.ePWM_AQCTLB =

                      (0x3 << 8)     // cmpa = set

                      |(0x1 << 0);   //零=强制为低电平

 

          PWMSS1.ePWM_TBCNT = 0;

           }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    软件团队已收到通知。 他们将在这里作出回应。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Daniel、您好!

    感谢您提供详细信息。 我将在明天开始处理您的 PWM 问题。

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

    Nick:

    还有任何反馈吗?  我们期待着解决这一问题-这已经困扰我们很长时间了,现在这个项目已经落后了。  

    Dan

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

    您的 PWM 寄存器设置似乎正常。 我将在明天回顾您的寄存器设置流程、以查看是否出现故障或缺失。

    您是否验证了 TBCNT 不能被更改(例如、如果您在 PWM_Enable 函数中将 TBCNT 设置为100而不是0、您仍然得到0?)

    您能否为我检查 ePWM_CMPCTL 寄存器的值?

    您是否已验证 PWM 时钟是否正在运行? 我认为您的 BeagleBone Black 的串行控制台具有可与 Sitara 时钟树工具(www.ti.com/.../CLOCKTREETOOL)配合使用的工具"omapconf export CTT"(请参阅 omapconf --help)

    我们可以使用 SysConfig STANDBYMODE 和 IDLEMODE (代码中当前设置为0x2)的调试值0x0或0x1来调试待机模式或空闲模式是否导致问题。

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

    看起来 PWM 时钟需要在两个位置启用:控制模块中的 PWMS_CTRL 寄存器(AM335x TRM 第9.3.1.31章)和 PWMSS CLKCONFIG。 我猜 CM_PER_EPWMSS1是 PWMSS_CTRL 寄存器-如果是、您的值是正确的。 是否设置 PWMSS CLKCONFIG?

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

    一些答案:

    我下载了最新的时钟树工具: CTT-Sitara-v1.0.0.3并安装了它。 我在 BeagleBone Black 上运行"omapconf export CTT"、并将转储行复制到.RD1类型的文件中。 当我尝试将寄存器导入时钟树工具时、我收到一个错误:文件的 Devic etype AM335x1.0不兼容

    我将 TBCNT 设置为它的值保持不变。 如果它设置为100、那么如果我读回它、它将保持为100。 我最初发布的代码在 PWM_Enable()中将其设置回零。 如果我移除该行、那么 TBCNT 将保持我在 PWM_Init()中设置的任何值

    我没有明确设置 PWMSS1.CLKCONFIG。 但是、我已经回读了 CLKSTATUS、它的十进制值为273 = 0x111 = ePWMCLK_EN、EQEPCLK_EN 和 eCAPCLK_EN、这是默认值。

    下面是我认为相关寄存器的转储(值以十进制表示):

    CM_PER_EPWMSS1 = 2

    PWMSS1.ePWM_TBCTL = 176

    PWMSS1.CLKCONFIG = 273

    PWMSS1.CLKSTATUS = 273

    PWMSS1.ePWM_TBSTS = 1.

    PWMSS1.TBCNT = 0

    PWMSS1.TBPRD = 600

    PWMSS1.CMP_A = 350

    PWMSS1.CMP_B = 200

    PWMSS1.TBPHS = 0

    PWMSS1.CMPCTL = 768

    PWMSS1.AQCTLA = 50

    PWMSS1.AQCTLB = 770

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

    Doug、您好!

    看起来是.dr1文件上的语法错误。 尝试打开.dr1文件并更改第一行、如下所示:
    DeviceName AM335x_SR2.x_SR1.0

    我通过 CTT 获得该结果、方法是依次转到 Save/Load > Save registers、然后检查  工具生成的文件的第一行。

    请告诉我、这是否允许您检查时钟树。 现在查看您的其他信息。

    Nick

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

    它允许我加载它、但我不确定要查找什么。 它确实显示了一个进入 EPWMSS1块的绿色箭头,我认为这是一件好事;-)当我运行的是2时,该寄存器(0x44E000CC)的值是2,根据数据表启用的。

    MODULEMODE 0x2 = ENABLE:模块被显式启用。 接口时钟(如果不用于函数)可根据时钟域状态进行门控。 功能时钟是保持存在的保证。 只要在此配置中、就不能进行电源域睡眠转换。

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

    您是否通过控制模块中的 pwms_ctrl 寄存器取消了 pwmss 时基时钟?

    请注意、由于写入控制模块必须具有特权、因此不能从 PRU 内核写入该寄存器。

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

    Matthijs、

    谢谢。 不,我没有。 根据手册、这将是0x44E10664。 我打印出来了、全部为零(未配置时基)。 尽管您有警告,我还是尝试通过 PRU 将其设置为“无任何可用”:-(

    那么、如何设置该寄存器呢? 我离 Linux 内核专家还很远。 我们有自己的器件树。 是否有方法在其中定义它? 我们使用的是 TI SDK。

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

    您的应用是否使用低功耗模式? 如果是、在器件树中设置 pwmss_ctrl 寄存器可能会干扰进入较低功耗模式(我仍在咨询电源团队以了解该模式)。 如果不使用低功耗模式、则应能够在器件树中设置寄存器。

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

    pwmss_ctrl 与电源管理无关。 它的存在是为了允许多个 eHRPWM 实例同时取消计时基时钟(在配置这些实例之后)、以使它们同步运行。

    如果您不关心此功能、您只需在启动时设置一次、无需再注意它们。 我不确定是否有一种巧妙的方法来实现这一点,我通常只使用/dev/mem 并通过使用 process_vm_readv ()诱使内核为我执行特权写入。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Matthijs、再次感谢。 我熟悉/dev/mem,可以编写一个简短的程序来更新寄存器,但我不熟悉 proc_vm_readv ()。 您能否提供代码片段或向我指出代码片段、这些代码片段会显示为进行特权级写入?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Doug Griswold">我熟悉/dev/mem,可以编写一个简短的程序来更新寄存器,但我不熟悉 proc_vm_readv ()。 您能否提供代码片段或向我指出代码片段、以进行特权级写入?

    #include 
    #include 
    
    template< typename T >
    void privated_write (t volatile * target、T const &value)
    {
    struct iovec dstv ={(void *) target、sizeof (T)};
    struct iovec srcv ={(void *)&value、sizeof (T)};
    if (process_vm_readv (getpid、getpid) &srcv、1、0)<0)
    裸片("process_vm_readv:%m\n");
    }