📄 sdc.c
字号:
if(uart->com_port == SD_UART1)
{
/* Enable the UART interrupt globally */
int_val = SD_INDWORD (ILR_BASE_2 + INT_MASK_OFFSET);
int_val &= ~(UART_INT_A);
SD_OUTDWORD(ILR_BASE_2 + INT_MASK_OFFSET, int_val);
}
else /* Handle UART B */
{
/* Enable the UART interrupt globally */
int_val = SD_INDWORD (ILR_BASE_2 + INT_MASK_OFFSET);
int_val &= ~(UART_INT_B);
SD_OUTDWORD(ILR_BASE_2 + INT_MASK_OFFSET, int_val);
}
/* Set the serial port to UART mode */
SD_OUTBYTE(uart->base_address + MDR_OFFSET, MDR_UART_MODE);
}
/************** End Port Specific Section *************/
/* Initialize the error counters. */
uart->parity_errors =
uart->frame_errors =
uart->overrun_errors =
uart->busy_errors =
uart->general_errors = 0;
/* Restore interrupts to previous level */
NU_Local_Control_Interrupts(int_level);
}
return (status);
}
/***************************************************************************
* FUNCTION
*
* SDC_Put_Char
*
* DESCRIPTION
*
* This writes a character out to the serial port.
*
* INPUTS
*
* UINT8 : Character to to be written to the serial port.
* SD_PORT * : Serial port to send the char to.
*
* OUTPUTS
*
* none
*
****************************************************************************/
VOID SDC_Put_Char(UINT8 ch, SD_PORT *uart)
{
INT int_level; /* old interrupt level */
UINT32 temp_long;
#ifdef GRAFIX_MOUSE
if ((uart->communication_mode == SERIAL_MODE) ||
(uart->communication_mode == SERIAL_MOUSE))
#else
if (uart->communication_mode == SERIAL_MODE)
#endif
{
/* If the buffer is full wait for it to empty a little. */
while (uart->tx_buffer_status == NU_BUFFER_FULL);
/* Disable interrupts */
int_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
/* Check the transmit buffer status. If it has data already
just add this byte to the buffer. */
if ( uart->tx_buffer_status != NU_BUFFER_EMPTY)
{
/* Add byte to buffer. */
uart->tx_buffer[uart->tx_buffer_write++] = ch;
/* Check for wrap of buffer. */
if(uart->tx_buffer_write == uart->sd_buffer_size)
uart->tx_buffer_write = 0;
/* Check for full buffer. */
if (uart->tx_buffer_write == uart->tx_buffer_read)
uart->tx_buffer_status = NU_BUFFER_FULL;
/* Restore interrupts to previous level */
NU_Local_Control_Interrupts(int_level);
}
else
{
/* Otherwise send the data. */
/* Restore interrupts to previous level */
NU_Local_Control_Interrupts(int_level);
/* Add byte to buffer. */
uart->tx_buffer[uart->tx_buffer_write++] = ch;
/* Check for wrap of buffer. */
if(uart->tx_buffer_write == uart->sd_buffer_size)
uart->tx_buffer_write = 0;
/* Set status */
uart->tx_buffer_status = NU_BUFFER_DATA;
/**************** Begin Port Specific Section **************/
/* Wait until the transmitter buffer is empty */
while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY));
/* Transmit the character */
SD_OUTBYTE (uart->base_address + THR_OFFSET, ch);
/* Enable the TX interrupts */
temp_long = SD_INBYTE (uart->base_address + IER_OFFSET);
temp_long |= IER_TX_HOLDING_REG;
SD_OUTBYTE (uart->base_address + IER_OFFSET, temp_long);
}
} /* endif mode */
else
{
/* Wait until the transmitter buffer is empty */
while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY));
/* Transmit the character */
SD_OUTBYTE (uart->base_address + THR_OFFSET, ch);
#ifndef PPP_POLLED_TX
/* Enable the TX interrupts */
temp_long = SD_INBYTE (uart->base_address + IER_OFFSET);
temp_long |= IER_TX_HOLDING_REG;
SD_OUTBYTE (uart->base_address + IER_OFFSET, temp_long);
#endif /* PPP_POLLED_TX */
}
/***************** End Port Specific Section ***************/
}
/***************************************************************************
* FUNCTION
*
* SDC_LISR
*
* DESCRIPTION
*
* This is the entry function for the receive ISR that services the UART
* in the ARM925.
*
* INPUTS
*
* INT : Interrupt vector
*
* OUTPUTS
*
* none
*
****************************************************************************/
VOID SDC_LISR(INT vector)
{
SD_PORT *uart;
CHAR receive;
UINT8 status;
UINT8 int_status;
UINT8 vector_found = NU_FALSE;
UINT8 ier_val;
#ifdef NU_ENABLE_PPP
DV_DEVICE_ENTRY *device;
#endif /* NU_ENABLE_PPP */
for(receive = 0 ; (SDC_Port_List[receive] != NU_NULL) &&
(receive < SD_MAX_UARTS) && !vector_found ; receive++)
{
/* See if we found one. Better have since we got an interrupt
from one. */
if (SDC_Port_List[receive] -> vector == vector)
{
/* Point our local structure to it. */
uart = SDC_Port_List[receive];
vector_found = NU_TRUE;
}
}
#ifdef NU_ENABLE_PPP
/* Find the device for this interrupt */
if ( (device = DEV_Get_Dev_For_Vector(vector)) != NU_NULL)
{
/* Get the address of the uart structure for this device. */
uart = &((PPP_LAYER *) device->ppp_layer)->uart;
vector_found = NU_TRUE;
}
#endif /* NU_ENABLE_PPP */
if (vector_found == NU_TRUE)
{
/**************** Begin Port Specific Section **************/
/* Get the interrupt status register value */
int_status = SD_INBYTE(uart->base_address + IIR_OFFSET);
/* Loop until all interrupts are processed */
while (!(int_status & IIR_PENDING))
{
/* Check for a receive interrupt */
if (((int_status & IIR_RX_LINE_STAT) ==IIR_RX_LINE_STAT) ||
((int_status & IIR_RX_RDY) ==IIR_RX_RDY) ||
((int_status & IIR_RX_TIMEOUT) ==IIR_RX_TIMEOUT) )
{
/* Process every character in the receive FIFO */
status = SD_INBYTE(uart->base_address + LSR_OFFSET);
while (status & LSR_RX_DATA_READY)
{
/* Get character from receive FIFO */
receive = SD_INBYTE (uart->base_address + RHR_OFFSET);
/* Check if receive character has errors */
if (status & (LSR_FRAMING_ERROR | LSR_PARITY_ERROR))
{
/* Increment parity errors if necessary */
uart->parity_errors += ((status & LSR_PARITY_ERROR) == LSR_PARITY_ERROR);
/* Increment framing errors if necessary */
uart->frame_errors += ((status & LSR_FRAMING_ERROR) == LSR_FRAMING_ERROR);
}
else // no framing or parity errors
{
/* Increment overrun errors if necessary */
uart->overrun_errors += ((status & LSR_RX_DATA_READY) == LSR_RX_DATA_READY);
/* Switch based on UART mode */
switch(uart->communication_mode)
{
case SERIAL_MODE:
if (uart->rx_buffer_status != NU_BUFFER_FULL)
{
/* Put the character into the buffer */
uart->rx_buffer[uart->rx_buffer_write++] = receive;
/* Check for wrap of buffer. */
if(uart->rx_buffer_write == uart->sd_buffer_size)
uart->rx_buffer_write = 0;
/* Set status field based on latest character */
if (uart->rx_buffer_write == uart->rx_buffer_read)
uart->rx_buffer_status = NU_BUFFER_FULL;
else
uart->rx_buffer_status = NU_BUFFER_DATA;
}
else
uart->busy_errors++;
break;
#ifdef NU_ENABLE_PPP
/* call PPP processing functions */
case MDM_NETWORK_COMMUNICATION:
/* Call this devices receive routine */
device->dev_receive(device);
break;
case MDM_TERMINAL_COMMUNICATION:
default:
MDM_Receive(device);
break;
#endif /* NU_ENABLE_PPP */
}
}
/* Check the rx buffer status again... */
status = SD_INBYTE(uart->base_address + LSR_OFFSET);
}
} // if ((status & IIR_TYPE_MASK) == IIR_Rx_Rdy)
int_status = SD_INBYTE(uart->base_address + IER_OFFSET);
if (int_status & IER_TX_HOLDING_REG)
{
if (uart->communication_mode == SERIAL_MODE)
{
/* Bump the read pointer past the byte that was just
transmitted. */
++(uart->tx_buffer_read);
/* Check for wrap of buffer. */
if(uart->tx_buffer_read == uart->sd_buffer_size)
uart->tx_buffer_read = 0;
/* Update the status. */
if (uart->tx_buffer_write == uart->tx_buffer_read)
{
uart->tx_buffer_status = NU_BUFFER_EMPTY;
/* Since it is now empty disable the TX interrupt! */
ier_val = SD_INBYTE(uart->base_address + IER_OFFSET);
ier_val &= ~IER_TX_HOLDING_REG;
SD_OUTBYTE(uart->base_address + IER_OFFSET, ier_val);
}
else
{
/* Wait until the transmitter buffer is empty */
while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY));
/* Send the next byte in the queue. */
SD_OUTBYTE(uart->base_address + THR_OFFSET, uart->tx_buffer[uart->tx_buffer_read]);
/* Update the status. */
uart->tx_buffer_status = NU_BUFFER_DATA;
}
}
#ifdef NU_ENABLE_PPP
else
{
#ifndef PPP_POLLED_TX
/* Check for a transmit interrupt. */
/* Is there another byte in the TX buffer to send? */
if (uart->tx_buffer_read != uart->tx_buffer_write)
{
/* Wait until the transmitter buffer is empty */
while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY));
/* Send the next byte in the queue. */
SD_OUTBYTE (uart->base_address + THR_OFFSET, uart->tx_buffer[uart->tx_buffer_read++]);
/* Check for wrap of buffer. */
uart->tx_buffer_read %= uart->sd_buffer_size;
}
else
{
/* Since it is now empty disable the TX interrupt! */
ier_val = SD_INBYTE (uart->base_address + IER_OFFSET);
ier_val &= ~IER_TX_HOLDING_REG;
SD_OUTBYTE (uart->base_address + IER_OFFSET, ier_val);
/* Only activate the HISR if we are tranmitting
network data. */
if (uart->communication_mode == MDM_NETWORK_COMMUNICATION)
{
/* Add this device to the list of PPP devices that have finished
sending a packet. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -