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.

AM3354: 裸机操作UART, PINMUX配置失败

Part Number: AM3354

大家好

芯片是AM3354,跑裸机,想把官方例程里面的uart0程序修改为uart1,仿真时发现引脚复用寄存器配置不起作用(上电复位后芯片默认该引脚为GPIO,想把它复用成其他模式修改不了,另外我也尝试了其他引脚,也是一样),找了好久也没找到问题在哪,希望得到大家帮助,万分感谢。

代码如下:

/**
* \file uartEcho.c
*
* \brief This example application demonstrates the working of UART for serial
* communication with another device/host by echoing back the data
* entered from serial console.
*
* Application Configuration:
*
* Modules Used:
* UART1
* Interrupt Controller
*
* Configurable Parameters
* None
*
* Hard-coded configuration of other parameters:
* 1) Baud Rate - 115200 bps
* 2) Word Length - 8 bits
* 3) Parity - None
* 4) Stop Bits - 1
* 5) FIFO Threshold Levels:
* a) TX Trigger Space value - 56
* b) TX Threshold Level - 8 (TX FIFO Size - TX Trigger Space)
* c) RX Threshold Level - 1
*
* Application Use case:
* 1) Application demonstrates the Receive/Transmit features
* of UART using a FIFO.
* 2) Interrupt features related to FIFO trigger levels are
* demonstrated for reading/writing from/to the FIFO.
*
* Running the Example:
* On executing the example:
* 1) A string is displayed on the serial console of the host machine.
* 2) The user is then expected to key in data on the serial console.
* The keyed in data are immediately echoed back by the application
* and are visible on the serial console.
*
*/

/*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
*/
/*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

#include "uart_irda_cir.h"
#include "soc_AM335x.h"
#include "interrupt.h"
#include "evmAM335x.h"
#include "hw_types.h"
#include "consoleUtils.h"

#include "hw_control_AM335x.h"
//#include "uartStdio.h"
//#include "beaglebone.h"
#include "hw_cm_wkup.h"
#include "hw_cm_per.h"


#include "gpio_v2.h"
#include "pin_mux.h"

/******************************************************************************
** INTERNAL MACRO DEFINITIONS
******************************************************************************/
#define BAUD_RATE_115200 (115200)
#define UART_MODULE_INPUT_CLK (48000000)


/*
** The number of data bytes to be transmitted to Transmit FIFO of UART
** per generation of the Transmit Empty interrupt. This can take a maximum
** value of TX Trigger Space which is 'TX FIFO size - TX Threshold Level'.
*/
#define NUM_TX_BYTES_PER_TRANS (56)

/******************************************************************************
** INTERNAL FUNCTION PROTOTYPES
******************************************************************************/

static void Uart0InterruptEnable(void);
static void Uart1InterruptEnable(void);
static void UART1AINTCConfigure(void);
static void UART0AINTCConfigure(void);
static void UartFIFOConfigure(unsigned int baseAdd);
static void UartBaudRateSet(unsigned int baseAdd);
static void UART0Isr(void);
static void UART1Isr(void);
static void GPIO0ModuleClkConfig(void);
/******************************************************************************
** GLOBAL VARIABLE DEFINITIONS
******************************************************************************/

/* A string to be transmitted by UART. */
unsigned char txArray[] = "StarterWare AM335X UART Interrupt application\r\n";

/* A flag used to signify the application to transmit data to UART TX FIFO. */
unsigned int txEmptyFlag = FALSE;

/*
** A variable which holds the number of bytes of the data block transmitted to
** UART TX FIFO until the current instant.
*/
unsigned int currNumTxBytes = 0;

/******************************************************************************
** FUNCTION DEFINITIONS
******************************************************************************/
void delay(void)
{
unsigned int i;
for(i =0; i < 0x1fff; i++);
}

void UART1PinMuxSetup(unsigned int instanceNum)
{
if(1 == instanceNum)
{
/* RXD */
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_UART_RXD(1)) =
(CONTROL_CONF_UART1_RXD_CONF_UART1_RXD_PUTYPESEL |
CONTROL_CONF_UART1_RXD_CONF_UART1_RXD_RXACTIVE);

/* TXD */
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_UART_TXD(1)) =
CONTROL_CONF_UART1_TXD_CONF_UART1_TXD_PUTYPESEL;
}
}
void UART1ModuleClkConfig(void)
{
/* Configuring L3 Interface Clocks. */

/* Writing to MODULEMODE field of CM_PER_L3_CLKCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKCTRL) |=
CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE;

/* Waiting for MODULEMODE field to reflect the written value. */
while(CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKCTRL) &
CM_PER_L3_CLKCTRL_MODULEMODE));

/* Writing to MODULEMODE field of CM_PER_L3_INSTR_CLKCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_L3_INSTR_CLKCTRL) |=
CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE;

/* Waiting for MODULEMODE field to reflect the written value. */
while(CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_INSTR_CLKCTRL) &
CM_PER_L3_INSTR_CLKCTRL_MODULEMODE));

/* Writing to CLKTRCTRL field of CM_PER_L3_CLKSTCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKSTCTRL) |=
CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP;

/* Waiting for CLKTRCTRL field to reflect the written value. */
while(CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKSTCTRL) &
CM_PER_L3_CLKSTCTRL_CLKTRCTRL));

/* Writing to CLKTRCTRL field of CM_PER_OCPWP_L3_CLKSTCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) |=
CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP;

/*Waiting for CLKTRCTRL field to reflect the written value. */
while(CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=
(HWREG(SOC_CM_PER_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) &
CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL));

/* Writing to CLKTRCTRL field of CM_PER_L3S_CLKSTCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_L3S_CLKSTCTRL) |=
CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP;

/*Waiting for CLKTRCTRL field to reflect the written value. */
while(CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3S_CLKSTCTRL) &
CM_PER_L3S_CLKSTCTRL_CLKTRCTRL));

//2017.3.27 zhao
HWREG(SOC_CM_PER_REGS + CM_PER_UART1_CLKCTRL) |=
CM_PER_UART1_CLKCTRL_MODULEMODE_ENABLE;

while(CM_PER_UART1_CLKCTRL_MODULEMODE_ENABLE !=
(HWREG(SOC_CM_PER_REGS + CM_PER_UART1_CLKCTRL) &
CM_PER_UART1_CLKCTRL_MODULEMODE));

/* Checking fields for necessary values. */

/* Waiting for IDLEST field in CM_PER_L3_CLKCTRL register to be set to 0x0. */
while((CM_PER_L3_CLKCTRL_IDLEST_FUNC << CM_PER_L3_CLKCTRL_IDLEST_SHIFT)!=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKCTRL) &
CM_PER_L3_CLKCTRL_IDLEST));

/*
** Waiting for IDLEST field in CM_PER_L3_INSTR_CLKCTRL register to attain the
** desired value.
*/
while((CM_PER_L3_INSTR_CLKCTRL_IDLEST_FUNC <<
CM_PER_L3_INSTR_CLKCTRL_IDLEST_SHIFT)!=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_INSTR_CLKCTRL) &
CM_PER_L3_INSTR_CLKCTRL_IDLEST));

/*
** Waiting for CLKACTIVITY_L3_GCLK field in CM_PER_L3_CLKSTCTRL register to
** attain the desired value.
*/
while(CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKSTCTRL) &
CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK));

/*
** Waiting for CLKACTIVITY_OCPWP_L3_GCLK field in CM_PER_OCPWP_L3_CLKSTCTRL
** register to attain the desired value.
*/
while(CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_GCLK !=
(HWREG(SOC_CM_PER_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) &
CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_GCLK));

/*
** Waiting for CLKACTIVITY_L3S_GCLK field in CM_PER_L3S_CLKSTCTRL register
** to attain the desired value.
*/
while(CM_PER_L3S_CLKSTCTRL_CLKACTIVITY_L3S_GCLK !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3S_CLKSTCTRL) &
CM_PER_L3S_CLKSTCTRL_CLKACTIVITY_L3S_GCLK));

}

void Uart1Init(void)
{
/* Configuring the system clocks for UART1 instance. */
UART1ModuleClkConfig();

/* Performing the Pin Multiplexing for UART1 instance. */
UART1PinMuxSetup(1);

/* Performing a module reset. */
UARTModuleReset(SOC_UART_1_REGS);

/* Performing FIFO configurations. */
UartFIFOConfigure(SOC_UART_1_REGS);

/* Performing Baud Rate settings. */
UartBaudRateSet(SOC_UART_1_REGS);

/* Switching to Configuration Mode B. */
UARTRegConfigModeEnable(SOC_UART_1_REGS, UART_REG_CONFIG_MODE_B);

/* Programming the Line Characteristics. */
UARTLineCharacConfig(SOC_UART_1_REGS,
(UART_FRAME_WORD_LENGTH_8 | UART_FRAME_NUM_STB_1),
UART_PARITY_NONE);

/* Disabling write access to Divisor Latches. */
UARTDivisorLatchDisable(SOC_UART_1_REGS);

/* Disabling Break Control. */
UARTBreakCtl(SOC_UART_1_REGS, UART_BREAK_COND_DISABLE);

/* Switching to UART16x operating mode. */
UARTOperatingModeSelect(SOC_UART_1_REGS, UART16x_OPER_MODE);
Uart1InterruptEnable();
}

int main()
{

Uart1Init();
while(1)
{
UARTCharPut(SOC_UART_1_REGS,'E');
delay();
UARTCharPut(SOC_UART_0_REGS,'E');
delay();

}


}

/*
** A wrapper function performing FIFO configurations.
*/

static void UartFIFOConfigure(unsigned int baseAdd)
{
unsigned int fifoConfig = 0;

/*
** - Transmit Trigger Level Granularity is 4
** - Receiver Trigger Level Granularity is 1
** - Transmit FIFO Space Setting is 56. Hence TX Trigger level
** is 8 (64 - 56). The TX FIFO size is 64 bytes.
** - The Receiver Trigger Level is 1.
** - Clear the Transmit FIFO.
** - Clear the Receiver FIFO.
** - DMA Mode enabling shall happen through SCR register.
** - DMA Mode 0 is enabled. DMA Mode 0 corresponds to No
** DMA Mode. Effectively DMA Mode is disabled.
*/
fifoConfig = UART_FIFO_CONFIG(UART_TRIG_LVL_GRANULARITY_1,
UART_TRIG_LVL_GRANULARITY_1,
1,
1,
1,
1,
UART_DMA_EN_PATH_SCR,
UART_DMA_MODE_1_ENABLE);

/* fifoConfig = UART_FIFO_CONFIG(UART_TRIG_LVL_GRANULARITY_4,
UART_TRIG_LVL_GRANULARITY_1,
UART_FCR_TX_TRIG_LVL_56,
1,
1,
1,
UART_DMA_EN_PATH_SCR,
UART_DMA_MODE_0_ENABLE);*/
/* Configuring the FIFO settings. */
UARTFIFOConfig(baseAdd, fifoConfig);
}

/*
** A wrapper function performing Baud Rate settings.
*/

static void UartBaudRateSet(unsigned int baseAdd)
{
unsigned int divisorValue = 0;

/* Computing the Divisor Value. */
divisorValue = UARTDivisorValCompute(UART_MODULE_INPUT_CLK,
BAUD_RATE_115200,
UART16x_OPER_MODE,
UART_MIR_OVERSAMPLING_RATE_42);

/* Programming the Divisor Latches. */
UARTDivisorLatchWrite(baseAdd, divisorValue);
}

/*
** A wrapper function performing Interrupt configurations.
*/

static void Uart1InterruptEnable(void)
{
/* Enabling IRQ in CPSR of ARM processor. */
IntMasterIRQEnable();

/* Configuring AINTC to receive UART1 interrupts. */
UART1AINTCConfigure();

/* Enabling the specified UART interrupts. */
UARTIntEnable(SOC_UART_1_REGS, (UART_INT_LINE_STAT | UART_INT_THR |
UART_INT_RHR_CTI));
}

/*
** Interrupt Service Routine for UART.
*/

static void UART1Isr(void)
{
unsigned int rxErrorType = 0;
unsigned char rxByte = 0;
unsigned int intId = 0;
unsigned int idx = 0;

/* Checking ths source of UART interrupt. */
intId = UARTIntIdentityGet(SOC_UART_1_REGS);

switch(intId)
{
case UART_INTID_TX_THRES_REACH:

/*
** Checking if the entire transmisssion is complete. If this
** condition fails, then the entire transmission has been completed.
*/
if(currNumTxBytes < (sizeof(txArray) - 1))
{
txEmptyFlag = TRUE;
}

/*
** Disable the THR interrupt. This has to be done even if the
** transmission is not complete so as to prevent the Transmit
** empty interrupt to be continuously generated.
*/
UARTIntDisable(SOC_UART_1_REGS, UART_INT_THR);

break;

case UART_INTID_RX_THRES_REACH:
rxByte = UARTCharGetNonBlocking(SOC_UART_1_REGS);
UARTCharPutNonBlocking(SOC_UART_1_REGS, rxByte);
break;

case UART_INTID_RX_LINE_STAT_ERROR:

rxErrorType = UARTRxErrorGet(SOC_UART_1_REGS);

/* Check if Overrun Error has occured. */
if(rxErrorType & UART_LSR_RX_OE)
{
// ConsoleUtilsPrintf("\r\nUART Overrun Error occured."
// " Reading and Echoing all data in RX FIFO.\r\n");

/* Read the entire RX FIFO and the data in RX Shift register. */
for(idx = 0; idx < (RX_FIFO_SIZE + 1); idx++)
{
rxByte = UARTFIFOCharGet(SOC_UART_1_REGS);
UARTFIFOCharPut(SOC_UART_1_REGS, rxByte);
}

break;
}

/* Check if Break Condition has occured. */
else if(rxErrorType & UART_LSR_RX_BI)
{
// ConsoleUtilsPrintf("\r\nUART Break Condition occured.");
}

/* Check if Framing Error has occured. */
else if(rxErrorType & UART_LSR_RX_FE)
{
// ConsoleUtilsPrintf("\r\nUART Framing Error occured.");
}

/* Check if Parity Error has occured. */
else if(rxErrorType & UART_LSR_RX_PE)
{
// ConsoleUtilsPrintf("\r\nUART Parity Error occured.");
}

// ConsoleUtilsPrintf(" Data at the top of RX FIFO is: ");
rxByte = UARTFIFOCharGet(SOC_UART_1_REGS);
UARTFIFOCharPut(SOC_UART_1_REGS, rxByte);

break;

case UART_INTID_CHAR_TIMEOUT:

// ConsoleUtilsPrintf("\r\nUART Character Timeout Interrupt occured."
// " Reading and Echoing all data in RX FIFO.\r\n");

/* Read all the data in RX FIFO. */
while(TRUE == UARTCharsAvail(SOC_UART_1_REGS))
{
rxByte = UARTFIFOCharGet(SOC_UART_1_REGS);
UARTFIFOCharPut(SOC_UART_1_REGS, rxByte);
}

break;

default:
break;
}

}

/*
** This function configures the AINTC to receive UART interrupts.
*/

static void UART1AINTCConfigure(void)
{
/* Initializing the ARM Interrupt Controller. */
IntAINTCInit();

/* Registering the Interrupt Service Routine(ISR). */
IntRegister(SYS_INT_UART1INT, UART1Isr);

/* Setting the priority for the system interrupt in AINTC. */
IntPrioritySet(SYS_INT_UART1INT, 0, AINTC_HOSTINT_ROUTE_IRQ);

/* Enabling the system interrupt in AINTC. */
IntSystemEnable(SYS_INT_UART1INT);
}


/******************************* End of file *********************************/

  • 请问您是修改的哪个例程,请贴出具体路径。

    pinmux部分可配合使用pinmux tool进行配置。

    https://www.ti.com/tool/PINMUXTOOL

    基于最新的processor sdk有相关文档说明替换新的pinmux配置,也可参考看一下:

    software-dl.ti.com/.../index_board.html

  • 您好,感谢回复,我修改的是官方例程库 AM335X_StarterWare_02_00_01_01\examples\evmAM335x\uart路径下的uart程序,官方提供的程序为uart0,我需要使用的是uart1,现在主要的问题是引脚复用寄存器配置不能成功,不管怎么配置,寄存器的值都不会改变,其他部分完全不变,只修改官方历程uart0的引脚复用功能函数,寄存器的值接不会改变,现在我使用的配置方式如下:

    void UART1PinMuxSetup(unsigned int instanceNum)  //uart1 引脚复用功能配置。
    {
    if(1 == instanceNum)
    {
    /* RXD */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_UART_RXD(1)) =
    (CONTROL_CONF_UART1_RXD_CONF_UART1_RXD_PUTYPESEL |
    CONTROL_CONF_UART1_RXD_CONF_UART1_RXD_RXACTIVE);

    /* TXD */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_UART_TXD(1)) =
    CONTROL_CONF_UART1_TXD_CONF_UART1_TXD_PUTYPESEL;
    }

    理论上调用该函数后conf_uart1_rxd 和 conf_uart1_txd的最后3bit数据会变成0b000,但实际仿真发现寄存器的值并没有改变,还是上电默认的初始值。其他引脚的复用寄存器配置也是一样,不管怎么配置,寄存器的值并不会改变。是不是配置该寄存器之前还需要配置其他寄存器?希望得到您的解答,万分感谢!!!

  • UART1 module clock是否有使能?

  • 时钟已经使能,我查了下资料, 应该是芯片需要进入 privileged mode才能配置该寄存器,但是CCS提供的libc.a库初始化时默认把芯片配置成user mode了,现在需要解决的问题是怎么把芯片从user mode切换到privileged mode,直接使用cpu.c文件下的CPUSwitchToPrivilegedMode函数切换模式程序会跑飞

  • 想起来之前碰到过跟您类似的问题,并且在英文论坛讨论过,您可以先参考看一下:

    e2e.ti.com/.../3478247

  • 您好,我看到另外一个回答,e2echina.ti.com/support/processors/f/processors-forum/103332/omap138-arm, 您帮忙看一下,  现在的问题是在CCS1020版本下怎么配置才能让程序从文中所说的Entry函数启动,按照文中所提的方式配置程序会报错。

  • 请问添加了哪些配置?具体是什么报错?

  • 使用模板工程重新配置后问题解决了,应该是之前不小心改动到其他配置信息, 非常感谢您的耐心解答

  • 好的,感谢分享,我会将此贴关闭。