[分享] RT1050 LPSPI3 引脚daisy功能注意点
516 查看
1 回复
 楼主 | 发布于 2020-09-17 | 只看楼主
分享到:
一文档简介

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

                                                                  

网友发现从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控制寄存器情况如何?


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//配置寄存器的值





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

                                                                           

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


所以需要再次查看对应新引脚的定义,是否包含了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寄存器到底如何?


看到这个位置,相信大家已经明白问题出在哪里了,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模块能够正常工作。

本帖有更多资源,需 登录 才可以下载,没有帐号?立即 注册

(0 ) (0 )
回复 举报

回复于 2020-09-17 沙发

感谢分享
(0 )
评论 (0) 举报
  • 发表回复
    0/3000





    举报

    请选择举报类别

    • 广告垃圾
    • 违规内容
    • 恶意灌水
    • 重复发帖

    全部板块

    返回顶部