📄 uart_hdl.c
字号:
/************************************************************************/
/* */
/* */
/* (C) Copyright Bangyan Information Technology Ltd, 2000/9. */
/* All right reserved */
/* */
/* Author: Zhuguosheng */
/* */
/* Description: */
/* Driver Set - SCC UART initiating specific routines. */
/* */
/* Routines */
/* */
/************************************************************************/
#include "PUB\PUB_INCL.H"
#include "DRVS\DRV860\PUB\NETCOMM.H" /* global defines */
#include "DRVS\DRV860\PUB\D860_PUB.H"
#include "DRVS\DRV860\PUB\MPC860.H" /* IMMR definitions and declarations */
#include "DRVS\DRV860\PUB\MASKS860.h" /* Global masks header file */
#include "DRVS\DRV860\UART\SCC_UART.H"
#define MAX_UART_TX_BDS 16
#define MAX_UART_RX_BDS 16
extern EPPC *quicc;
extern SCC_TABLE scc_table;
extern CONT_CHAR cc_saved[NUM_OF_SCCS][CC_MAX];
extern SI number_of_cc_saved[NUM_OF_SCCS];
extern VOID issue_cmd(UI cmd, SI scc_num);
extern VOID DrvUartRecvMsu(VOID *buf, SI length);
STATIC VOID uart_ccr(SI scc_num, SC ch);
SI uart_tx(SI scc_num, VOID *buf, SI length)
{
SI i;
register QUICC_BD *tbd, *next_tbd;
struct uart_pram *uart_pram;
/* Pointer to corresponding uart parameter ram */
uart_pram = &quicc->PRAM[scc_num].pg.scc.u;
next_tbd = tbd = scc_table[scc_num].tbd_put;
// INCREASE_TBD(next_tbd, quicc, uart_pram);
if( ((next_tbd)->status&T_W)!=0 )
(next_tbd) = TBD_ADDR(quicc,uart_pram); //Point to first BD
else
(next_tbd)++;
if( (next_tbd==scc_table[scc_num].tbd_get) || ((tbd->status&T_R)!=0) )
return -1; /* Ring full. */
tbd->length = (UI)length;
memcpy( tbd->buf, buf, length );
tbd->status &= T_W; /* Clear all except Wrap bit */
tbd->status |= T_R | T_I; /* Ready to transmittion */
scc_table[scc_num].tbd_put = next_tbd;
return 0;
}
STATIC VOID uart_rx_internal(SI scc_num)
{
register QUICC_BD *rbd;
struct uart_pram *uart_pram;
uart_pram = &quicc->PRAM[scc_num].pg.scc.u;
rbd = scc_table[scc_num].rbd;
while( (!(rbd->status&R_E))!=0 )
{
if (rbd->status & R_ERROR)
{
}
else
{
DrvUartRecvMsu(rbd->buf, rbd->length);
}
/* Reset this buffer status to be ready to next reception. */
rbd->status &= R_W;
rbd->status |= R_E | R_I;
INCREASE_RBD(rbd, quicc,uart_pram);
}
scc_table[scc_num].rbd = rbd;
}
STATIC VOID uart_tx_internal(SI scc_num)
{
register QUICC_BD *tbd;
struct uart_pram *uart_pram;
uart_pram = &quicc->PRAM[scc_num].pg.scc.u;
tbd = scc_table[scc_num].tbd_get;
while ((tbd!=scc_table[scc_num].tbd_put) && (!(tbd->status&T_R)))
{
if( (tbd->status&T_ERROR)!=0 )
{
issue_cmd(RESTART_TX,scc_num);
}
/* Reset this buffer status. */
tbd->status &= T_W; /* Clear all except Wrap bit */
INCREASE_TBD(tbd, quicc, uart_pram);
}
scc_table[scc_num].tbd_get = tbd;
}
VOID uart_interrupt(UI scc_num)
{
UI event;
struct uart_pram *uart_pram;
struct scc_regs *regs;
uart_pram = &quicc->PRAM[scc_num].pg.scc.u;
regs = &quicc->scc_regs[scc_num];
/* consider unmasked interrupts only */
event = regs->scc_scce;
event &= regs->scc_sccm;
if (event & UART_CCR)
uart_ccr(scc_num, uart_pram->rccr & 0xFF);
if (event & UART_BSY)
{
}
if (event & UART_TX)
{
uart_tx_internal(scc_num);
}
if (event & UART_RX)
{
uart_rx_internal(scc_num);
}
/*
* cleared handled event bits
*/
regs->scc_scce = event;
}
STATIC VOID uart_ccr(SI scc_num, SC ch)
{
SI i;
for (i=0; i<number_of_cc_saved[scc_num]; i++)
{
if (cc_saved[scc_num][i].reject &&
ch == cc_saved[scc_num][i].ch &&
cc_saved[scc_num][i].user_func)
{
(*cc_saved[scc_num][i].user_func)(scc_num);
break;
}
}
}
VOID uart_send_out_of_seq(SI scc_num, SC c)
{
struct uart_pram *uart_pram = &quicc->PRAM[scc_num].pg.scc.u;
uart_pram->toseq = UART_TOSEQ_REA | (c & 0xFF);
}
VOID uart_stop_transmission(SI scc_num)
{
struct scc_regs *regs = &quicc->scc_regs[scc_num];
regs->scc_psmr |= UART_PSMR_FRZ;
}
VOID uart_resume_transmission (SI scc_num)
{
struct scc_regs *regs = &quicc->scc_regs[scc_num];
regs->scc_psmr &= ~UART_PSMR_FRZ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -