sdc.c
来自「基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7」· C语言 代码 · 共 1,112 行 · 第 1/4 页
C
1,112 行
/* Disable interrupts */
int_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
/* Initialize the UART */
/************** Begin Port Specific Section *************/
/* Disable the receiver & transmiter */
SD_OUTBYTE (uart->base_address + SD_UCON_OFFSET, SD_UCON_DISABLE);
/* Setup Mode, Parity, Stop Bits and Data Size in ULCON Reg. */
SD_OUTBYTE (uart->base_address + SD_ULCON_OFFSET,
(uart->parity | uart->data_bits | uart->stop_bits));
/* Setup baud rate */
SDC_Set_Baud_Rate(uart->baud_rate, uart);
/* Setup vector number to be generated by UART1 */
if (uart->com_port == SD_UART1)
{
/* Enable the UART1 interrupt. */
imr_val = SD_INDWORD(INTMSK);
imr_val &= ~(SD_IMR_UART1_RX_MASK);
//imr_val &= ~(SD_IMR_UART1_TX_MASK);
imr_val &= ~(SD_IMR_MASTER_MASK);
SD_OUTDWORD (INTMSK, imr_val);
/* clear pending bit befor enable interrupt */
SD_OUTDWORD(I_ISPC, SD_IMR_UART1_TX_MASK);
}
else
{
/* Setup interrupt level of UART2, also diable autovector. */
imr_val = SD_INDWORD(INTMSK);
imr_val &= ~(SD_IMR_UART2_RX_MASK);
imr_val &= ~(SD_IMR_UART2_TX_MASK);
imr_val &= ~(SD_IMR_MASTER_MASK);
SD_OUTDWORD (INTMSK, imr_val);
}
/* Enable Tx & Rx in UCON register. */
SD_OUTBYTE (uart->base_address + SD_UCON_OFFSET,
(SD_UCON_TX_MODE_IRQ | SD_UCON_RX_MODE_IRQ));
/* Reset to IRQ mode in UFCON register (Disables FIFO Mode) */
SD_OUTBYTE (uart->base_address + SD_UFCON_OFFSET, SD_UFCON_DISABLE);
/************** End Port Specific Section *************/
/* Initialize the error counters. */
uart->parity_errors = 0;
uart->frame_errors = 0;
uart->overrun_errors = 0;
uart->busy_errors = 0;
uart->general_errors = 0;
/* Restore interrupts to previous level */
NU_Local_Control_Interrupts(int_level);
}
return (status);
} /* END SDC_Init_Port(SD_PORT *uart) */
/****************************************************************************/
/* FUNCTION */
/* */
/* SDC_Put_Char */
/* */
/* DESCRIPTION */
/* */
/* This writes a character out to the serial port. */
/* */
/* CALLED BY */
/* */
/* UART_Put_String */
/* Application */
/* */
/* CALLS */
/* */
/* Serial port macros */
/* */
/* INPUTS */
/* */
/* UNSIGNED_CHAR : Character to to be written to the serial port. */
/* SD_PORT * : Serial port to send the char to. */
/* */
/* OUTPUTS */
/* */
/* none */
/* */
/****************************************************************************/
VOID SDC_Put_Char(UNSIGNED_CHAR ch, SD_PORT *uart)
{
UNSIGNED imr_val; /* IRQ Mask register value */
if (uart->communication_mode == SERIAL_MODE)
{
/* Check the transmit buffer status. If it has data already
just add this byte to the buffer. */
if (( uart->tx_buffer_status == NU_BUFFER_DATA) ||
( uart->tx_buffer_status == NU_BUFFER_FULL) )
{
/* If the buffer is full wait for it to empty a little. */
while (uart->tx_buffer_status == NU_BUFFER_FULL)
NU_Sleep (1); /* Wait for one tick */
/* Add byte to buffer. */
uart->tx_buffer[uart->tx_buffer_write++] = ch;
/* Check for wrap of buffer. */
uart->tx_buffer_write %= uart->sd_buffer_size;
/* Check for full buffer. */
if (uart->tx_buffer_write == uart->tx_buffer_read)
uart->tx_buffer_status = NU_BUFFER_FULL;
}
else /* Otherwise send the data! */
{ /* This should be the case when Buffer_Status = Empty! */
/* Add byte to buffer. */
uart->tx_buffer[uart->tx_buffer_write++] = ch;
/* Check for wrap of buffer. */
uart->tx_buffer_write %= uart->sd_buffer_size;
/* Set status */
uart->tx_buffer_status = NU_BUFFER_DATA;
/**************** Begin Port Specific Section **************/
/* Wait until the transmitter buffer is empty by polling USTAT
** until Tx Holding Reg bit is set */
while (! (SD_INBYTE (uart->base_address + SD_USTAT_OFFSET)
& SD_USTAT_TX_EMPTY));
/* Unmask the TX interrupt in INT MASK register.
**
** NOTE: On the KS32C41000 - It appears that Tx IRQ must be enabled
** prior to stuffing the char to the Tx holding Reg or no IRQ
** is generated!
**********************************************************************/
imr_val = SD_INDWORD(INTMSK);
/* This is one of the places were we must specify which UART! */
if (uart->com_port == SD_UART1)
{
imr_val &= ~(SD_IMR_UART1_TX_MASK);
SD_OUTDWORD (INTMSK, imr_val);
}
else if (uart->com_port == SD_UART2)
{
imr_val &= ~(SD_IMR_UART2_TX_MASK);
SD_OUTDWORD (INTMSK, imr_val);
}
/* Transmit the character */
SD_OUTBYTE (uart->base_address + SD_UTXH_OFFSET, ch);
}
} /* END if (uart->communication_mode == SERIAL_MODE) */
else /* 'else' is NOT Used for SERIAL_MODE !) */
{
/* Wait until the transmitter buffer is empty by polling USTAT
** until Tx Holding Reg bit is set */
while (! (SD_INBYTE (uart->base_address + SD_USTAT_OFFSET)
& SD_USTAT_TX_EMPTY));
/* Transmit the character */
SD_OUTBYTE (uart->base_address + SD_UTXH_OFFSET, ch);
/* Not required with the KS32C41000 !
#ifndef PPP_POLLED_TX
SD_OUTBYTE (uart->base_address + SD_UIMR_OFFSET, SD_UIMR_TX_ENABLE);
#endif
*/
}
/***************** End Port Specific Section ***************/
} /* END SDC_Put_Char(UNSIGNED_CHAR ch, SD_PORT *uart) */
/****************************************************************************/
/* FUNCTION */
/* */
/* SDC_LISR */
/* */
/* DESCRIPTION */
/* */
/* This is the entry function for the ISR that services the UART. */
/* */
/* CALLED BY */
/* */
/* none */
/* */
/* CALLS */
/* */
/* Serial port macros */
/* */
/* INPUTS */
/* */
/* INT: Interrupt vector */
/* */
/***** NOTE: In the ARM ports Input will be the IRQ Pending Reg value */
/* instead an interrupt Vector. */
/* */
/* OUTPUTS */
/* */
/* none */
/* */
/****************************************************************************/
/* This is for processors that have multiple vectors:
** static VOID SDC_LISR(INT vector)
*/
VOID SDC_LISR(void)
{
/* NOTE: For the ARM Processors there is no input Vector used to determine
** which UART is interrupting! Instead the external variable
** "INTERRUPTING_DEVICE", captured in INT_IRQ, may be used to set the
** structure pointer if more than 1 UART is initialized!
**
** For the Version 1.11.1 Plus release we will use only UART 1 so the
** *uart is initialized at entry to SDC_Port_List[0].
**
** The reference code that searches the SDC_Port_List[] for a matching
** Vector has been commented out for this ARM port!
*****************************************************************************/
SD_PORT *uart = SDC_Port_List[0];
/* For multiple UARTs
** SD_PORT *uart; */
UNSIGNED imr_val;
CHAR receive;
unsigned char rx_status;
/* Default vector_found to NU_TRUE in THIS ARM Port! */
INT vector_found = NU_TRUE;
#ifdef PPP
DV_DEVICE_ENTRY *device;
#endif
/* Find the port stucture for this vector. */
/*** NOT for ARM!
receive = 0;
while ((SDC_Port_List[receive] != NU_NULL) &&
(SDC_Port_List[receive] -> vector != vector) &&
(receive < SD_MAX_UARTS) )
receive++;
***/
/* See if we found one and point our local structure to it.
** (Better have since we got an interrupt from one) */
/***
if (SDC_Port_List[receive] -> vector == vector)
{
uart = SDC_Port_List[receive];
vector_found = NU_TRUE;
}
***/
#ifdef PPP
else
{
/* 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;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?