📄 primecellsio.c
字号:
if ((brd < 1) || (brd > 0xFFF))
{
status = EIO; /* baud rate out of range */
break;
}
/* disable interrupts during chip access */
oldlevel = intLock ();
/* Set baud rate divisor in UART */
/*
AMBA_UART_REG_WRITE(pChan, L_UBRLCR, brd & 0xFF);
AMBA_UART_REG_WRITE(pChan, M_UBRLCR, (brd >> 8) & 0xF);
*/
brd=(pChan->xtal*10) /(arg*16);
if ((brd % 10) >= 5)
brd = (brd / 10) + 1;
else
brd /= 10;
AMBA_UART_REG_WRITE(pChan, DBGU_BRGR, brd); /*huxianpeng 20060104*/
/*
* Set word format, enable FIFOs: set 8 bits, 1 stop bit, no parity.
* This also latches the writes to the two (sub)registers above.
*/
/*
AMBA_UART_REG_WRITE(pChan, H_UBRLCR,
(UINT8)(WORD_LEN_8 | ONE_STOP | PARITY_NONE | FIFO_ENABLE));
*/
AMBA_UART_REG_WRITE(pChan, DBGU_MR,
AT91C_US_CHMODE_NORMAL | AT91C_US_PAR_NONE ); /*huxianpeng 20060104*/
pChan->baudRate = arg;
intUnlock (oldlevel);
break;
case SIO_BAUD_GET:
/* Get the baud rate and return OK */
*(int *)arg = pChan->baudRate;
break;
case SIO_MODE_SET:
/*
* Set the mode (e.g., to interrupt or polled). Return OK
* or EIO for an unknown or unsupported mode.
*/
if ((arg != SIO_MODE_POLL) && (arg != SIO_MODE_INT))
{
status = EIO;
break;
}
oldlevel = intLock ();
if (arg == SIO_MODE_INT)
{
/* Ensure that only Receive ints are generated. */
/* AMBA_UART_REG_BIT_CLR(pChan,
UARTCON,
UART_RTIE | UART_TIE |
UART_RIE | UART_MSIE );
AMBA_UART_REG_BIT_SET(pChan, UARTCON, UART_RIE | UART_RTIE);
*/
AMBA_UART_REG_WRITE(pChan, DBGU_IDR, 0xFFFFFFFF);
AMBA_UART_REG_WRITE(pChan, DBGU_IER, 0x0);
AMBA_UART_REG_BIT_SET(pChan, DBGU_IER, (DBGU_IER_RXRDY/*|DBGU_IER_TXRDY*/)); /*huxianpeng 20060108*/
AMBA_UART_REG_BIT_CLR(pChan, DBGU_IDR, (DBGU_IER_RXRDY/*|DBGU_IER_TXRDY*/));
/* Enable appropriate interrupts. */
/*intEnable (pChan->levelRx); */
/*
* There is no point in enabling the Tx interrupt, as it
* will interrupt immediately and be disabled.
*/
}
else
{
/* Disable all interrupts for this UART. */
/*intDisable (pChan->levelRx);*/
if (pChan->levelTx != pChan->levelRx)
{
/*intDisable (pChan->levelTx);*/
}
/* AMBA_UART_REG_BIT_CLR(pChan,
UARTCON,
UART_RTIE | UART_TIE |
UART_RIE | UART_MSIE );
*/
AMBA_UART_REG_WRITE(pChan, DBGU_IDR, 0xFFFFFFFF);
AMBA_UART_REG_WRITE(pChan, DBGU_IER, 0x0);
/*
AMBA_UART_REG_BIT_SET(pChan, DBGU_IDR, (DBGU_IER_RXRDY|DBGU_IER_TXRDY));
AMBA_UART_REG_BIT_CLR(pChan, DBGU_IER, (DBGU_IER_RXRDY|DBGU_IER_TXRDY));
*/
}
pChan->channelMode = arg;
intUnlock (oldlevel);
break;
case SIO_MODE_GET:
/* Get the current mode and return OK */
*(int *)arg = pChan->channelMode;
break;
case SIO_AVAIL_MODES_GET:
/* Get the available modes and return OK */
*(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;
break;
case SIO_HW_OPTS_SET:
/*
* Optional command to set the hardware options (as defined
* in sioLib.h).
* Return OK, or ENOSYS if this command is not implemented.
* Note: several hardware options are specified at once.
* This routine should set as many as it can and then return
* OK. The SIO_HW_OPTS_GET is used to find out which options
* were actually set.
*/
/*
oldlevel = intLock ();
AMBA_UART_REG_WRITE(pChan, DBGU_MR, arg);
intUnlock (oldlevel);
*/
case SIO_HW_OPTS_GET:
/*
* Optional command to get the hardware options (as defined
* in sioLib.h). Return OK or ENOSYS if this command is not
* implemented. Note: if this command is unimplemented, it
* will be assumed that the driver options are CREAD | CS8
* (e.g., eight data bits, one stop bit, no parity, ints enabled).
*/
default:
status = ENOSYS;
}
return status;
}
/*******************************************************************************
*
* primeCellSioIntTx - handle a transmitter interrupt
*
* This routine handles write interrupts from the UART.
*
* RETURNS: N/A
*/
void primeCellSioIntTx
(
AMBA_CHAN * pChan /* ptr to AMBA_CHAN describing this channel */
)
{
char outChar;
if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)
{
/* write char. to Transmit Holding Reg. */
/* AMBA_UART_REG_WRITE(pChan, UARTDR, outChar);*/
AMBA_UART_REG_WRITE(pChan, DBGU_THR, outChar);
}
else
{
/* Disable transmit interrupts. Leave receive interrupts enabled. */
/*
if (pChan->levelTx != pChan->levelRx)
intDisable (pChan->levelTx);
*/
/* AMBA_UART_REG_BIT_CLR(pChan, UARTCON, UART_TIE);*/
/* AMBA_UART_REG_BIT_SET(pChan, DBGU_IDR, DBGU_IER_TXRDY);*/
AMBA_UART_REG_WRITE(pChan, DBGU_IDR, DBGU_IER_TXRDY);
}
}
/*****************************************************************************
*
* primeCellSioIntRx - handle a receiver interrupt
*
* This routine handles read interrupts from the UART.
*
* RETURNS: N/A
*/
void primeCellSioIntRx
(
AMBA_CHAN * pChan /* ptr to AMBA_CHAN describing this channel */
)
{
char inchar;
char flags;
BOOL more_data = FALSE;
/* read characters from Receive Holding Reg. */
do
{
/* While RX FIFO isn't empty, we have more data to read */
AMBA_UART_REG_READ(pChan, UARTFLG, flags);
/* more_data = ( (flags & FLG_URXFE) == 0);*/
more_data = ( (flags & FLG_URXFE) != 0);
if (more_data)
{
/* Read from data register. */
/* AMBA_UART_REG_READ(pChan, UARTDR, inchar);*/
AMBA_UART_REG_READ(pChan, DBGU_RHR, inchar);
(*pChan->putRcvChar) (pChan->putRcvArg, inchar);
}
}
while (more_data);
}
/******************************************************************************
*
* primeCellSioInt - handle any UART interrupt
*
* This routine handles interrupts from the UART and determines whether
* the source is a transmit interrupt or receive/receive-timeout interrupt.
*
* The Prime Cell UART generates a receive interrupt when the RX FIFO is
* half-full, and a receive-timeout interrupt after 32 bit-clocks have
* elapsed with no incoming data.
*
* RETURNS: N/A
*/
void primeCellSioInt
(
AMBA_CHAN * pChan /* ptr to AMBA_CHAN describing this channel */
)
{
char intId;
char intMsk;
/* AMBA_UART_REG_READ(pChan, UARTIIR, intId);*/
AMBA_UART_REG_READ(pChan, DBGU_SR, intId);
AMBA_UART_REG_READ(pChan, DBGU_IMR, intMsk);
intId=intId&intMsk;
/* if (intId & UART_TIS)*/
if (intId & DBGU_IER_TXRDY || intId & DBGU_IER_TXBUFE )
{
primeCellSioIntTx (pChan);
}
/* if (intId & UART_RIS || intId & UART_RTIS)*/
if (intId & DBGU_IER_RXRDY || intId & DBGU_IER_RXBUFF)
{
primeCellSioIntRx (pChan);
}
/* AMBA_UART_REG_WRITE(pChan, UARTICR, intId); *//* clear interrupts */
}
/*******************************************************************************
*
* ambaTxStartup - transmitter startup routine
*
* Enable interrupt so that interrupt-level char output routine will be called.
*
* RETURNS: OK on success, ENOSYS if the device is polled-only, or
* EIO on hardware error.
*/
LOCAL int ambaTxStartup
(
SIO_CHAN * pSioChan /* ptr to SIO_CHAN describing this channel */
)
{
AMBA_CHAN * pChan = (AMBA_CHAN *)pSioChan;
if (pChan->channelMode == SIO_MODE_INT)
{
intEnable (pChan->levelTx);
/* AMBA_UART_REG_BIT_SET(pChan, UARTCON, UART_TIE);*/
AMBA_UART_REG_BIT_SET(pChan, DBGU_IER, DBGU_IER_TXRDY );
return OK;
}
else
return ENOSYS;
}
/******************************************************************************
*
* ambaPollOutput - output a character in polled mode.
*
* RETURNS: OK if a character arrived, EIO on device error, EAGAIN
* if the output buffer is full, ENOSYS if the device is interrupt-only.
*/
LOCAL int ambaPollOutput
(
SIO_CHAN * pSioChan, /* ptr to SIO_CHAN describing this channel */
char outChar /* char to output */
)
{
AMBA_CHAN * pChan = (AMBA_CHAN *)pSioChan;
FAST UINT32 pollStatus;
/* AMBA_UART_REG_READ(pChan, UARTFLG, pollStatus);*/
AMBA_UART_REG_READ(pChan, DBGU_SR, pollStatus);
/* is the transmitter ready to accept a character? */
/* if ((pollStatus & FLG_UTXFF) != 0x00)*/
if ((pollStatus & FLG_UTXFF) == 0x00)
return EAGAIN;
/* write out the character */
/* AMBA_UART_REG_WRITE(pChan, UARTDR, outChar); *//* transmit character */
AMBA_UART_REG_WRITE(pChan, DBGU_THR, outChar); /* transmit character */
return OK;
}
/******************************************************************************
*
* ambaPollInput - poll the device for input.
*
* RETURNS: OK if a character arrived, EIO on device error, EAGAIN
* if the input buffer is empty, ENOSYS if the device is interrupt-only.
*/
LOCAL int ambaPollInput
(
SIO_CHAN * pSioChan, /* ptr to SIO_CHAN describing this channel */
char * thisChar /* pointer to where to return character */
)
{
AMBA_CHAN * pChan = (AMBA_CHAN *)pSioChan;
FAST UINT32 pollStatus;
/* AMBA_UART_REG_READ(pChan, UARTFLG, pollStatus);*/
AMBA_UART_REG_READ(pChan, DBGU_SR, pollStatus);
/* if ((pollStatus & FLG_URXFE) != 0x00)*/
if ((pollStatus & FLG_URXFE) == 0x00)
return EAGAIN;
/* got a character */
/* AMBA_UART_REG_READ(pChan, UARTDR, *thisChar);*/
AMBA_UART_REG_READ(pChan, DBGU_RHR, *thisChar);
return OK;
}
/******************************************************************************
*
* ambaCallbackInstall - install ISR callbacks to get/put chars.
*
* This routine installs interrupt callbacks for transmitting characters
* and receiving characters.
*
* RETURNS: OK on success, or ENOSYS for an unsupported callback type.
*
*/
LOCAL int ambaCallbackInstall
(
SIO_CHAN * pSioChan, /* ptr to SIO_CHAN describing this channel */
int callbackType, /* type of callback */
STATUS (*callback)(), /* callback */
void * callbackArg /* parameter to callback */
)
{
AMBA_CHAN * pChan = (AMBA_CHAN *)pSioChan;
switch (callbackType)
{
case SIO_CALLBACK_GET_TX_CHAR:
pChan->getTxChar = callback;
pChan->getTxArg = callbackArg;
return OK;
case SIO_CALLBACK_PUT_RCV_CHAR:
pChan->putRcvChar = callback;
pChan->putRcvArg = callbackArg;
return OK;
default:
return ENOSYS;
}
}
void comOutputTest(
char outChar /* char to output */
)
{
#if 0
int j,k;
/* UINT32 * baseadd;*/
int * baseadd;
FAST UINT32 pollStatus;
baseadd=(int *)UART_0_BASE_ADR;
baseadd+=(DBGU_SR);
pollStatus=*((volatile UINT32 *)baseadd);
/* pollStatus=*(baseadd+DBGU_SR);*/
if ((pollStatus & FLG_UTXFF) == 0x00)
return ; /* Transmitter not ready*/
/* *(baseadd+DBGU_THR)=outChar;*/
baseadd=(int *)UART_0_BASE_ADR;
baseadd+=(DBGU_THR);
*baseadd =outChar;
for(j=0;j<1000;j++)
{
k++;
k--;
}
#else
/*
char tmp[16];
sprintf(tmp, "%c", outChar);
bootPrint(tmp);
*/
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -