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.

AM4378芯片,使用spi1功能时,需要对复用寄存器进行设置,但是设置复用为spi模式以后,再读取发现写入的值未生效,无法写入?

Other Parts Discussed in Thread: AM4378

如题:

1、使用的芯片为am4378,

2、目前在实现spi1功能,QNX操作系统下,采用地址映射的方式操作寄存器。

3、在配置SPI1外设的pin引脚复用功能时,通过读取手册发现需要配置以下几个寄存器:

        CTRL_CONF_MCASP0_ACLKX  Register   

        CTRL_CONF_MCASP0_FSX Register 

        CTRL_CONF_MCASP0_AXR0 Register

4、在用户手册中寄存器控制章节查到对应几个寄存器的配置:可以配置bit0-bit3为spi模式

        CTRL_CONF_MCASP0_ACLKX Register   --->  可以复用为:spi1_sclk   --->    bitr0-bit3为:mode3    即:b0011   

        CTRL_CONF_MCASP0_FSX Register        --->  可以复用为:spi1_d0     --->    bitr0-bit3为:mode3    即:b0011   

        CTRL_CONF_MCASP0_AXR0 Register     --->  可以复用为:spi1_d1      --->    bitr0-bit3为:mode3    即:b0011   

如图:

5、然后问题出现了:

    (1)读取默认值,发现bit0-bit3是b0111,也就是GPIO模式;

    (2)写入b0011到bit0-bit3中,想要复用为SPI模式;

    (3)再读取该寄存器,发现写入失败,寄存器的值还是以前的b0111,并未切换成功。

跪求指点,感激不尽!!

代码如下:(备注:为了看起来简洁,把判错以及一些不相关的log代码删除了)

/* GPIO MUX */
#define AM437X_PIN_MUX_SIZE                   0x1000
#define CONTROL_MODULE_BASE                   0x44E10000
#define CTRL_STS                              ((CONTROL_MODULE_BASE) + (0x40))
#define CTRL_CONF_MCASP0_ACLKX                ((CONTROL_MODULE_BASE) + (0x990))
#define CTRL_CONF_MCASP0_FSX                  ((CONTROL_MODULE_BASE) + (0x994))
#define CTRL_CONF_MCASP0_AXR0                 ((CONTROL_MODULE_BASE) + (0x998))


typedef struct {
    am437x_reg sts;
    am437x_reg conf_mcasp0_aclkx;
    am437x_reg conf_mcasp0_fsx;
    am437x_reg conf_mcasp0_axr0;
} am437x_pin_mux;

void spi_pin_mux_init(am437x_pin_mux *spi_pin)
{
    /* pin mux io map */
    DEBUG_INFO("----pin mux iomap start.-----------\r\n");
    spi_pin->conf_mcasp0_aclkx.vaddr = mmap_device_io(AM437X_PIN_MUX_SIZE, CTRL_CONF_MCASP0_ACLKX);
    spi_pin->conf_mcasp0_fsx.vaddr   = mmap_device_io(AM437X_PIN_MUX_SIZE, CTRL_CONF_MCASP0_FSX);
    spi_pin->conf_mcasp0_axr0.vaddr  = mmap_device_io(AM437X_PIN_MUX_SIZE, CTRL_CONF_MCASP0_AXR0);

    /* pin mux */
    /* 1. spi1_sclk */
    DEBUG_INFO("reg value = 0x%8x\r\n", in32(spi_pin->conf_mcasp0_aclkx.vaddr));
    spi_pin->conf_mcasp0_aclkx.value.all = in32(spi_pin->conf_mcasp0_aclkx.vaddr);
    spi_pin->conf_mcasp0_aclkx.value.bit.bit0 = 1;
    spi_pin->conf_mcasp0_aclkx.value.bit.bit1 = 1;
    spi_pin->conf_mcasp0_aclkx.value.bit.bit2 = 0;
    spi_pin->conf_mcasp0_aclkx.value.bit.bit3 = 0;
    out32(spi_pin->conf_mcasp0_aclkx.vaddr, spi_pin->conf_mcasp0_aclkx.value.all);
    DEBUG_INFO("value     = 0x%8x\r\n", spi_pin->conf_mcasp0_aclkx.value.all);
    DEBUG_INFO("reg value = 0x%8x\r\n", in32(spi_pin->conf_mcasp0_aclkx.vaddr));

    /* 2. spi1_d0 */
    DEBUG_INFO("reg value = 0x%8x\r\n", in32(spi_pin->conf_mcasp0_fsx.vaddr));
    spi_pin->conf_mcasp0_fsx.value.all = in32(spi_pin->conf_mcasp0_fsx.vaddr);
    spi_pin->conf_mcasp0_fsx.value.bit.bit0 = 1;
    spi_pin->conf_mcasp0_fsx.value.bit.bit1 = 1;
    spi_pin->conf_mcasp0_fsx.value.bit.bit2 = 0;
    spi_pin->conf_mcasp0_fsx.value.bit.bit3 = 0;
    out32(spi_pin->conf_mcasp0_fsx.vaddr, spi_pin->conf_mcasp0_fsx.value.all);
    DEBUG_INFO("value     = 0x%8x\r\n", spi_pin->conf_mcasp0_fsx.value.all);
    DEBUG_INFO("reg value = 0x%8x\r\n", in32(spi_pin->conf_mcasp0_fsx.vaddr));

    /* 3. spi1_d1 */
    DEBUG_INFO("reg value = 0x%8x\r\n", in32(spi_pin->conf_mcasp0_axr0.vaddr));
    spi_pin->conf_mcasp0_axr0.value.all = in32(spi_pin->conf_mcasp0_axr0.vaddr);
    spi_pin->conf_mcasp0_axr0.value.bit.bit0 = 1;
    spi_pin->conf_mcasp0_axr0.value.bit.bit1 = 1;
    spi_pin->conf_mcasp0_axr0.value.bit.bit2 = 0;
    spi_pin->conf_mcasp0_axr0.value.bit.bit3 = 0;
    out32(spi_pin->conf_mcasp0_axr0.vaddr, spi_pin->conf_mcasp0_axr0.value.all);
    DEBUG_INFO("value     = 0x%8x\r\n", spi_pin->conf_mcasp0_axr0.value.all);
    DEBUG_INFO("reg value = 0x%8x\r\n", in32(spi_pin->conf_mcasp0_axr0.vaddr));
}

打印结果如下:

reg value = 0x 8040007   --->写入前先读取一下寄存器的值
value     = 0x 8040003     --->写入的变量的值
reg value = 0x 8040007   --->写入以后再次读取寄存器的值

reg value = 0x 8040007
value     = 0x 8040003
reg value = 0x 8040007

reg value = 0x 8040007
value     = 0x 8040003
reg value = 0x 8040007

  • 请问代码是参考的哪个SDK?
    有没有试过用pinmux工具直接生成相关配置。
    www.ti.com/.../PINMUXTOOL
    以下路径下的pinmux.c的源码也可以参考:
    ti-processor-sdk-rtos-am437x\pdk_am437x_1_0_15\packages\ti\starterware\board\pinmux.c
    PINMUXModuleConfig();
  • 用pinmuxtool工具试了,生成的代码移植到我的项目中了,但是还是一样,目前情况是:复用功能寄存器写不进去,不知道为啥,写入以后,再读取,还是原始值。

    是否复用寄存器也跟时钟有关系?需要配置复用功能时钟?
  • int32_t MCSPIAppInit(mcspiAppCfgObj_t *pCfgMcspi)

    {

       int32_t status = S_PASS;

       /* Clock Configuration. */

       status = PRCMModuleEnable(CHIPDB_MOD_ID_MCSPI, pCfgMcspi->instNum, 0U);

       if (S_PASS != status)

       {

           CONSOLEUtilsPrintf("\n Clock Configuration failed !\n");

       }

       else

       {

           /* Perform the MCSPI pinmux. */

           status = PINMUXModuleConfig(CHIPDB_MOD_ID_MCSPI, pCfgMcspi->instNum, NULL);

    配置一下时钟看看。

    ti-processor-sdk-rtos-am437xpdk_am437x_1_0_15\packages\ti\starterware\examples\mcspi

    PRCMModuleEnable()请参考ti-processor-sdk-rtos-am437xpdk_am437x_1_0_15\packages\ti\starterware\soc\am43xx\am43xx_prcm.c

  • 对了,昨天忘了说,我在第7章 Control Module的7.1 Introduction小节看到有这么一句描述:

    Note: For writing to the control module registers, the MPU will need to be in privileged mode of operation and writes will not work from user mode.

    意思是,我要写复用寄存器还需要先进入privileged mode吗?所以,这才是导致我写复用功能寄存器写不进去的原因吗?如果是的话,该怎么进特权模式呢?

    如图:

  • 是的,需要进入privileged mode 。
    试试看调用void CPUSwitchToPrivilegedMode(void)
    C:\ti-processor-sdk-rtos-am437x-evm-06.00.00.07-Windows\pdk_am437x_1_0_15\packages\ti\starterware\soc\armv7a\gcc\cpu.c
    Cortex-A9技术手册也可以参考看一下。
    developer.arm.com/.../h
  • CPUSwitchToPrivilegedMode()执行带有常量值1的SWI,但是SVC_Handler函数在切换到系统(特权)模式之前会查找常量458752。建议通过以下方法对此进行试验:

    在代码中调用CPUSwitchToPrivilegedMode()
    在exception vector table的SVC向量中打断点
    查看SVC向量是否调用SVC_Handler
    单步执行(asm单步执行)以查看是否跳过了切换到系统模式的操作
    如果跳过了代码,则建议更新CPUSwitchToPrivilegedMode()以调用带有常量值458752的SWI。然后重复上面概述的相同实验。

    具体查看pdk_am437x_1_0_17\packages\ti\starterware\soc\armv7a\gcc\exceptionhandler.S: