📄 16c552.c
字号:
/****************************************************************
** *
** FILE : 16C552.C *
** COPYRIGHT : (c) 2001 .Xiamen Yaxon NetWork CO.LTD *
** *
** *
** By : CCH 2005.5.28 *
****************************************************************/
#include "includes.h"
#include "bsp.h"
#include "uart_drv.h"
#include "roundbuf.h"
#include "16c552.h"
#ifndef IRQ0_INTERRUPT_PRIO
#define IRQ0_INTERRUPT_PRIO 0
#endif
#ifndef IRQ1_INTERRUPT_PRIO
#define IRQ1_INTERRUPT_PRIO 1
#endif
#define ExtUartResetPinID AT91C_PIO_P8
/*
********************************************************************************
* 定义配置参数
********************************************************************************
*/
#define frequency 1843200L /* 16C552外部晶振频率 */
#define MAX_RBUF 1024 /* 接收缓冲区大小 */
#define MAX_SBUF 1024 /* 发送缓冲区大小 */
/*
********************************************************************************
* 定义16C552寄存器
********************************************************************************
*/
#define THR RHR
#define ISR FCR
#define DLL RHR
#define DLM IER
typedef struct{
volatile INT16U RHR;
volatile INT16U IER;
volatile INT16U FCR;
volatile INT16U LCR;
volatile INT16U MCR;
volatile INT16U LSR;
volatile INT16U MSR;
volatile INT16U SPR;
}REG_16C552;
/*
********************************************************************************
* 定义UART结构
********************************************************************************
*/
typedef struct {
INT8U r_buf[MAX_RBUF]; /* 接收数据缓冲区 */
INT8U s_buf[MAX_SBUF]; /* 发送数据缓冲区 */
ROUNDBUF_STRUCT r_round; /* 接收环形缓冲区 */
ROUNDBUF_STRUCT s_round; /* 发送环形缓冲区 */
} UART;
/*
********************************************************************************
* 定义模块变量
********************************************************************************
*/
static INT8U uart_flag;
static UART uart[2];
static volatile REG_16C552 *uartreg[2] = {(REG_16C552 *)EXT_SR_CSA_BASE,(REG_16C552 *)EXT_SR_CSB_BASE};
#pragma O0
INT16S ReadExtUart(INT8U ch)
{
if (ch >= 2) return -1;
return ReadRoundBuf(&uart[ch].r_round);
}
BOOLEAN WriteExtUart(INT8U ch, INT8U c)
{
INT16S tempch;
if (ch >= 2) return false;
if (!WriteRoundBuf(&uart[ch].s_round, c)) {
return false;
}
if (uartreg[ch]->LSR & 0x20) { /* 发送缓冲区为空 */
if ((tempch = ReadRoundBuf(&uart[ch].s_round)) != -1) {
uartreg[ch]->THR = tempch;
//while((uartreg[ch]->LSR & 0x20) == 0){} //查询时打开,中断时关闭
}
}
return true;
}
BOOLEAN WriteExtUart_Block(INT8U ch, INT8U *ptr, INT8U len)
{
if (ch >= 2) return false;
if (len > LeftOfRoundBuf(&uart[ch].s_round)) return false;
for (; len > 0; len--) {
WriteExtUart(ch, *ptr++);
}
return TRUE;
}
INT16U ExtUart_ready(INT8U ch)
{
return LeftOfRoundBuf(&uart[ch].s_round);
}
static void IRQ0_handler(void)
{
INT8U i;
INT16S c;
uart_flag = uartreg[0]->ISR & 0x0e; /* 读中断标志寄存器 */
#if EN_DEBUG_BSP
//PrintFromUART(DEBUG_UARTNo_DRIV, "\nuart_flag=");
//SendFromUART_HEX(DEBUG_UARTNo_DRIV, uart_flag);
#endif
if (uart_flag == 0x04 || uart_flag == 0x0c) { /* 处理接收中断 */
for (i = 1; i <= 16; i++) {
if (uartreg[0]->LSR & 0x01) { /* 接收缓冲区存在未读数据 */
WriteRoundBuf(&uart[0].r_round, uartreg[0]->RHR);
} else {
break;
}
}
} else if (uart_flag == 0x02) { /* 处理发送中断 */
for (i = 1; i <= 16; i++) {
if (uartreg[0]->LSR & 0x20) { /* 发送缓冲区为空 */
if ((c = ReadRoundBuf(&uart[0].s_round)) != -1) {
uartreg[0]->THR = c;
} else {
break;
}
} else {
break;
}
}
}
}
static void IRQ1_handler(void)
{
INT8U i;
INT16S c;
uart_flag = uartreg[1]->ISR & 0x0e; /* 读中断标志寄存器 */
if (uart_flag == 0x04 || uart_flag == 0x0c) { /* 处理接收中断 */
for (i = 1; i <= 16; i++) {
if (uartreg[1]->LSR & 0x01) { /* 接收缓冲区存在未读数据 */
WriteRoundBuf(&uart[1].r_round, uartreg[1]->RHR);
} else {
break;
}
}
} else if (uart_flag == 0x02) { /* 处理发送中断 */
for (i = 1; i <= 16; i++) {
if (uartreg[1]->LSR & 0x20) { /* 发送缓冲区为空 */
if ((c = ReadRoundBuf(&uart[1].s_round)) != -1) {
uartreg[1]->THR = c;
} else {
break;
}
} else {
break;
}
}
}
}
void ResetExtUart(void)
{
#if EN_XR16L2552 > 0
AT91C_BASE_PIO->PIO_SODR = AT91C_PIO_P8;
AT91C_BASE_PIO->PIO_CODR = AT91C_PIO_P8;
#else
AT91C_BASE_PIO->PIO_CODR = AT91C_PIO_P8;
AT91C_BASE_PIO->PIO_SODR = AT91C_PIO_P8;
#endif
}
void InitExtUart(INT8U ch, INT16U baud)
{
INT16U *ptr;
INT8U i, temp;
if (ch >= 2) return;
AT91C_BASE_PIO->PIO_PER = AT91C_PIO_P8;
AT91C_BASE_PIO->PIO_OER = AT91C_PIO_P8;
#if EN_XR16L2552 > 0
AT91C_BASE_PIO->PIO_CODR = AT91C_PIO_P8;
#else
AT91C_BASE_PIO->PIO_SODR = AT91C_PIO_P8;
#endif
InitRoundBuf(&uart[ch].r_round, uart[ch].r_buf, sizeof(uart[ch].r_buf), 0); /* 初始化接收环形缓*/
InitRoundBuf(&uart[ch].s_round, uart[ch].s_buf, sizeof(uart[ch].s_buf), 0); /* 初始化发送环形缓*/
ptr = (INT16U *)uartreg[ch];
for (i = 1; i <= 8; i++) { /* 读16C552寄存器 */
temp = *ptr++;
}
/* 配置16C552寄存器 */
uartreg[ch]->LCR = 0x83;
uartreg[ch]->DLL = frequency / 16L / baud; /* 配置串口波特率 */
uartreg[ch]->DLM = (frequency / 16L / baud) >> 8;
uartreg[ch]->LCR = 0x03; /* 设置1位起始位,8位数据位,1位停止位,无奇偶校验码 */
uartreg[ch]->FCR = 0x87; /* 使能FIFO模式,复位接收发送FIFO,每收8个字节中断一次 */
uartreg[ch]->IER = 0x03; /* 允许接收发送中断 */
uartreg[ch]->MCR = 0x08;
#if EN_DEBUG_BSP > 0
PrintFromUART(DEBUG_UARTNo_DRIV, "\nafter write uartreg[");
SendFromUART_HEX(DEBUG_UARTNo_DRIV, ch);
PrintFromUART(DEBUG_UARTNo_DRIV, "]=");
#endif
ptr = (INT16U *)uartreg[ch];
for (i = 1; i <= 8; i++) { /* 读16C552寄存器 */
temp = *ptr++;
#if EN_DEBUG_BSP > 0
SendFromUART_HEX(DEBUG_UARTNo_DRIV, temp);
#endif
}
if (ch == 0) {
PIO_Close(AT91C_P9_IRQ0);
AIC_Install( AT91C_ID_IRQ0,IRQ0_INTERRUPT_PRIO,AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE, IRQ0_handler);
AIC_Int_Enable(AT91C_ID_IRQ0);
} else {
PIO_Close(AT91C_P10_IRQ1);
AIC_Install( AT91C_ID_IRQ1,IRQ1_INTERRUPT_PRIO,AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE, IRQ1_handler);
AIC_Int_Enable(AT91C_ID_IRQ1);
}
}
#if EN_DEBUG_BSP > 0
static INT8U temp[120];
void Poll16c552(void)
{
INT16S j;
INT16U i,usedlen;
for(j=0;j<2;j++){
usedlen = UsedOfRoundBuf(&uart[j].r_round);
if(usedlen >100) {
for(i=0;i<usedlen;i++) {
temp[i] = ReadRoundBuf(&uart[j].r_round);
}
PrintFromUART(DEBUG_UARTNo_DRIV,"\nextuartID=");
SendFromUART_HEX(DEBUG_UARTNo_DRIV, j);
PrintFromUART(DEBUG_UARTNo_DRIV,"\nrecvdatalen=");
SendFromUART_HEX(DEBUG_UARTNo_DRIV, usedlen);
PrintFromUART(DEBUG_UARTNo_DRIV,"\ndata=");
SendFromUART_MEM_HEX(DEBUG_UARTNo_DRIV, temp, usedlen);
}
}
}
static INT8U checkarray[200];
void check16c552send(void)
{
INT16U i,j;
INT8U *ptr;
InitExtUart(0, 9600);
InitExtUart(1, 9600);
for(;;) {
ptr = checkarray;
for(i=1; i<65535; i++) {
*ptr++ = i;
if(i%200 == 0) {
ClearWatchdog();
//PrintFromUART(DEBUG_UARTNo_DRIV, "\n");
//SendFromUART_MEM_HEX(DEBUG_UARTNo_DRIV, checkarray, 200);
WriteExtUart_Block(0, checkarray, 200);
WriteExtUart_Block(1, checkarray, 200);
ptr = checkarray;
for(j=65535; j>0; j--);
for(j=65535; j>0; j--);
}
ClearWatchdog();
for(j=5000; j>0; j--);
Poll16c552();
ClearWatchdog();
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -