大家好
芯片是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 *********************************/