?? uart.c
字號:
#if ((CHIPSET != 5) && (CHIPSET != 6))
/*
* Enable sleep mode.
*/
WRITE_UART_REGISTER (uart, IER, IER_SLEEP);
#endif
}
/*******************************************************************************
*
* UA_Init
*
* Purpose : Initializes the module and the UART.
*
* Arguments: In : uart_id : UART id.
* baudrate: baud rate selected.
* callback: user's function called characters are received.
* Out: none
*
* Returns: none
*
* Warning: Parameters are not verified.
*
******************************************************************************/
void
UA_Init (T_tr_UartId uart_id,
T_tr_Baudrate baudrate,
void (callback_function (void)))
{
t_uart *uart;
int index;
for (index = 0; index < NUMBER_OF_TR_UART; index++)
uart_parameter[index].base_address = base_address[index];
uart = &(uart_parameter[uart_id]);
uart->rx_in = &(uart->rx_buffer[0]);
uart->rx_out = &(uart->rx_buffer[0]);
uart->callback_function = callback_function;
uart->framing_error = 0;
uart->parity_error = 0;
uart->overrun_error = 0;
uart->dle_detected = 0;
uart->inframe = 0;
uart->encapsulation_flag = 0;
uart->frame_length = 0;
/*
* Mask all interrupts causes and disable sleep mode.
*/
WRITE_UART_REGISTER (uart, IER, 0x00);
/*
* Reset UART mode configuration.
*/
WRITE_UART_REGISTER (uart, MDR1, RESET_DEFAULT_STATE |
IR_SLEEP_DISABLED |
SIR_TX_WITHOUT_ACREG2 |
FRAME_LENGTH_METHOD);
/*
* FIFO configuration.
* EFR[4] = 1 to allow to program FCR[5:4] and MCR[7:5].
*/
WRITE_UART_REGISTER (uart, LCR, 0xBF);
SET_BIT (uart, EFR, ENHANCED_FEATURE_BIT);
/*
* Select the word length, the number of stop bits , the parity and set
* LCR[7] (DLAB) to allow to program FCR, DLL and DLM.
*/
WRITE_UART_REGISTER (uart, LCR, WLS_8 | DLAB);
/*
* Program the trigger levels.
* MCR[6] must be set to 1.
*/
SET_BIT (uart, MCR, TCR_TLR_BIT);
WRITE_UART_REGISTER (uart, TCR, 0x0F);
WRITE_UART_REGISTER (
uart, TLR, RX_FIFO_TRIGGER_LEVEL);
/*
* Program the FIFO control register. Bit 0 must be set when other FCR bits
* are written to or they are not programmed.
* FCR is a write-only register. It will not be modified.
*/
WRITE_UART_REGISTER (uart, FCR, FIFO_ENABLE |
RX_FIFO_RESET | /* self cleared */
TX_FIFO_RESET); /* self cleared */
/*
* Program the baud generator.
*/
WRITE_UART_REGISTER (uart, DLL, dll[baudrate]);
WRITE_UART_REGISTER (uart, DLM, dlh[baudrate]);
/*
* Reset LCR[7] (DLAB) to have access to the RBR, THR and IER registers.
*/
WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
/*
* Select UART mode.
*/
WRITE_UART_REGISTER (uart, MDR1, UART_MODE |
IR_SLEEP_DISABLED |
SIR_TX_WITHOUT_ACREG2 |
FRAME_LENGTH_METHOD);
#if ((CHIPSET == 5) || (CHIPSET == 6))
/*
* Unmask RX interrupt
*/
WRITE_UART_REGISTER (uart, IER, ERBI);
#else
/*
* Unmask RX interrupt and allow sleep mode.
*/
WRITE_UART_REGISTER (uart, IER, ERBI | IER_SLEEP);
#endif
}
/*******************************************************************************
*
* UA_ReadNChars
*
* Purpose : Reads N characters from the RX buffer.
*
* Arguments: In : uart_id : UART id.
* buffer : buffer address where the characters are
* copied.
* chars_to_read: number of characters to read.
* Out: none
*
* Returns : The number of characters read.
*
* Warning: Parameters are not verified.
*
******************************************************************************/
SYS_UWORD32
UA_ReadNChars (T_tr_UartId uart_id,
char *buffer,
SYS_UWORD32 chars_to_read)
{
SYS_UWORD32 chars_in_rx_buffer;
SYS_UWORD32 chars_to_copy;
SYS_UWORD32 chars_written;
char *rx_in;
t_uart *uart;
uart = &(uart_parameter[uart_id]);
/*
* A copy of the rx_in pointer is used because it may be updated by
* the interrupt handler.
* Get the number of bytes available in the RX buffer.
*/
rx_in = uart->rx_in;
if (uart->rx_out <= rx_in)
chars_in_rx_buffer = (SYS_UWORD32) (rx_in - uart->rx_out);
else
chars_in_rx_buffer = (SYS_UWORD32) (rx_in - uart->rx_out + BUFFER_SIZE + 1);
/*
* No more bytes than those received may be written in the output buffer.
*/
if (chars_in_rx_buffer >= chars_to_read)
chars_to_copy = chars_to_read;
else
chars_to_copy = chars_in_rx_buffer;
chars_written = chars_to_copy;
/*
* Write the received bytes in the output buffer.
*/
while (chars_to_copy) {
*(buffer++) = *(uart->rx_out++);
chars_to_copy--;
if (uart->rx_out == &(uart->rx_buffer[0]) + BUFFER_SIZE + 1)
uart->rx_out = &(uart->rx_buffer[0]);
}
return (chars_written);
}
/*******************************************************************************
*
* UA_ReadNBytes
*
* Purpose : Reads and destuff N bytes from the RX buffer.
*
* Arguments: In : uart_id : UART id.
* buffer : buffer address where the bytes are copied.
* chars_to_read: number of bytes to read.
* Out: eof_detected : indicates if an EOF has been detected.
*
* Returns : The number of bytes read.
*
* Warning: Parameters are not verified.
*
******************************************************************************/
SYS_UWORD32
UA_ReadNBytes (T_tr_UartId uart_id,
char *buffer,
SYS_UWORD32 bytes_to_read,
SYS_BOOL *eof_detected)
{
SYS_UWORD32 bytes_in_rx_buffer;
SYS_UWORD32 bytes_to_process;
SYS_UWORD32 bytes_written;
char *rx_in;
t_uart *uart;
bytes_written = 0;
uart = &(uart_parameter[uart_id]);
/*
* A copy of the rx_in pointer is used because it may be updated by
* the interrupt handler.
* Get the number of bytes available in the RX buffer.
*/
rx_in = uart->rx_in;
if (uart->rx_out <= rx_in)
bytes_in_rx_buffer = (SYS_UWORD32) (rx_in - uart->rx_out);
else
bytes_in_rx_buffer = (SYS_UWORD32) (rx_in - uart->rx_out + BUFFER_SIZE + 1);
/*
* No more bytes than those received may be processed and then written in
* the output buffer.
*/
if (bytes_in_rx_buffer >= bytes_to_read)
bytes_to_process = bytes_to_read;
else
bytes_to_process = bytes_in_rx_buffer;
/*
* Perform the byte destuffing and then write the "valid" received bytes in
* the output buffer.
*/
while ((bytes_to_process) && !(*eof_detected)) {
switch (*(uart->rx_out)) {
/*
* Current byte is DLE.
*/
case DLE:
if (!uart->dle_detected) {
/*
* No DLE previously detected =>
* Skip the current byte and set the flag.
*/
uart->dle_detected = 1;
bytes_to_process--;
uart->rx_out++;
}
else { /* if (uart->dle_detected) */
if (uart->inframe) {
/*
* DLE previously detected AND currently inside of a frame =>
* Copy the current byte in the output buffer, reset the flag
* and increase the frame length.
*/
uart->dle_detected = 0;
bytes_to_process--;
uart->frame_length++;
*(buffer++) = *(uart->rx_out++);
bytes_written++;
}
else { /* if (!uart->inframe) */
/*
* DLE previously detected AND currently outside of a frame =>
* Skip the current byte.
*/
bytes_to_process--;
uart->rx_out++;
}
}
break; /* case DLE */
/*
* Current byte is STX.
*/
case STX:
if ((!uart->dle_detected) && (uart->inframe)) {
/*
* No DLE previously detected AND currently inside of a frame.
*/
if (uart->frame_length) {
/*
* Frame length is not zero (End of Frame) =>
* Skip the current byte and set the flags (EOF).
*/
uart->inframe = 0;
*eof_detected = 1;
uart->frame_length = 0;
bytes_to_process--;
uart->rx_out++;
}
else { /* if (!uart->frame_length) */
/*
* Frame length is zero (STX followed by another STX =
* Synchro lost but start of a new frame) =>
* Skip the current byte and keep the flag set.
*/
bytes_to_process--;
uart->rx_out++;
}
}
else if ((!uart->dle_detected) && (!uart->inframe)) {
/*
* No DLE previously detected AND currently outside of a
* frame (Start of Frame) =>
* Skip the current byte and set the flag.
*/
uart->inframe = 1;
bytes_to_process--;
uart->rx_out++;
}
else if ((uart->dle_detected) && (uart->inframe)) {
/*
* DLE previously detected AND currently inside of a frame =>
* Copy the current byte in the output buffer, reset the flag
* and increase the frame length.
*/
uart->dle_detected = 0;
bytes_to_process--;
uart->frame_length++;
*(buffer++) = *(uart->rx_out++);
bytes_written++;
}
else if ((uart->dle_detected) && (!uart->inframe)) {
/*
* DLE previously detected AND currently outside of a frame =>
* Skip the current byte and reset the flag.
*/
uart->dle_detected = 0;
bytes_to_process--;
uart->rx_out++;
}
break; /* case STX */
/*
* Current byte is neither DLE nor STX.
*/
default:
if (uart->inframe) {
/*
* Currently inside of a frame =>
* Copy the current byte in the output buffer and increase
* the frame length.
*/
bytes_to_process--;
uart->frame_length++;
*(buffer++) = *(uart->rx_out++);
bytes_written++;
}
else { /* if (!uart->inframe) */
/*
* Currently outside of a frame =>
* Skip the current byte.
*/
bytes_to_process--;
uart->rx_out++;
}
break; /* default */
}
if (uart->rx_out == &(uart->rx_buffer[0]) + BUFFER_SIZE + 1)
uart->rx_out = &(uart->rx_buffer[0]);
}
return (bytes_written);
}
/*******************************************************************************
*
* UA_WriteNChars
*
* Purpose : Writes N characters in the TX FIFO.
*
* Arguments: In : uart_id : UART id.
* buffer : buffer address from which characters are
* written.
* bytes_to_write: number of bytes to write.
* Out: none
*
* Returns : Number of bytes written.
*
* Warning: Parameters are not verified.
*
******************************************************************************/
SYS_UWORD32
UA_WriteNChars (T_tr_UartId uart_id,
char *buffer,
SYS_UWORD32 chars_to_write)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -