📄 uart.c
字号:
// if(TxQ[channel].cnt >= MAXEVENT) {// tx queue buffer full //////////////////////////////////////////////////////// return(0); }#ifdef _S3C4530_ // compiled with s3c4530 support /////////////////////////////////////////////// if(is_s3c4530(syscfg_pd_id)) { if(channel == 0) { // read s3c4530 UART0 stat = USTAT0; // status register } else { stat = USTAT1; // s3c4530 UART1 status register } stat &= USTAT_THE; // transmit holding register is empty } else {// compiled with s3c4530 & CPU 4510 if(channel == 0) { // read s3c4510 UART 0 status register stat = UARTSTAT0; } else { stat = UARTSTAT1; // read s3c4510 UART 1 status register } stat &= UARTSTAT_TXB_EMPTY; }#else if(channel == 0) { // read s3c4510 UART 0 status register stat = UARTSTAT0; } else { stat = UARTSTAT1; // read s3c4510 UART 1 status register } stat &= UARTSTAT_TXB_EMPTY;#endif /* _S3C4530_ */ if(stat != 0 && TxQ[channel].cnt == 0) { if(channel == 0) { UARTTXH0 = (U32) ch; // write character to UART0 holding register } else { UARTTXH1 = (U32) ch; // write character to UART1 holding register } return(1); } if(TxQ[channel].wptr >= MAXEVENT) { TxQ[channel].wptr = 0; }// write character to buffer /////////////////////////////////////////////////// TxQ[channel].buff[TxQ[channel].wptr++] = ch;// Disable_Int(channel ? nUART1_TX_INT : nUART0_TX_INT); TxQ[channel].cnt++; // tx bytes Enable_Int (channel ? nUART1_TX_INT : nUART0_TX_INT); return(1);}////////////////////////////////////////////////////////////////////////////////// UART Interrupt put string ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int i_puts(int channel, char * str){ if(channel < 0 || channel > 1 || str == 0) { return(0); } while(*str != '\0') { /* Call i_putc to print each character. */ while(i_putc(channel, *str) == 0) { ; } str++; }// return(1);}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int i_flush(int channel){ if(channel < 0 || channel > 1) { return(0); } // while(TxQ[channel].cnt > 0) { ; }// return(1);} ////////////////////////////////////////////////////////////////////////////////// put polling char from UART0/UART1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int put_char(int channel,char ch) { if(channel == 1) {#ifdef _S3C4530_ if(is_s3c4530(syscfg_pd_id)) { while( (USTAT1 & USTAT_THE) == 0 ) {;} } else { while( (UARTSTAT1 & UARTSTAT_TXB_EMPTY) == 0 ) {;} }#else while( (UARTSTAT1 & UARTSTAT_TXB_EMPTY) == 0 ) {;}#endif /* _S3C4530_ */ UARTTXH1 = (U32) ch; return(1); } else if(channel == 0) {#ifdef _S3C4530_ if(is_s3c4530(syscfg_pd_id)) { while( (USTAT0 & USTAT_THE) == 0 ) {;} } else { while( (UARTSTAT0 & UARTSTAT_TXB_EMPTY) == 0 ) {;} }#else while( (UARTSTAT0 & UARTSTAT_TXB_EMPTY) == 0 ) {;}#endif /* _S3C4530_ */ UARTTXH0 = (U32) ch; return(1); } else { return(0); }}////////////////////////////////////////////////////////////////////////////////// get polling char from UART0/UART1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////char get_char(int channel) { char ch; if(channel == 1) { #ifdef _S3C4530_ if(is_s3c4530(syscfg_pd_id)) { while( (USTAT1 & USTAT_RDV) == 0 ) {;} } else { while( (UARTSTAT1 & UARTSTAT_RCV_READY) == 0 ) {;} }#else while( (UARTSTAT1 & UARTSTAT_RCV_READY) == 0 ) {;}#endif /* _S3C4530_ */ ch = UARTRXB1; } else if(channel == 0) { #ifdef _S3C4530_ if(is_s3c4530(syscfg_pd_id)) { while( (USTAT0 & USTAT_RDV) == 0 ) {;} } else { while( (UARTSTAT0 & UARTSTAT_RCV_READY) == 0 ) {;} }#else while( (UARTSTAT0 & UARTSTAT_RCV_READY) == 0 ) {;}#endif /* _S3C4530_ */ ch = UARTRXB0; } else { ch = 0; }// return(ch);}int rcv_char(int ch, U8 * val){ if(val == 0) { return(0); } if(ch == 0) { #ifdef _S3C4530_ if(is_s3c4530(syscfg_pd_id)) { if( (USTAT0 & USTAT_RDV) == 0 ) { return(0); } } else { if( (UARTSTAT0 & UARTSTAT_RCV_READY) == 0 ) { return(0); } }#else if( (UARTSTAT0 & UARTSTAT_RCV_READY) == 0 ) { return(0); }#endif /* _S3C4530_ */ *val = (UARTRXB0&0xFF); } else if(ch == 1) { #ifdef _S3C4530_ if(is_s3c4530(syscfg_pd_id)) { if( (USTAT1 & USTAT_RDV) == 0 ) { return(0); } } else { if( (UARTSTAT1 & UARTSTAT_RCV_READY) == 0 ) { return(0); } }#else if( (UARTSTAT1 & UARTSTAT_RCV_READY) == 0 ) { return(0); }#endif /* _S3C4530_ */ *val = (UARTRXB1&0xFF); } else { return(0); }// return(1); }int put_str(int ch, char * str){ if(ch < 0 || ch > 1 || str == 0) { return(0); } while(*str != '\0') { /* Call i_putc to print each character. */ put_char(ch, *str); str++; }// return(1);}////////////////////////////////////////////////////////////////////////////////// put char to console /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void put_byte(char ch){ put_char(CONSOLE, ch); } ////////////////////////////////////////////////////////////////////////////////// get char from console ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////char get_byte(void){ char ch; ch = get_char(CONSOLE); CONSOLE_last = ch; return(ch);}////////////////////////////////////////////////////////////////////////////////// get upper char from console /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////char get_upper(void){ U8 ch; ch = get_byte(); if(ch >= 'a' && ch <= 'z') {// lowercase character => convert to upper case ////////////////////////// ch = (ch - 'a') + 'A'; // } CONSOLE_last = ch; put_byte(ch); return(ch); // return character}char get_last(void){ return(CONSOLE_last);}int kbd_hit(void) { if(CONSOLE == 1) {#ifdef _S3C4530_ if(is_s3c4530(syscfg_pd_id)) { if( (USTAT1 & USTAT_RDV) ) { return(1); } } else { if( (UARTSTAT1 & UARTSTAT_RCV_READY) ) { return(1); } }#else if( (UARTSTAT1 & UARTSTAT_RCV_READY) ) { return(1); }#endif /* _S3C4530_ */ } else if(CONSOLE == 0) {#ifdef _S3C4530_ if(is_s3c4530(syscfg_pd_id)) { if( (USTAT0 & USTAT_RDV) ) { return(1); } } else { if( (UARTSTAT0 & UARTSTAT_RCV_READY) ) { return(1); } }#else if( (UARTSTAT0 & UARTSTAT_RCV_READY) ) { return(1); }#endif /* _S3C4530_ */ } return(0);}////////////////////////////////////////////////////////////////////////////////// UART0/UART1 Int LoopBack test ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////struct UARTERRBUF // uart error recv bytes buffer{ U32 txseq; // transmit sequence number U32 rxseq; // receive sequence number U8 wait; // waited value U8 recv; // received }; struct UARTERRBUF uart_err_buf[32];int uart_err_cnt = 0;int put_uart_err(U32 ts, U32 rs, U8 w, U8 r){ if(uart_err_cnt < 0 || uart_err_cnt >= 32) { return(0); // out off error buffer } else { struct UARTERRBUF * ui = uart_err_buf + uart_err_cnt++; ui->txseq = ts; // transmit sequence number ui->rxseq = rs; // receive sequence number ui->wait = w; // waited byte value ui->recv = r; // received byte value return(1); }} int print_uart_err(void){ int en = 0; while(en < uart_err_cnt) { struct UARTERRBUF * ui = uart_err_buf + en++; Print("\nRx error:sequence num=[tx %d rx %d] wait=[0x%02x] received=[0x%02x]", ui->txseq , // tx sequence number ui->rxseq , // rx sequence number ui->wait, // waited byte ui->recv // received byte ); } uart_err_cnt = 0; return(1);}////////////////////////////////////////////////////////////////////////////////// UART 0 & 1 internal loopback test ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int UARTIntLoopBack(void){ int txcount[2] = {0, 0}; // tx bytes int rxcount[2] = {0, 0}; // tx bytes int errcount[2]= {0, 0}; // errors U32 ascii[2] = {0, 0}; // sended byte U32 wait[2] = {0, 0}; // next waited byte int more = 0; // continue flag int rvl = 1; // return code U8 ch; // received character int cn; // channel number// TimerReset(1); // reset timer 0 TimerInit (1,(ONE_SECOND/TICKS_PER_SECOND)); // init timer 0 TimerStart(1); // start timer 0 Print("\nUART 0&1 Internal Loopback Test"); for(cn = 0; cn < 2; ++cn) { UARTSetLoopBack(cn, 1); // set loop back mode UARTRxIntOn(0); // enable UART cn Rx Interrupt UARTTxIntOn(0); // enable UART cn Tx Interrupt more |= (1 << cn); // set channel more flag } Enable_Int(nGLOBAL_INT); // enable global int while(more) { for(cn = 0; cn < 2; ++cn) // { // UART channel [cn] transmit loop ///////////////////////////////////////////// if(ascii[cn] < 1024 * 256) { while(ascii[cn] < 1024 * 256) { if(i_putc(cn, ascii[cn]) == 0) { // Tx Queue full break; } txcount[cn]++; // tx bytes ascii[cn]++; // next sended byte } } else if(TxQ[cn].cnt == 0) {// all test bytes are sended /////////////////////////////////////////////////// more &= ~(1 << cn); // clear channel more flag UARTWaitTxComp(cn); // wait last byte transmit completition TimerWaitMs(1, 100); // } } for(cn = 0; cn < 2; ++cn) { while(i_getc(cn, & ch) != 0) { rxcount[cn]++; // rx bytes if(ch != (U8) wait[cn]) {// received byte not equal waited ////////////////////////////////////////////// put_uart_err(txcount[cn], rxcount[cn], wait[cn], ch); // rvl = 0; // clear return code wait[cn] = ch; // reset wait byte errcount[cn]++; // rx errors } wait[cn]++; // next waited byte } } } for(cn = 0; cn < 2; ++cn) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -