/* return left tx bytes */ int uart_tx(int ch, const char *buf, int len) { unsigned int mask; if(uart[ch].is_open != 1) { RERR(); return -ENODEV; } while(len > 0) { if((uart[ch].tx_w + 1) % TX_BUF == uart[ch].tx_r) { /* bad, tx_buf is full */ RERR("uart:%d, tx_buf is full, cann't fill any more bytes!",ch); break; } uart[ch].tx_buf[uart[ch].tx_w] = *buf++; uart[ch].tx_w = (uart[ch].tx_w + 1) % TX_BUF; len--; } irq_mask(IRQ_UART0 + ch); mask = UART_REG_R(ch, UINTM_OFFSET); mask &= ~(1<<2); /* enable tx interrupt */ UART_REG_W(ch, UINTM_OFFSET, mask); irq_unmask(IRQ_UART0 + ch); return len; }
ErrVal RecPicBuffer::xMMCO( SliceHeader* pcSliceHeader ) { ROF( pcSliceHeader ); MmcoOp eMmcoOp; const MmcoBuffer& rcMmcoBuffer = pcSliceHeader->getMmcoBuffer(); Int iIndex = 0; UInt uiVal1, uiVal2; while( MMCO_END != ( eMmcoOp = rcMmcoBuffer.get( iIndex++ ).getCommand( uiVal1, uiVal2 ) ) ) { switch( eMmcoOp ) { case MMCO_SHORT_TERM_UNUSED: RNOK( xMarkShortTermUnused( m_pcCurrRecPicBufUnit, uiVal1 ) ); break; case MMCO_RESET: case MMCO_MAX_LONG_TERM_IDX: case MMCO_ASSIGN_LONG_TERM: case MMCO_LONG_TERM_UNUSED: case MMCO_SET_LONG_TERM: default: RERR(); } } return Err::m_nOK; }
/* return receive bytes */ int uart_rx_sleep(int ch, char *buf, int len) { int receive = 0; if(uart[ch].is_open != 1) { RERR(); return -ENODEV; } while(len > 0) { irq_mask(IRQ_UART0+ch); if(uart[ch].rx_r == uart[ch].rx_w) { /* rx buf is empty now */ uart[ch].sem_rx_empty_valid = 1; irq_unmask(IRQ_UART0+ch); sys_sem_wait(&uart[ch].sem_rx_empty); if(uart[ch].rx_r == uart[ch].rx_w) /* we are abort by uart_rx_sleep_abort */ return receive; } else irq_unmask(IRQ_UART0+ch); while (len > 0 && uart[ch].rx_r != uart[ch].rx_w) { *buf++ = uart[ch].rx_buf[uart[ch].rx_r]; uart[ch].rx_r = (uart[ch].rx_r + 1) % RX_BUF; receive++; len--; } } return receive; }
/* return 1 if tx buffer is empty */ int uart_tx_buffer_empty(int ch) { if(uart[ch].is_open != 1) { RERR(); return -ENODEV; } return uart[ch].tx_r == uart[ch].tx_w; }
/* close the ch * send and receive buf will be clear */ void uart_close(int ch) { if(uart[ch].is_open != 1) { RERR(); return; } irq_mask(IRQ_UART0 + ch); uart[ch].is_open = 0; /* disable all uart interrupt */ UART_REG_W(ch, UINTM_OFFSET, 0x0f); }
/* return 1 if tx buffer is full */ int uart_tx_buffer_full(int ch) { if(uart[ch].is_open != 1) { RERR(); return -ENODEV; } if((uart[ch].tx_w + 1) % TX_BUF == uart[ch].tx_r) return 1; else return 0; }
void uart_tx_sleep_abort(int ch) { /* don't forbid other process call */ if(uart[ch].is_open != 1) { RERR(); return; } irq_mask(IRQ_UART0 + ch); if(uart[ch].sem_tx_full_valid) { uart[ch].sem_tx_full_valid = 0; /* one time signal */ sys_sem_signal(&uart[ch].sem_tx_full); } irq_unmask(IRQ_UART0 + ch); }
/* return unsent bytes */ int uart_tx_sleep(int ch, const char *buf, int len) { #define ENABLE_SEND() \ do {\ if(UART_REG_R(ch, UINTM_OFFSET) & (1<<2)) {\ /* enable send interrupt */\ irq_mask(IRQ_UART0 + ch);\ mask = UART_REG_R(ch, UINTM_OFFSET);\ mask &= ~(1<<2); /* enable tx interrupt */\ UART_REG_W(ch, UINTM_OFFSET, mask);\ irq_unmask(IRQ_UART0 + ch);\ }\ } while(0) unsigned int mask; if(uart[ch].is_open != 1) { RERR(); return -ENODEV; } while(len > 0) { irq_mask(IRQ_UART0+ch); if((uart[ch].tx_w + 1) % TX_BUF == uart[ch].tx_r) { /* tx_buf is full, wait */ uart[ch].sem_tx_full_valid = 1; irq_unmask(IRQ_UART0+ch); ENABLE_SEND(); sys_sem_wait(&uart[ch].sem_tx_full); if((uart[ch].tx_w + 1) % TX_BUF == uart[ch].tx_r) /* we are abort by uart_tx_sleep_abort */ return len; } else irq_unmask(IRQ_UART0+ch); while(len > 0 && (uart[ch].tx_w + 1) % TX_BUF != uart[ch].tx_r) { uart[ch].tx_buf[uart[ch].tx_w] = *buf++; uart[ch].tx_w = (uart[ch].tx_w + 1) % TX_BUF; len--; } } ENABLE_SEND(); return len; }
/* return 1 if all charactor in tx buffer has been successfully sent */ int uart_tx_finish(int ch) { if(uart[ch].is_open != 1) { RERR(); return -ENODEV; } /* tx finish means: * tx buffer empty, tx fifo empty, and transmit holding and shift register empty. */ if(uart[ch].tx_r == uart[ch].tx_w \ && (UART_REG_R(ch, UFSTAT_OFFSET) & 0x7f00) == 0 \ && (UART_REG_R(ch, UTRSTAT_OFFSET) & 0x04) == 0x04) return 1; else return 0; }
void uart_test3(void) { int ret; char buf[1024]; int i; volatile int j; for(i = 0; i<sizeof(buf); i++) buf[i] = i & 0xff; /* uart3 tx test */ ret = uart_open(3,115200,8,'n',1); dprintf("open uart 3 ret:%d\r\n", ret); for(;;) { uart_tx_str(3, "AT\r"); while(!uart_tx_finish(3)) ; while(!(ret = uart_rx(3, buf, sizeof(buf)))) ; if(ret < 0) { RERR(); continue; } j = 1000; while(j--) ; ret += uart_rx(3, buf + ret, sizeof(buf)); if(ret > 0) { buf[ret] = 0; dprintf("ret:%d buf:%s\r\n",ret, buf); } else { dprintf("uart rx 3 ret:%d\r\n",ret); } } uart_close(3); }
/* return receive bytes */ int uart_rx(int ch, char *buf, int len) { int receive = 0; if(uart[ch].is_open != 1) { RERR(); return -ENODEV; } while(len > 0) { if(uart[ch].rx_r == uart[ch].rx_w) { /* rx buf is empty now */ break; } *buf++ = uart[ch].rx_buf[uart[ch].rx_r]; uart[ch].rx_r = (uart[ch].rx_r + 1) % RX_BUF; receive++; len--; } return receive; }
ErrVal RecPicBuffer::xMarkShortTermUnused( RecPicBufUnit* pcCurrentRecPicBufUnit, UInt uiDiffOfPicNums ) { ROF( pcCurrentRecPicBufUnit ); UInt uiCurrPicNum = pcCurrentRecPicBufUnit->getFrameNum(); Int iPicNumN = (Int)uiCurrPicNum - (Int)uiDiffOfPicNums - 1; RecPicBufUnitList::iterator iter = m_cUsedRecPicBufUnitList.begin(); RecPicBufUnitList::iterator end = m_cUsedRecPicBufUnitList.end (); for( ; iter != end; iter++ ) { //if( (*iter)->isNeededForRef() && (*iter)->getPicNum( uiCurrPicNum, m_uiMaxFrameNum ) == iPicNumN ) if( (*iter)->getPicNum( uiCurrPicNum, m_uiMaxFrameNum ) == iPicNumN ) { if ((*iter)->isNeededForRef()) (*iter)->markNonRef(); return Err::m_nOK; } } RERR(); }
static int l_write( FIOSPTR css, unit *cup, /* Current unit pointer */ void *dptr, /* Address of data */ unsigned elsize, /* Bytes per element (used for char type only)*/ int count, /* Number of elements */ int inc, /* Number of words per element */ int type, /* Type of data */ long recsize,/* Number of characters to output per line */ int errf, struct BUFFERS *bptr /* Structure containing formatting buffers */ ) { unsigned int len77; char *cp; /* points to data if type is DT_CHAR */ long *ptr; /* points to data if type is not DT_CHAR */ long ugly[ITEMBUFSIZ]; /* temporary buffer used for numeric output */ long dig; long exp; long mod; long scl; long ss; long wid; long *ib_ptr; /* pointer into the current item buffer */ long *newp; int lcount; /* repeat count of current input data group */ oc_func *gcf; /* Generic NOCV-type conversion func */ ftype_t f90type; if (type == DT_CHAR) { /* * Character data is unique in that one value may span * more than one record when output. * When we can handle opening the output file with a * 'DELIM=' descriptor (see Ansi 8x Fortran standard), this * code will need to change. For now, delimit the constant * with apostrophes, and double all internal apostrophes. */ cp = dptr; len77 = elsize; for (; count > 0; count-- ) { bptr->lcomma = 0; if (count > 1) { /* * If we have an array of character data, * determine if any values are repeated. */ cp = char_rep(cp, count, len77, &lcount, bptr); count = count - (lcount - 1); } /* Write the character constant */ ss = lw_A(css, cp, len77, recsize, cup, errf, bptr); if (ss != 0) { RERR(css, ss); } cp = cp + len77; } /* for */ return(0); } /* if (type == DT_CHAR) */ /* Noncharacter data */ ptr = (long *)dptr; f90type = _f77_to_f90_type_cnvt[type]; if ((type == DT_DBLE) || (type == DT_CMPLX)) inc = inc + inc; for (; count > 0; count--, ptr += inc) { if (count > 1) { /* find repeat values */ ptr = find_rep(ptr, count, inc, type, &lcount, bptr); count = count - (lcount - 1); } ib_ptr = bptr->f_lbufptr; switch (type) { /* set up for each data type */ case DT_NONE: gcf = _s2uo; mod = MODEUN; wid = WOCTWRD; dig = WOCTWRD; exp = 0; scl = 0; break; case DT_SINT: case DT_INT: gcf = _s2ui; mod = 0; wid = WINT; dig = 1; exp = 0; scl = 0; break; case DT_REAL: case DT_CMPLX: gcf = _sd2uge; mod = 0; wid = WREAL8; dig = _dreal8; exp = DEXP8; scl = 1; if (YMP80) dig = 9; break; case DT_DBLE: /* * When printing with D format, decrease * the digits by one because we are setting * the scale factor to 1. This ensures that * _dreal16 digits of precision are printed. */ gcf = _sd2udee; mod = MODEDP; wid = WREAL16; dig = _dreal16-1; exp = DEXP16; scl = 1; if (YMP80) dig = 25; break; } /* * Perform the output conversion. */ switch (type) { /* set up for each data type */ default: /* Integer, Short Integer, Real, or Double */ #if _F_REAL16 == 1 /* suppress if _f_dble is not fully supported */ if (YMP80 && !cup->uft90 && type == DT_DBLE && *(_f_dble *)ptr == 0.0) { static const char *zero_dp = "0.0E+00"; ib_ptr += _unpack(zero_dp, ib_ptr, strlen(zero_dp), -1); break; } #endif newp = gcf(ptr, ugly, &mod, &wid, &dig, &exp, &scl); if (type == DT_NONE) *newp++ = 'B'; ib_ptr = ib_ptr + _wnl_beautify(f90type, ugly, newp, ib_ptr, cup->uft90); break; case DT_CMPLX: *ib_ptr++ = '('; newp = gcf(ptr, ugly, &mod, &wid, &dig, &exp, &scl); ib_ptr = ib_ptr + _wnl_beautify(f90type, ugly, newp, ib_ptr, cup->uft90); *ib_ptr++ = COMMA; newp = gcf((_f_real *)ptr + 1, ugly, &mod, &wid, &dig, &exp, &scl); ib_ptr = ib_ptr + _wnl_beautify(f90type, ugly, newp, ib_ptr, cup->uft90); *ib_ptr++ = ')'; break; case DT_LOG: *ib_ptr++ = _lvtob(*(_f_log8 *)ptr)? 'T':'F'; break; } /* switch */ /* * Update the item buffer pointers before using LPUT again. */ bptr->f_lbufcnt += ib_ptr - bptr->f_lbufptr; bptr->f_lbufptr = ib_ptr; LPUT(OUT_SEP); LPUT(' '); /* put 2 blanks between items */ LPUT(' '); if (bptr->outcnt <= bptr->f_lbufcnt) { /* * If there is not enough room in the line buffer * to copy the next output value, flush out the line * and start a new line. */ REPFLUSH(); } bptr->f_lbufptr = bptr->f_lbuf; _memwcpy(bptr->outptr, bptr->f_lbufptr, bptr->f_lbufcnt); bptr->outptr += bptr->f_lbufcnt; bptr->outcnt -= bptr->f_lbufcnt; bptr->f_lbufptr = bptr->f_lbuf; bptr->f_lbufcnt = 0; } return(0); ret: return(ss); }
int @WNL( _f_int *unump, /* Unit number or dataset name */ Namelist *nl, /* Namelist structure */ int errf /* Nonzero if ERR specified */ ) { unum_t unum; int errn; int n, ss; void *vaddr; /* variable address */ unsigned elsize; /* size in bytes of the variable */ long recsize; /* number of characters to output per * line. Used by REPFLUSH.*/ char c; /* needed by NLPUTS macro */ char *s; /* needed by NLPUTS macro */ unit *cup; /* unit pointer */ Nlentry *nlent; FIOSPTR css; struct BUFFERS wnlbuffers; struct BUFFERS *bptr; bptr = &wnlbuffers; bptr->f_lbuf = NULL; unum = *unump; GET_FIOS_PTR(css); STMT_BEGIN(unum, 0, T_WNL, NULL, css, cup); if (cup == NULL) { /* if not connected */ cup = _imp_open77(css, SEQ, FMT, unum, errf, &errn); /* * If the open failed, cup is NULL and errn contains * the error number. */ if (cup == NULL) RERR(css, errn); } /* Set various unit table fields */ cup->uflag = (errf != 0 ? _UERRF : 0); cup->ulineptr = cup->ulinebuf; cup->uwrt = 1; /* Set write flag */ /* Set fields in the Fortran statement state structure */ css->u.fmt.nonl = 0; /* Clear no-newline flag */ if (cup->useq == 0) /* If direct access file */ RERR(css, FESEQTIV); /* Sequential attempted on direct access */ if (!cup->ufmt) /* If unformatted file */ RERR(css, FEFMTTIV); /* Formatted attempted on unformatted */ if ((cup->uaction & OS_WRITE) == 0) RERR(css, FENOWRIT); bptr = &wnlbuffers; bptr->lcomma = 0; /* * Set up record size. The hierarchy for determining Namelist * output record size is as follows: * 1) RECL, if specified * 2) WNLLONG(), if set and does not exceed cup->urecsize * 3) list-directed output record size (cup->uldwsize) * * Note that while (1) and (3) are established at OPEN time, (2) * can be changed ``on the fly''; therefore, this check has to * be performed here. */ recsize = cup->uldwsize; if (cup->urecl == 0 && _wnlrecsiz > 0) /* No RECL and WNLLONG() set */ recsize = MIN(cup->urecsize, _wnlrecsiz); bptr->outcnt = recsize - 1; /* First char. for carriage control */ bptr->outbuff = cup->ulinebuf; bptr->outptr = bptr->outbuff; *bptr->outptr++ = OUT_ECHO; /* First character of first line */ bptr->f_lbuf = (long *) malloc((recsize + 1) * sizeof(long)); if (bptr->f_lbuf == NULL) RERR(css, FENOMEMY); /* No memory */ /* NAMELIST delimiter to output line */ NLPUT(OUT_CHAR); /* output delimiter */ NLPUTS(nl->nlname); /* unpack group name to buffer */ NLPUT(' '); NLPUT(' '); NLINE(); /* Did user specify new line for each variable? */ nlent = nl->nlvnames; do { int ntype; ntype = _old_namelist_to_f77_type_cnvt[nlent->na.type]; /* * Always format output into f_lbufptr. * After formatting, if it will fit, move it into outbuff. * If it will not fit, write out what is already in outbuff, * and then move in the newly formatted data. */ bptr->f_lbufptr = bptr->f_lbuf; bptr->f_lbufcnt = 0; LPUTS(nlent->varname); /* output variable name */ LPUT(' '); LPUT(OUT_EQ); /* output the replacement * character. '=' by default. */ n = (nlent->na.offdim) ? nlent->na.nels : 1; if (ntype == DT_CHAR) { _fcd f; f = *(_fcd *)(((unsigned long) nlent->va.varaddr + (long *)nl)); vaddr = _fcdtocp(f); elsize = _fcdlen(f); } else { vaddr = (void *)nlent->va.varaddr; elsize = 0; } LPUT(' '); /* Output value */ ss = l_write(css, cup, vaddr, elsize, n, 1, ntype, recsize, errf, bptr); if (ss != 0) { RERR(css, ss); } NLINE(); nlent++; /* point to next variable description */ } while (nlent->varname[0]); if (bptr->outcnt < 6) { REPFLUSH(); /* Make sure there's room for " &END" */ bptr->outptr--; /* start in col. 2 */ bptr->outcnt++; } NLPUT(OUT_CHAR); NLPUTS("END"); REPFLUSH(); ret: STMT_END(cup, T_WNL, NULL, css); /* Unlock the unit */ if (bptr->f_lbuf != NULL) /* Free formatting buffer */ free(bptr->f_lbuf); return(CFT77_RETVAL(ss)); }
ErrVal RecPicBuffer::xRefListRemapping( RefFrameList& rcList, ListIdx eListIdx, SliceHeader* pcSliceHeader ) { ROF( pcSliceHeader ); const RplrBuffer& rcRplrBuffer = pcSliceHeader->getRplrBuffer( eListIdx ); //===== re-ordering ====== if( rcRplrBuffer.getRefPicListReorderingFlag() ) { UInt uiPicNumPred = pcSliceHeader->getFrameNum(); UInt uiIndex = 0; UInt uiCommand = 0; UInt uiIdentifier = 0; // JVT-V043 UInt uiCurrViewId = pcSliceHeader->getViewId(); Bool bAnchor = pcSliceHeader->getAnchorPicFlag(); Int iPicViewIdx = -1; //JVT-AB204_r1, ying Int IndexSkipCount=0; while( RPLR_END != ( uiCommand = rcRplrBuffer.get( uiIndex ).getCommand( uiIdentifier ) ) ) { IntFrame* pcFrame = 0; if( uiCommand == RPLR_LONG ) { //===== long-term index ===== RERR(); // long-term not supported } else if (uiCommand == RPLR_NEG || uiCommand == RPLR_POS) // JVT-V043 { //===== short-term index ===== UInt uiAbsDiff = uiIdentifier + 1; //----- set short-term index (pic num) ----- if( uiCommand == RPLR_NEG ) { if( uiPicNumPred < uiAbsDiff ) { uiPicNumPred -= ( uiAbsDiff - m_uiMaxFrameNum ); } else { uiPicNumPred -= uiAbsDiff; } } else // uiCommand == RPLR_POS { if( uiPicNumPred + uiAbsDiff > m_uiMaxFrameNum - 1 ) { uiPicNumPred += ( uiAbsDiff - m_uiMaxFrameNum ); } else { uiPicNumPred += uiAbsDiff; } } uiIdentifier = uiPicNumPred; //----- get frame ----- RecPicBufUnitList::iterator iter = m_cUsedRecPicBufUnitList.begin(); RecPicBufUnitList::iterator end = m_cUsedRecPicBufUnitList.end (); for( ; iter != end; iter++ ) { if( (*iter)->isNeededForRef() && (*iter)->getFrameNum() == uiIdentifier && (*iter)->getViewId() == uiCurrViewId) // JVT-V043 { pcFrame = (*iter)->getRecFrame(); break; } } if( ! pcFrame ) { fprintf( stderr, "\nERROR: MISSING PICTURE for RPLR\n\n" ); RERR(); } //----- find picture in reference list ----- UInt uiRemoveIndex = MSYS_UINT_MAX; for( UInt uiPos = uiIndex; uiPos < rcList.getActive(); uiPos++ ) // active is equal to size { if( rcList.getEntry( uiPos ) == pcFrame ) { uiRemoveIndex = uiPos; break; } } //----- reference list re-ordering ----- RNOK( rcList.setElementAndRemove( uiIndex-IndexSkipCount, uiRemoveIndex, pcFrame ) ); uiIndex++; } // short-term else // 4 or 5 { Int iAbsDiff = uiIdentifier + 1; // JVT-W066 Int iMaxRef = pcSliceHeader->getSPS().getSpsMVC()->getNumRefsForListX (uiCurrViewId, eListIdx, bAnchor); if( uiCommand == RPLR_VIEW_NEG ) { if( iPicViewIdx < iAbsDiff ) { iPicViewIdx -= ( iAbsDiff - iMaxRef ); } else { iPicViewIdx -= iAbsDiff; } } if( uiCommand == RPLR_VIEW_POS) { if( iPicViewIdx + iAbsDiff >= iMaxRef ) { iPicViewIdx += ( iAbsDiff - iMaxRef ); } else { iPicViewIdx += iAbsDiff; } } // JVT-W066 uiIdentifier = iPicViewIdx; UInt targetViewId = pcSliceHeader->getSPS().getSpsMVC()->getViewIDByViewIndex( pcSliceHeader->getViewId(), uiIdentifier, eListIdx, bAnchor ); //----- get frame ----- RecPicBufUnitList::iterator iter = m_cUsedRecPicBufUnitList.begin(); RecPicBufUnitList::iterator end = m_cUsedRecPicBufUnitList.end (); Bool InterViewFlag=false; for( ; iter != end; iter++ ) { InterViewFlag = m_pcPicEncoder->derivation_Inter_View_Flag((*iter)->getViewId(), *pcSliceHeader); if ((*iter)->getViewId() == targetViewId && (*iter)->getPoc() == pcSliceHeader->getPoc(TOP_FIELD) && InterViewFlag) //lufeng: same frame for top/bot field { pcFrame = (*iter)->getRecFrame()->getPic(pcSliceHeader->getPicType()); break; } } if (InterViewFlag == true) { if( !pcFrame ) { fprintf( stderr, "\nERROR: MISSING Inter-View PICTURE for RPLR\n\n" ); RERR(); } //----- find picture in reference list ----- UInt uiRemoveIndex = MSYS_UINT_MAX; for( UInt uiPos = uiIndex; uiPos < rcList.getActive(); uiPos++ ) // active is equal to size { if( rcList.getEntry( uiPos ) == pcFrame ) { uiRemoveIndex = uiPos; break; } } //----- reference list re-ordering ----- RNOK( rcList.setElementAndRemove( uiIndex-IndexSkipCount, uiRemoveIndex, pcFrame ) ); uiIndex++; } else { uiIndex++; IndexSkipCount++; } } // inter-view } // while } return Err::m_nOK; }
/* enable interrupts: * tx: when fifo iss less than triger level * rx: * 1. when fifo is large than triger level * 2. receive timeout and fifo is not empty * error status: * rx receive error. */ static void uart_isr(int ch) { unsigned int status; unsigned int mask; unsigned int ufstat; int call_rx_buffer_event = 0; int call_tx_buffer_event = 0; status = UART_REG_R(ch, UINTP_OFFSET); mask = UART_REG_R(ch, UINTM_OFFSET); /* mask this channel's all interrupt */ UART_REG_W(ch, UINTM_OFFSET, 0x0f); /* clear uart interrupt */ UART_REG_W(ch, UINTSP_OFFSET, status); UART_REG_W(ch, UINTP_OFFSET, status); //RDIAG(LEGACY_DEBUG,"uart ch:%d isr",ch); /* rx interrupt: * 1. when fifo is large than triger level * 2. receive timeout and fifo is not empty */ if(status & 0x01) { unsigned int rx_count; ufstat = UART_REG_R(ch, UFSTAT_OFFSET) & 0xff; rx_count = ufstat & 0x7f; /* if rx buffer was empty before, and we receive some ch * rx_buffer_event should be called */ if(rx_count && (uart[ch].rx_w == uart[ch].rx_r)) call_rx_buffer_event = 1; //RDIAG(LEGACY_DEBUG,"rx %d bytes",rx_count); /* read to rx buf */ while(rx_count--) { if((uart[ch].rx_w + 1) % RX_BUF == uart[ch].rx_r) { /* bad, rx_buf overflow, don't fill any more char into it */ RERR("uart:%d rx overflow, data may lost!", ch); break; } uart[ch].rx_buf[uart[ch].rx_w] = UART_REG_R(ch, URXH_OFFSET); uart[ch].rx_w = (uart[ch].rx_w + 1) % RX_BUF; } } /* rx error status interrupt */ if(status & 0x02) { unsigned int error_status; RDIAG(LEGACY_DEBUG,"rx error!!!"); /* read to clear error status register */ error_status = UART_REG_R(ch, UERSTAT_OFFSET); } /* tx interrupt */ if(status & 0x04) { /* if before uart tx buffer is full, tx_buffer_event will be called */ if((uart[ch].tx_w + 1) % TX_BUF == uart[ch].tx_r) call_tx_buffer_event = 1; //RDIAG(LEGACY_DEBUG,"tx fifo empty"); /* fill tx fifo until it is full */ while((UART_REG_R(ch, UFSTAT_OFFSET) & (1<<14)) == 0) { if(uart[ch].tx_r == uart[ch].tx_w) { /* tx buf now is empty, disable tx interrupt */ mask |= 1<<2; break; } UART_REG_W(ch,UTXH_OFFSET, uart[ch].tx_buf[uart[ch].tx_r]); uart[ch].tx_r = (uart[ch].tx_r + 1) % TX_BUF; } } UART_REG_W(ch, UINTM_OFFSET, mask); /* call the event handler,usually wakeup some tasks handler * uart data. */ if(call_tx_buffer_event && uart[ch].sem_tx_full_valid) { uart[ch].sem_tx_full_valid = 0; /* one time signal */ sys_sem_signal(&uart[ch].sem_tx_full); } if(call_rx_buffer_event && uart[ch].sem_rx_empty_valid) { uart[ch].sem_rx_empty_valid = 0; /* one time signal */ sys_sem_signal(&uart[ch].sem_rx_empty); } }