查看: 2581|回复: 0

【经验分享】RT1050 LPSPI3 引脚daisy功能注意点

[复制链接]

该用户从未签到

656

主题

6312

帖子

0

超级版主

Rank: 8Rank: 8

积分
20055
最后登录
2024-4-28
发表于 2019-7-18 10:30:00 | 显示全部楼层 |阅读模式
本帖最后由 小恩GG 于 2019-7-18 10:45 编辑

【经验分享】RT1050 LPSPI3 引脚daisy功能注意点

一文档简介

      有网友在使用MIMXRT1050-EVKB板子,并且使用官方的SDK的代码运行lpspi驱动工程没有问题,但是由于客户的一些需求,需要将LPSPI3的引脚改为另外的引脚,从下面的表格可以知道RT1050 LPSPI3的相关引脚:

                                                                   1_1.jpg

网友发现从GPIO_AD_B0口修改为GPIO_AD_B1口后不能工作的问题。修改点其实也只是在pin_mux.c中修改对应的LPSPI3引脚。
      这里就以最新的RT1050SDK的代码,LPSPI工程:
SDK_2.6.1_EVKB-IMXRT1050\boards\evkbimxrt1050\driver_examples\lpspi\interrupt
为例,原代码的pin_mux.c配置的引脚为:
             Master (LPSPI3)                                                               Slave (LPSPI1)
PCS0:   GPIO_AD_B0_03_LPSPI3_PCS0                           GPIO_SD_B0_01_LPSPI1_PCS0
SCK :    GPIO_AD_B0_00_LPSPI3_SCK                             GPIO_SD_B0_00_LPSPI1_SCK
SDO:    GPIO_AD_B0_01_LPSPI3_SDO                             GPIO_SD_B0_02_LPSPI1_SDO
SDI :    GPIO_AD_B0_02_LPSPI3_SDI                               GPIO_SD_B0_03_LPSPI1_SDI
现在网友想改代码的引脚为:

             Master (LPSPI3)                                                               Slave (LPSPI1)
PCS0:   GPIO_AD_B1_12_LPSPI3_PCS0                                   GPIO_SD_B0_01_LPSPI1_PCS0
SCK :    GPIO_AD_B1_15_LPSPI3_SCK                                   GPIO_SD_B0_00_LPSPI1_SCK
SDO:    GPIO_AD_B1_14_LPSPI3_SDO                                  GPIO_SD_B0_02_LPSPI1_SDO
SDI :    GPIO_AD_B1_13_LPSPI3_SDI                                    GPIO_SD_B0_03_LPSPI1_SDI
Pinmux.c BOARD_InitPins 函数中关于SPI3的引脚代码修改为:
IOMUXC_SetPinMux(
      IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK,        /* GPIO_AD_B1_15 is configured asLPSPI3_SCK */
      0U);                                   /* SoftwareInput On Field: Input Path is determined by functionality */
  IOMUXC_SetPinMux(
      IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO,        /* GPIO_AD_B1_14 is configured asLPSPI3_SDO */
      0U);                                   /* SoftwareInput On Field: Input Path is determined by functionality */
  IOMUXC_SetPinMux(
      IOMUXC_GPIO_AD_B1_13_LPSPI3_SDI,        /* GPIO_AD_B1_13 is configured asLPSPI3_SDI */
      0U);                                    /* Software Input On Field: InputPath is determined by functionality */
  IOMUXC_SetPinMux(
      IOMUXC_GPIO_AD_B1_12_LPSPI3_PCS0,       /* GPIO_AD_B1_12 is configured asLPSPI3_PCS0 */
      0U);                                    /* SoftwareInput On Field: Input Path is determined by functionality */
  IOMUXC_SetPinConfig(
      IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK,        /* GPIO_AD_B1_15  PAD functional properties : */
      0x10B0u);                               /* Slew Rate Field:Slow Slew Rate
                                                Drive Strength Field: R0/6
                                                Speed Field: medium(100MHz)
                                                 Open Drain Enable Field: Open DrainDisabled
                                                Pull / Keep Enable Field: Pull/Keeper Enabled
                                                Pull / Keep Select Field: Keeper
                                                 Pull Up / Down Config.Field: 100K Ohm Pull Down
                                                Hyst. Enable Field: Hysteresis Disabled */
  IOMUXC_SetPinConfig(
      IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO,        /* GPIO_AD_B1_14 PAD functionalproperties : */
      0x10B0u);                               /* Slew RateField: Slow Slew Rate
                                                Drive Strength Field: R0/6
                                                Speed Field: medium(100MHz)
                                                Open Drain Enable Field: Open Drain Disabled
                                                Pull / Keep Enable Field: Pull/Keeper Enabled
                                                Pull / Keep Select Field: Keeper
                                                Pull Up / Down Config. Field: 100K Ohm Pull Down
                                                Hyst. Enable Field: Hysteresis Disabled */
  IOMUXC_SetPinConfig(
      IOMUXC_GPIO_AD_B1_13_LPSPI3_SDI,        /* GPIO_AD_B1_13 PAD functionalproperties : */
      0x10B0u);                               /* Slew RateField: Slow Slew Rate
                                                 Drive Strength Field: R0/6
                                                Speed Field: medium(100MHz)
                                                Open Drain Enable Field: Open Drain Disabled
                                                Pull / Keep Enable Field: Pull/Keeper Enabled
                                                Pull / Keep Select Field: Keeper
                                                Pull Up / Down Config. Field: 100K Ohm Pull Down
                                                 Hyst. Enable Field: HysteresisDisabled */
  IOMUXC_SetPinConfig(
      IOMUXC_GPIO_AD_B1_12_LPSPI3_PCS0,       /* GPIO_AD_B1_12 PAD functionalproperties : */
      0x10B0u);                               /* Slew RateField: Slow Slew Rate
                                                Drive Strength Field: R0/6
                                                Speed Field: medium(100MHz)
                                                Open Drain Enable Field: Open Drain Disabled
                                                 Pull/ Keep Enable Field: Pull/Keeper Enabled
                                                Pull / Keep Select Field: Keeper
                                                Pull Up / Down Config. Field: 100K Ohm Pull Down
                                                Hyst. Enable Field: Hysteresis Disabled */
代码修改之后,SPI通信失败,那么到底是什么原因导致这个问题呢?下面进行仔细分析。

二问题分析

首先从pin_mux.c代码分析, 可以看到每个SPI引脚调用两个API函数:
IOMUXC_SetPinMux IOMUXC_SetPinConfig
分析这两个函数具体功能:
static inlinevoid IOMUXC_SetPinMux(uint32_t muxRegister,
                                    uint32_tmuxMode,
                                    uint32_tinputRegister,
                                    uint32_tinputDaisy,
                                    uint32_t configRegister,
                                    uint32_tinputOnfield)
{
    *((volatile uint32_t *)muxRegister) =
        IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(muxMode)| IOMUXC_SW_MUX_CTL_PAD_SION(inputOnfield);
    if (inputRegister)
    {
        *((volatile uint32_t *)inputRegister) =inputDaisy;
    }
}
static inlinevoid IOMUXC_SetPinConfig(uint32_t muxRegister,
                                       uint32_tmuxMode,
                                       uint32_tinputRegister,
                                       uint32_tinputDaisy,
                                       uint32_tconfigRegister,
                                       uint32_tconfigValue)
{
    if (configRegister)
    {
        *((volatile uint32_t *)configRegister)= configValue;
    }
}
#defineIOMUXC_GPIO_AD_B1_15_LPSPI3_SCK 0x401F8138U, 0x2U, 0, 0, 0x401F8328U
#defineIOMUXC_GPIO_AD_B1_14_LPSPI3_SDO 0x401F8134U, 0x2U, 0x401F8518U, 0x1U,0x401F8324U
#defineIOMUXC_GPIO_AD_B1_13_LPSPI3_SDI 0x401F8130U, 0x2U, 0x401F8514U, 0x1U,0x401F8320U
#define IOMUXC_GPIO_AD_B1_12_LPSPI3_PCS00x401F812CU, 0x2U, 0x401F850CU, 0x1U, 0x401F831CU
这里以IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK为例代入API分析。
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK, 0U);      
IOMUXC_SetPinMux( 0x401F8138U, 0x2U,0, 0, 0x401F8328U,  0U);      

muxRegister  =  0x401F8138U// SW_MUX_CTL_PAD_GPIO_AD_B1_15 SW MUX Control Register 地址
muxMode      =  0x2U     //MUX模式
inputRegister =   0          //输入寄存器地址,通常有daisy的为对于daisy寄存器的地址
inputDaisy      =  0          //对应Daisy的数据
configRegister= 0x401F8328U//SW_PAD_CTL_PAD_GPIO_AD_B1_15SW PAD Control Register地址
inputOnfield   = 0U  // 输入on是否使能, 输入回环功能
对于IOMUXC_SetPinMux代码:

   *((volatile uint32_t *)muxRegister) =
    IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(muxMode) |IOMUXC_SW_MUX_CTL_PAD_SION(inputOnfield);
  if (inputRegister)
{
       *((volatile uint32_t *)inputRegister) = inputDaisy;
}

可以知道,实际上是配置MUX控制寄存器数据,以及对应输入寄存器的daisy数据。
那么这里是以IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK为例,对应的MUX控制寄存器情况如何?

1.jpg

IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK,   0x10B0u);   
IOMUXC_SetPinConfig( 0x401F8138U, 0x2U, 0, 0,0x401F8328U,    0x10B0u);

muxRegister  =  0x401F8138U// SW_MUX_CTL_PAD_GPIO_AD_B1_15 SW MUX Control Register 地址
muxMode      =  0x2U     //MUX模式
inputRegister =   0          //输入寄存器地址,通常有daisy的为对于daisy寄存器的地址
inputDaisy      =  0          //对应Daisy的数据
configRegister= 0x401F8328U//SW_PAD_CTL_PAD_GPIO_AD_B1_15SW PAD Control Register地址
configValue    =   0x10B0u//配置寄存器的值

2.jpg

3.jpg



   if (configRegister)
{
       *((volatile uint32_t *)configRegister)= configValue;
}
IOMUXC_SetPinConfig只用到配置寄存器,没有用MUX控制寄存器。
下面再来分析关于Daisy的功能,看看LPSPI3是否具有DAISY寄存器,通过查看RM,发现LPSPI3模块是有对应的DAISY寄存器的。

                                                                            4.jpg

可以发现,LPSPI3的几个引脚都是具有DAISY功能的,DAISY功能主要用于一个模块对应多个引脚的情况,这个时候需要用DAISY寄存器去确定具体是哪个引脚接到对应的模块:

5.jpg

所以需要再次查看对应新引脚的定义,是否包含了DAISY寄存器,功能是否正确。

#defineIOMUXC_GPIO_AD_B1_15_LPSPI3_SCK 0x401F8138U, 0x2U, 0, 0, 0x401F8328U
#defineIOMUXC_GPIO_AD_B1_14_LPSPI3_SDO 0x401F8134U, 0x2U, 0x401F8518U, 0x1U, 0x401F8324U
#defineIOMUXC_GPIO_AD_B1_13_LPSPI3_SDI 0x401F8130U, 0x2U, 0x401F8514U, 0x1U,0x401F8320U
#defineIOMUXC_GPIO_AD_B1_12_LPSPI3_PCS0 0x401F812CU, 0x2U, 0x401F850CU, 0x1U,0x401F831CU
可以发现,上述几个引脚,只有IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK没有定义DAISY寄存器,那么看看具体对应的SPI3 SCK引脚DAISY寄存器到底如何?

6.jpg

看到这个位置,相信大家已经明白问题出在哪里了,SDK代码里面漏定义了SPI3 SCKDAISY寄存器以及数据。

三修改内容

所以,根据第2章节的分析,可以知道,需要把SPI3 SCK的定义中添加DAISY寄存器以及数据的定义,把代码:
#defineIOMUXC_GPIO_AD_B1_15_LPSPI3_SCK 0x401F8138U, 0x2U, 0, 0, 0x401F8328U

修改为:

#defineIOMUXC_GPIO_AD_B1_15_LPSPI3_SCK 0x401F8138U, 0x2U, 0X401F8510, 0x1U,0x401F8328U
修改后,再次运行修改后的新SPI3对应引脚,可以发现SPI3模块能够正常工作。


【经验分享】RT1050 LPSPI3引脚daisy功能注意点.pdf (449.44 KB, 下载次数: 24)
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /4 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2024-4-29 00:22 , Processed in 0.110825 second(s), 20 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表