TI中文支持网
TI专业的中文技术问题咨询交流网站

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

如题:

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_SIZE0x1000
#define CONTROL_MODULE_BASE0x44E10000
#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

Nancy Wang:

请问代码是参考的哪个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();

user6090244:

回复 Nancy Wang:

用pinmuxtool工具试了,生成的代码移植到我的项目中了,但是还是一样,目前情况是:复用功能寄存器写不进去,不知道为啥,写入以后,再读取,还是原始值。

是否复用寄存器也跟时钟有关系?需要配置复用功能时钟?

Nancy Wang:

回复 user6090244:

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

user6090244:

回复 Nancy Wang:

对了,昨天忘了说,我在第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吗?所以,这才是导致我写复用功能寄存器写不进去的原因吗?如果是的话,该怎么进特权模式呢?

如图:

Nancy Wang:

回复 user6090244:

是的,需要进入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

Nancy Wang:

回复 user6090244:

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:

赞(0)
未经允许不得转载:TI中文支持网 » AM4378芯片,使用spi1功能时,需要对复用寄存器进行设置,但是设置复用为spi模式以后,再读取发现写入的值未生效,无法写入?
分享到: 更多 (0)