📄 uart.c
字号:
/*************************************************************************//* *//* FILE NAME VERSION *//* *//* uart.c KS32C5000(A)/50100 SNDS100 Ver1.0 *//* *//* COMPONENT *//* *//* *//* DESCRIPTION *//* *//* UART library functions. *//* *//* AUTHOR *//* *//* Young Sun KIM, Samsung Electronics, Inc. *//* *//* DATA STRUCTURES *//* *//* *//* FUNCTIONS *//* *//* UART_Initialize Initialize serial driver *//* i_getc Get a character from buffer *//* i_gets Get a string from buffer *//* i_putc print a character *//* i_puts Print a string *//* i_printf formmatted print *//* *//* DEPENDENCIES *//* *//* *//* HISTORY *//* *//* NAME DATE REMARKS *//* *//* in4maker 05-31-1999 Created initial version 1.0 *//* *//*************************************************************************//* *//* Modified by *//* Dmitriy Cherkashin *//* dch@ucrouter.ru *//* 2002,2003 *//* */#include "evm50100.h" // evm50100 board definition #include "ks32c50.h"#define CHECK_UART////////////////////////////////////////////////////////////////////////////////// INITIALIZE UART GLOBAL VARIABLE /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////static U8 CONSOLE_last = 0; // last received from console character// Transmit & Receive Que data structure ///////////////////////////////////////#define MAXEVENT 8192 // buffer size typedef struct { U8 buff[MAXEVENT]; // data buffer volatile int wptr; // write pointer volatile int rptr; // read pointer volatile int cnt; // bytes count} UART_BUFFER;/* Define references to external structures */UART_BUFFER RxQ[2]; // Receive QueueUART_BUFFER TxQ[2]; // Transmit Queuestruct { U32 overrun; // overrun error U32 parity; // parity error U32 frame; // frame error U32 brdet; // break} UART_ERR[2];#define BAUD_TABLE_SIZE 7 // No of baud rate tablestruct { U32 baud; // baud rate U32 div; // divisor } BaudTable[BAUD_TABLE_SIZE] = {#ifdef EX_UCLK/* for 29.4912MHz UART clock */ 9600, 0x000bf, 19200, 0x0005f, 38400, 0x0002f, 57600, 0x0001f, 115200, 0x0000f, 230400, 0x00007, 460800, 0x00003#else#ifdef _KS32C50100_/* for 50MHz/2 UART clock *//* see KS32C50100 RISC MICROCONTROLLER reference, page 10-14 */ 9600, 0x00a20, // cnt0 = 162 cnt1 = 0, 0 19200, 0x00500, // cnt0 = 80 cnt1 = 0, 1 38400, 0x00280, // cnt0 = 40 cnt1 = 0, 2 57600, 0x001a0, // cnt0 = 26 cnt1 = 0, 3 115200, 0x000d0, // cnt0 = 13 cnt1 = 0, 4 230400, 0x00060, // cnt0 = 6 cnt1 = 0, 5 460800, 0x00020 // cnt0 = 2 cnt1 = 0, 6 not available /* UBRDIV0, UBRDIV1 format *//* [ 0:3] = Baud rate divisor value CNT1 *//* xxx0 = divide by 1 */ /* [15:4] = Time constant value for CNT0 *//* BRGOUT = (MCLK2 or UCLK) / (CNT0 + 1) / (16^CNT1) / 16 */#else 9600, 0x00a20, 19200, 0x00500, 38400, 0x00280, 57600, 0x001a0, 115200, 0x000d0, 230400, 0x00060, 460800, 0x00020 #endif#endif};////////////////////////////////////////////////////////////////////////////////// UART0 Transmit Interrupt Service Routine ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#ifdef _KS32C50100_////////////////////////////////////////////////////////////////////////////////// KS32C50100 UART channel 0 Tx int service routine ////////////////////////////////////////////////////////////////////////////////////////////////////////////void S3C4510_Uart0TxISR(void){ U32 stat = UARTSTAT0; // read UART0 status register if((stat & UARTSTAT_TXB_EMPTY)!= 0) /* Uart 0 Tx Buffer Empty */ { if(TxQ[0].cnt > 0) { // tx queue not empty if(TxQ[0].rptr >= MAXEVENT) { // set read pointer to queue start TxQ[0].rptr = 0; } UARTTXH0=TxQ[0].buff[TxQ[0].rptr++];// write to UART0 transmit holding regs TxQ[0].cnt--; // remain bytes in UART0 transmit queue } }// if((stat & UARTSTAT_ERROR) != 0) {// overrun, parity, frame bits automaticaly cleared when status register is readed if((stat & UARTSTAT_OVERRUN)) { // overrun error UART_ERR[0].overrun++; // calculate overrun error count } if((stat & UARTSTAT_PARITY)) { // parity error UART_ERR[0].parity++; // calculate parity error count } if((stat & UARTSTAT_FRAME)) { // frame error UART_ERR[0].frame++; // calculate frame error count } } if((stat & UARTSTAT_BREAK)) { // calculate break detect count UART_ERR[0].brdet++; // } }////////////////////////////////////////////////////////////////////////////////// KS32C50100 UART1 Tx ISR /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void S3C4510_Uart1TxISR(void){ U32 stat = UARTSTAT1; // read status register 0 if( (stat & UARTSTAT_TXB_EMPTY) != 0 ) { // Uart 0 Tx Buffer Empty if(TxQ[1].cnt > 0) { if(TxQ[1].rptr >= MAXEVENT) { // read pointer out off queue buffer TxQ[1].rptr = 0; // set read pointer to bugger start } UARTTXH1=TxQ[1].buff[TxQ[1].rptr++];// write byte to UART1 tx holding register TxQ[1].cnt--; // remain bytes in tx queue } }// if((stat & UARTSTAT_ERROR) != 0) {// overrun, parity, frame bits automaticaly cleared when status register is readed if((stat & UARTSTAT_OVERRUN)) { // overrun error UART_ERR[1].overrun++; // calculate overrun error count } if((stat & UARTSTAT_PARITY)) { // parity error UART_ERR[1].parity++; // calculate parity error count } if((stat & UARTSTAT_FRAME)) { // frame error UART_ERR[1].frame++; // calculate frame error count } } if((stat & UARTSTAT_BREAK)) { UART_ERR[1].brdet++; } }#endif /* _KS32C50100_ */#ifdef _S3C4530_////////////////////////////////////////////////////////////////////////////////// S3C4530 UART channel 0 Tx int service routine ///////////////////////////////////////////////////////////////////////////////////////////////////////////////void S3C4530_Uart0TxISR(void){ if((USTAT0 & USTAT_THE) != 0) { // Uart Tx holding register Empty if(TxQ[0].cnt > 0) { // UART0 Tx queue not empty if(TxQ[0].rptr >= MAXEVENT) { // set read pointer to TxQ[0].rptr = 0; // start off queue buffer } UARTTXH0=TxQ[0].buff[TxQ[0].rptr++];// write to uart0 tx holding register TxQ[0].cnt--; // remain bytes in UART0 tx queue } }}////////////////////////////////////////////////////////////////////////////////// S3C4530 UART channel 1 Tx int service routine ///////////////////////////////////////////////////////////////////////////////////////////////////////////////void S3C4530_Uart1TxISR(void){ if((USTAT1 & USTAT_THE) != 0) { // Uart1 Tx Holding Register Empty if(TxQ[1].cnt > 0) { // UART1 Tx queue not empty if(TxQ[1].rptr >= MAXEVENT) { // set read pointer TxQ[1].rptr = 0; // to begin } UARTTXH1=TxQ[1].buff[TxQ[1].rptr++];// write to UART1 tx holding register TxQ[1].cnt--; // remain bytes in tx queue } }}#endif////////////////////////////////////////////////////////////////////////////////// UART0 Rcv, Error Interrupt Service Routine //////////////////////////////////////////////////////////////////////////////////////////////////////////////////#ifdef _KS32C50100_////////////////////////////////////////////////////////////////////////////////// S3C4510 (KS32C50100) Receive, Error Interrupt Service Routine ///////////////////////////////////////////////////////////////////////////////////////////////void S3C4510_Uart0RxErrISR(void){ U32 stat; // status register content stat = UARTSTAT0; // read UART0 status register if((stat & UARTSTAT_RCV_READY) != 0) { // UARTRXB0 contain valid rx data U8 ch = UARTRXB0; // read received byte if(RxQ[0].cnt < MAXEVENT) { // UART0 queue not fill if(RxQ[0].wptr >= MAXEVENT) { // set write pointer RxQ[0].wptr = 0; // to begin of queue }// read UART0 rx buffer register RxQ[0].buff[RxQ[0].wptr++] = ch; RxQ[0].cnt++; // bytes in rx queue } else { // UART 0 Rx queue full UART_ERR[0].overrun++; // calculate overrun error count } } if((stat & UARTSTAT_ERROR) != 0) {// overrun, parity, frame bits automaticaly cleared when status register is readed if((stat & UARTSTAT_OVERRUN)) { // overrun error UART_ERR[0].overrun++; // calculate overrun error count } if((stat & UARTSTAT_PARITY)) { // parity error UART_ERR[0].parity++; // calculate parity error count } if((stat & UARTSTAT_FRAME)) { // frame error UART_ERR[0].frame++; // calculate frame error count } } if((stat & UARTSTAT_BREAK)) { UART_ERR[0].brdet++; } }////////////////////////////////////////////////////////////////////////////////// KS32C50100 rX Int ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void S3C4510_Uart1RxErrISR(void){ U32 stat; // status register content stat = UARTSTAT1; // read UART0 status register if((stat & UARTSTAT_RCV_READY) != 0) { // UARTRXB1 contain valid rx data U8 ch = UARTRXB1; if(RxQ[1].cnt < MAXEVENT) { // UART1 Rx Queue no full if(RxQ[1].wptr >= MAXEVENT) { // set write pointer RxQ[1].wptr = 0; // to begin of queue }// read from channel 0 RxQ[1].buff[RxQ[1].wptr++] = ch; RxQ[1].cnt++; // bytes in UART1 rx queue } else { // UART1 rx queue full UART_ERR[1].overrun++; // calculate overrun error count } } if((stat & UARTSTAT_ERROR) != 0) {// overrun, parity, frame bits automaticaly cleared when status register is readed if((stat & UARTSTAT_OVERRUN)) { // overrun error UART_ERR[1].overrun++; // calculate overrun error count } if((stat & UARTSTAT_PARITY)) { // parity error UART_ERR[1].parity++; // calculate parity error count } if((stat & UARTSTAT_FRAME)) { // frame error UART_ERR[1].frame++; // calculate frame error count } } if((stat & UARTSTAT_BREAK)) { UART_ERR[1].brdet++; } }#endif /* _KS32C50100_ */#ifdef _S3C4530_////////////////////////////////////////////////////////////////////////////////// S3C4530 Receive Error Interrupt Service Routine ///////////////////////////// ////////////////////////////////////////////////////////////////////////////////void S3C4530_Uart0RxErrISR(void){ U32 stat, wstat = 0; // readed status, write stat = USTAT0; // read UART0 status if((stat & USTAT_OER) != 0) { // [4] Overrun Error (OER) wstat |= USTAT_OER; // set write bit UART_ERR[0].overrun++; // calc UART0 overrun errors count } if((stat & USTAT_BSD) != 0) { // [1] Break Signal Detected (BSD) wstat |= USTAT_BSD; // set write bit UART_ERR[0].brdet++; // calc statistics } if((stat & USTAT_FER) != 0) { // [2] Frame Error (FER) wstat |= USTAT_FER; // set write bit UART_ERR[0].frame++; } if((stat & USTAT_PER) != 0) { // [3] Parity Error (PER) wstat |= USTAT_PER; UART_ERR[0].parity++; }/* write to status register to clear bits */ USTAT0 = wstat; if( (stat & USTAT_RDV) != 0 ) { // UARTRXB0 contain valid rx data U8 ch = UARTRXB0; // read rx byte if(RxQ[0].cnt < MAXEVENT) { // UART0 rx queue not full if(RxQ[0].wptr >= MAXEVENT) { // set write pointer RxQ[0].wptr = 0; // to queue begin } RxQ[0].buff[RxQ[0].wptr++] = ch; // read ex data & write to rx queue RxQ[0].cnt++; // bytes in UART0 rx queue } else { // UART0 rx queue full UART_ERR[0].overrun++; // calc errors count } }} void S3C4530_Uart1RxErrISR(void){ U32 stat, wstat = 0; // readed status, writed stat = USTAT1; // read UART1 status register if((stat & USTAT_OER) != 0) { // [4] Overrun Error (OER) wstat |= USTAT_OER; // set write bit UART_ERR[1].overrun++; // calc UART1 overrun count } if((stat & USTAT_BSD) != 0) { // [1] Break Signal Detected (BSD) wstat |= USTAT_BSD; // set write bit UART_ERR[1].brdet++; // calc UART1 stat } if((stat & USTAT_FER) != 0) { // [2] Frame Error (FER) wstat |= USTAT_FER; // set write bit UART_ERR[1].frame++; } if((stat & USTAT_PER) != 0) { // [3] Parity Error (PER) wstat |= USTAT_PER; // set write bit UART_ERR[1].parity++; }/* write to status register to clear status register bits */ USTAT1 = wstat; if( (stat & USTAT_RDV) != 0 ) { // UARTRXB1 contain valid rx data U8 ch = UARTRXB1; // read and discard rx byte if(RxQ[1].cnt < MAXEVENT) { // UART1 Rx queue not full if(RxQ[1].wptr >= MAXEVENT) { // set write pointer to begin of queue RxQ[1].wptr = 0; } RxQ[1].buff[RxQ[1].wptr++] = ch; // read UART1 rx data & write to rx queue RxQ[1].cnt++; // UART1 rx queue bytes count } else { // UART1 Rx queue full UART_ERR[1].overrun++; // calc overrun errors count } }} #endif // _S3C4530_////////////////////////////////////////////////////////////////////////////////// Initialization of global structures /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////U32 UART_Initialize(void){ U32 uartbrd; // UARTBRD content int pos; // position in UART Tx & Rx buffer int cn; // UART channel // Disable_Int(nGLOBAL_INT); // Global interrupt disabled // Disable UART0 & UART1 interrupts //////////////////////////////////////////// UARTRxIntOff(0); // UART0 Rx interrupt disable UARTRxIntOff(1); // UART1 Rx interrupt disable UARTTxIntOff(0); // UART0 Tx interrupt disable UARTTxIntOff(1); // UART1 Tx interrupt disable// Initialize UART0&UART1 transmit & receive Queue ///////////////////////////// for(cn = 0; cn < 2; ++cn) // { TxQ[cn].wptr = 0; // Tx Queue write pointer TxQ[cn].rptr = 0; // Tx Queue read pointer TxQ[cn].cnt = 0; // Tx Queue bytes count// RxQ[cn].wptr = 0; // Rx Queue write pointer RxQ[cn].rptr = 0; // Rx Queue read pointer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -