📄 uart.c
字号:
/**************************************************************************************
*
* Project Name : S3C6410 Validation
*
* Copyright 2006 by Samsung Electronics, Inc.
* All rights reserved.
*
* Project Description :
* This software is only for validating functions of the S3C6410.
* Anybody can use this software without our permission.
*
*--------------------------------------------------------------------------------------
*
* File Name : uart.c
*
* File Description : This file implements the API functon for UART.
*
* Author : Woojin,Kim
* Dept. : AP Development Team
* Created Date : 2007/01/16
* Version : 0.1
*
* History
* - Creat debug function (InitDebug,Putc,Getc,Getkey)(Haksoo,Kim 2006/11/08)
* - Creat Full function (Woojin,Kim 2007/01/16)
*
**************************************************************************************/
#include <stdio.h>
#include "option.h"
#include "library.h"
#include "sfr6410.h"
#include "system.h"
#include "uart.h"
#include "sysc.h"
#include "gpio.h"
#include "intc.h"
#define UART_OFFSET 0x400
#define UART0_BASE (UART_REGS *)(UART_BASE)
#define UART1_BASE (UART_REGS *)(UART_BASE+UART_OFFSET)
#define UART2_BASE (UART_REGS *)(UART_BASE+UART_OFFSET*2)
#define UART3_BASE (UART_REGS *)(UART_BASE+UART_OFFSET*3)
#define UART_BUF (DefaultDownloadAddress + 0x10000)
#define FIFO_DEBUG_BUF (DefaultDownloadAddress + 0x11000)
#define TX_FIFO_RESET (1<<2)
#define RX_FIFO_RESET (1<<1)
#define TX_INT_TYPE (1<<9) // 0:pulse 1:level(6410 should be level)
#define RX_INT_TYPE (1<<8) // 0:pulse 1:level(6410 should be level)
#define RX_TIMEOUT_EN (0<<7) // 0:disable 1:enable, disable for FIFO test
#define RX_ERR_INT_EN (1<<6) // 0:disable 1:enable
#define RTS_ACTIVE (1) // In normal mode, nRTS signal 0:low, 1:High
#define BIT_UART_MODEM (1<<3)
#define BIT_UART_TXD (1<<2)
#define BIT_UART_ERROR (1<<1)
#define BIT_UART_RXD (1)
#define INT_MODE 0
#define DMA_MODE 1
#define DMA_BUF_LEN 8 // for rx
#define TX_END_CHAR NULL
#define RX_END_CHAR '\r'
typedef struct tag_UART_REGS
{
u32 rUlCon;
u32 rUCon;
u32 rUfCon;
u32 rUmCon;
u32 rUtrStat;
u32 rUerStat;
u32 rUfStat;
u32 rUmStat;
u32 rUtxh;
u32 rUrxh;
u32 rUbrDiv;
u32 rUdivSlot;
u32 rUintP;
u32 rUintSp;
u32 rUintM;
} UART_REGS;
typedef struct tag_UART_CON
{
u32 uBaudrate;
u8 cSelUartIrda; // Uart mode
u8 cLoopTest; // UCON[5] (0 : normal, 1 : LoopBack)
u8 cAfc;
u8 cEnableFifo;
u8 cOpClock; // 0,2:PCLK, 1:UEXTCLK, 2:EPLL
u8 cDataBit; // 0:5bit, 1:6bit, 2:7bit, 3:8bit
u8 cParityBit; // 0:no parity, 1:odd, 2:even, 3:forced 1, 4:forced 0
u8 cStopBit; // 0:one stopbit, 1:two stopbit
u8 cTxMode; // 0:disable, 1:interrupt or polling, 2:DMA0, 3:DMA1
u8 cTxTrig; // 0:empty, 1:16, 2:32, 3:48 (byte)
u8 cRxMode; // 0:disable, 1:interrupt or polling, 2:DMA0, 3:DMA1
u8 cRxTrig; // 0:1, 1:8, 2:16, 3:32 (byte)
u8 cRtsTrig; // 0:63, 1:56, 2:48, ... , 7:8 (byte)
u8 cSendBreakSignal; // ULCON[4] (0 : normal, 1 : Send Break Signal)
} UART_CON;
/////////
// Global variables
static UART_CON g_AUartCon[5] = {{115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}
, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}
, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}
, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}
, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}};
// control property per each channel. 4th data is defualt value for initialize
static volatile u8 g_AisTxDone[4] = {0, 0, 0, 0};
static volatile u8 g_AisRxDone[4] = {0, 0, 0, 0};
u8 *g_pUartTxStr[4];
u8 *g_pUartRxStr[4];
volatile u32 *g_pFifoDebug = (u32 *)FIFO_DEBUG_BUF; //temporary for fifo count test
volatile u32 g_uFcnt = 0;
static UART_REGS *g_pUartDebugRegs;
u32 UART_InitializeREG( UART_REGS *pUartRegs, UART_CON *pUartCon);
void UART_CalcBaudrate( UART_REGS *pUartRegs, UART_CON *pUartCon);
//////////
// Function Name : UART_InitDebugCh
// Function Description : This function initializes a certain uart ch. for debugging console
// Input : NONE
// Output : NONE
// Version :
void UART_InitDebugCh(u8 ch, u32 uBaudRate)
{
UART_Config2(ch,0,1,1,4,1,1,uBaudRate,1,1,1,1);
UART_Open(ch);
return;
}
//////////
// Function Name : UART_Putc
// Function Description : This function write character data to uart debugging ch
// Input : NONE
// Output : NONE
// Version :
void UART_Putc(char data)
{
u32 temp;
if(data=='\n')
{
while(1)
{
temp = Inp32(&g_pUartDebugRegs->rUtrStat);
temp&=0x2;
if(temp)
break;
}
Outp8(&g_pUartDebugRegs->rUtxh,'\r');
}
while(1)
{
temp = Inp32(&g_pUartDebugRegs->rUtrStat);
temp&=0x02;
if(temp)
break;
}
Outp8(&g_pUartDebugRegs->rUtxh,data);
return;
}
//////////
// Function Name : UART_Getc
// Function Description : This function read character data from uart debugging ch
// Input : NONE
// Output : temp8, character data received through uart
// Version :
s8 UART_Getc( void)
{
u32 temp32;
char temp8;
while(1)
{
temp32 = Inp32(&g_pUartDebugRegs->rUtrStat);
temp32&=0x01;
if(temp32)
break;
}
temp8 = Inp8(&g_pUartDebugRegs->rUrxh);
return temp8;
}
//////////
// Function Name : UART_GetKey
// Function Description : This function read character data from uart debugging ch if there is received data
// Input : NONE
// Output : temp8 or 0, character data received through uart or 0
// Version :
s8 UART_GetKey( void)
{
u32 temp32;
char temp8;
temp32 = Inp32(&g_pUartDebugRegs->rUtrStat);
if(temp32 & 0x1)
{
temp8 = Inp8(&g_pUartDebugRegs->rUrxh);
return temp8;
}
else
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
//////////
// Function Name : UART_Config
// Function Description : This function set up UART by user's choice
// Input : NONE
// Output : NONE
// Version : v0.1
u8 UART_Config(void)
{
u8 cCh;
s32 iNum = 0;
volatile UART_CON *pUartCon;
// Select Channel
printf("Note : [D] mark means default value. If you press ENTER key, default value is selected.\n");
printf("Select Channel(0~3) [D=0] : ");
cCh = (u8)GetIntNum();
if ( cCh>3 ) cCh = 0; // default uart 0
pUartCon = &g_AUartCon[cCh];
printf("\n\nConnect PC[COM1 or COM2] and UART%d of S3C6410 with a serial cable for test!!! \n", cCh);
//Set Other Options
printf("\nSelect Other Options\n 0. Nothing[D] 1.Send Break Signal 2. Loop Back Mode \n Choose : ");
switch(GetIntNum())
{
default :
Outp8(&pUartCon->cSendBreakSignal , 0x0);
Outp8(&pUartCon->cLoopTest , 0x0);
break;
case 1 :
Outp8(&pUartCon->cSendBreakSignal , 1);
return cCh;
case 2 :
Outp8(&pUartCon->cLoopTest , 1);
break;
}
//Set Parity mode
printf("\nSelect Parity Mode\n 1. No parity[D] 2. Odd 3. Even 4. Forced as '1' 5. Forced as '0' \n Choose : ");
switch(GetIntNum())
{
default :
Outp8(&pUartCon->cParityBit , 0);
break;
case 2 :
Outp8(&pUartCon->cParityBit , 4);
break;
case 3 :
Outp8(&pUartCon->cParityBit , 5);
break;
case 4 :
Outp8(&pUartCon->cParityBit , 6);
break;
case 5 :
Outp8(&pUartCon->cParityBit , 7);
break;
}
//Set the number of stop bit
printf("\n\nSelect Number of Stop Bit\n 1. One stop bit per frame[D] 2. Two stop bit per frame");
switch(GetIntNum())
{
default :
Outp8(&pUartCon->cStopBit , 0);
break;
case 2 :
Outp8(&pUartCon->cStopBit , 1);
break;
}
//Set Word Length
printf("\n\nSelect Word Length\n 1. 5bits 2. 6bits 3. 7bits 4. 8bits \n Choose : ");
switch(GetIntNum())
{
case 1 :
Outp8(&pUartCon->cDataBit , 0);
break;
case 2 :
Outp8(&pUartCon->cDataBit , 1);
break;
case 3 :
Outp8(&pUartCon->cDataBit , 2);
break;
default :
Outp8(&pUartCon->cDataBit , 3);
break;
}
// Set Operation clock
printf("\n\nSelect Operating Clock\n 1. PCLK[D] 2. EXT_CLK0(pwm) 3. EXT_CLK1(EPLL/MPLL) \n Choose : ");
switch (GetIntNum())
{
case 2 :
Outp8(&pUartCon->cOpClock , 1);
// connect CLKOUT and UEXTCLK
printf("\nInput PWM EXT_CLK by Pulse Generater\n");
break;
case 3 :
Outp8(&pUartCon->cOpClock , 3);
printf("\nSelect Clock SRC\n 1.EPLL 2.MPLL \n Choose: ");
switch(GetIntNum())
{
case 1:
// use EPLL output clock
//SetEPLL(42, 1, 2); // Epll output - 96MHz, pll input - 12MHz
//CLK_SRC UART_SEL[13] 0:EPLL
//CLK_DIV2 UART_RATIO[19:16]
break;
case 2:
// use MPLL output clock
//CLK_SRC UART_SEL[13] 1:MPLL
//CLK_DIV2 UART_RATIO[19:16]
break;
default:
// use EPLL output clock
//SetEPLL(42, 1, 2); // Epll output - 96MHz, pll input - 12MHz
//CLK_SRC UART_SEL[13] 0:EPLL
//CLK_DIV2 UART_RATIO[19:16]
break;
}
break;
default :
Outp8(&pUartCon->cOpClock , 0); // PCLK
break;
}
// Select UART or IrDA 1.0
printf("\n\nSelect External Interface Type\n 1. UART[D] 2. IrDA mode\n Choose : ");
if (GetIntNum() == 2)
Outp8(&pUartCon->cSelUartIrda , 1); // IrDA mode
else
Outp8(&pUartCon->cSelUartIrda , 0); // IrDA mode
// Set Baudrate
printf("\n\nType the baudrate and then change the same baudrate of host, too.\n");
printf(" Baudrate (ex 9600, 115200[D], 921600) : ");
Outp32(&pUartCon->uBaudrate , GetIntNum());
if ((s32)Inp32(&pUartCon->uBaudrate) == -1)
Outp32(&pUartCon->uBaudrate , 115200);
// Select UART operating mode
printf("\n\nSelect Operating Mode\n 1. Interrupt[D] 2. DMA\n Choose : ");
if (GetIntNum() == 2)
{
Outp8(&pUartCon->cTxMode , 2); // DMA0 mode
Outp8(&pUartCon->cRxMode , 3); // DMA1 mode
}
else
{
Outp8(&pUartCon->cTxMode , 1); // Int mode
Outp8(&pUartCon->cRxMode , 1); // Int mode
}
// Select UART FIFO mode
printf("\n\nSelect FIFO Mode (Tx/Rx[byte])\n 1. no FIFO[D] 2. Empty/1 3. 16/8 4. 32/16 5. 48/32 \n Choose : ");
iNum = GetIntNum();
if ( (iNum>1)&&(iNum<6) )
{
Outp8(&pUartCon->cEnableFifo , 1);
Outp8(&pUartCon->cTxTrig , iNum -2);
Outp8(&pUartCon->cRxTrig , iNum -2);
}
else
{
Outp8(&pUartCon->cEnableFifo , 0);
}
// Select AFC mode enable/disable
printf("\n\nSelect AFC Mode\n 1. Disable[D] 2. Enable\n Choose : ");
if (GetIntNum() == 2)
{
Outp8(&pUartCon->cAfc , 1); // AFC mode enable
printf("Select nRTS trigger level(byte)\n 1. 63[D] 2. 56 3. 48 4. 40 5. 32 6. 24 7. 16 8. 8\n Choose : ");
iNum = GetIntNum();
if ( (iNum>1)&&(iNum<9) )
Outp8(&pUartCon->cRtsTrig , iNum -1);
else
Outp8(&pUartCon->cRtsTrig , 0); // default 63 byte
}
else
{
Outp8(&pUartCon->cAfc , 0); // AFC mode disable
}
printf("SendBreakSignal=%d\n",Inp8(&pUartCon->cSendBreakSignal));
printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",Inp32(&pUartCon->uBaudrate)
,Inp8(&pUartCon->cSelUartIrda),
Inp8(&pUartCon->cLoopTest),
Inp8(&pUartCon->cAfc),
Inp8(&pUartCon->cEnableFifo),
Inp8(&pUartCon->cOpClock),
Inp8(&pUartCon->cDataBit),
Inp8(&pUartCon->cParityBit),
Inp8(&pUartCon->cStopBit),
Inp8(&pUartCon->cTxMode),
Inp8(&pUartCon->cTxTrig),
Inp8(&pUartCon->cRxMode),
Inp8(&pUartCon->cRxTrig),
Inp8(&pUartCon->cRtsTrig),
Inp8(&pUartCon->cSendBreakSignal));
return cCh;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -