Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "pxa255_UART.h"
  2. #include "mem.h"
  3.  
  4.  
  5.  
  6. //TODO: signal handler for Ctl+C and send break to fifo :)
  7. //todo: recalc ints after eveyr write and every call to "process" from SoC
  8.  
  9.  
  10. #define UART_IER_DMAE           0x80    //DMA enable
  11. #define UART_IER_UUE            0x40    //Uart unit enable
  12. #define UART_IER_NRZE           0x20    //NRZI enable
  13. #define UART_IER_RTOIE          0x10    //transmit timeout interrupt enable
  14. #define UART_IER_MIE            0x08    //modem interrupt enable
  15. #define UART_IER_RLSE           0x04    //receiver line status interrupt enable
  16. #define UART_IER_TIE            0x02    //transmit data request interrupt enable
  17. #define UART_IER_RAVIE          0x01    //receiver data available interrupt enable
  18.  
  19. #define UART_IIR_FIFOES         0xC0    //fifo enable status
  20. #define UART_IIR_TOD            0x08    //character timout interrupt pending
  21. #define UART_IIR_RECV_ERR       0x06    //receive error(overrun, parity, framing, break)
  22. #define UART_IIR_RECV_DATA      0x04    //receive data available
  23. #define UART_IIR_RCV_TIMEOUT    0x0C    //receive data in buffer and been a while since we've seen more
  24. #define UART_IIR_SEND_DATA      0x02    //transmit fifo requests data
  25. #define UART_IIR_MODEM_STAT     0x00    //modem lines changed state(CTS, DSR, DI, DCD)
  26. #define UART_IIR_NOINT          0x01    //no interrupt pending
  27.  
  28.  
  29. #define UART_FCR_ITL_MASK       0xC0    //mask for ITL part of FCR
  30. #define UART_FCR_ITL_1          0x00    //interrupt when >=1 byte in recv fifo
  31. #define UART_FCR_ITL_8          0x40    //interrupt when >=8 byte in recv fifo
  32. #define UART_FCR_ITL_16         0x80    //interrupt when >=16 byte in recv fifo
  33. #define UART_FCR_ITL_32         0xC0    //interrupt when >=32 byte in recv fifo
  34. #define UART_FCR_RESETTF        0x04    //reset tranmitter fifo
  35. #define UART_FCR_RESETRF        0x02    //reset receiver fifo
  36. #define UART_FCR_TRFIFOE        0x01    //transmit and receive fifo enable
  37.  
  38. #define UART_LCR_DLAB           0x80    //divisor latch access bit
  39. #define UART_LCR_SB             0x40    //send break
  40. #define UART_LCR_STKYP          0x20    //sticky parity (send parity bit but dont care what value)
  41. #define UART_LCR_EPS            0x10    //even parity select
  42. #define UART_LCR_PEN            0x08    //parity enable
  43. #define UART_LCR_STB            0x04    //stop bits (1 = 2, 0 = 1)
  44. #define UART_LCR_WLS_MASK       0x03    //mask for WLS values
  45. #define UART_LCR_WLS_8          0x03    //8 bit words
  46. #define UART_LCR_WLS_7          0x02    //7 bit words
  47. #define UART_LCR_WLS_6          0x01    //6 bit words
  48. #define UART_LCR_WLS_5          0x00    //5 bit words
  49.  
  50. #define UART_LSR_FIFOE          0x80    //fifo contails an error (framing, parity, or break)
  51. #define UART_LSR_TEMT           0x40    //tranmitter empty (shift reg is empty and no more byte sin fifo/no byte in holding reg)
  52. #define UART_LSR_TDRQ           0x20    //transmitter data request (see docs)
  53. #define UART_LSR_BI             0x10    //send when char at front of fifo (or in holding reg) was a break char (chr reads as zero by itself)
  54. #define UART_LSR_FE             0x08    //same as above, but for framing errors
  55. #define UART_LSR_PE             0x04    //dame as above, but for parity errors
  56. #define UART_LSR_OE             0x02    //recv fifo overran
  57. #define UART_LSR_DR             0x01    //byte received
  58.  
  59. #define UART_MCR_LOOP           0x10    //loop modem control lines (not full loopback)
  60. #define UART_MCR_OUT2           0x08    //when loop is 0 enables or disables UART interrupts
  61. #define UART_MCR_OUT1           0x04    //force RI to 1
  62. #define UART_MCR_RTS            0x02    //1 -> nRTS is 0
  63. #define UART_MCR_DTR            0x01    //0 -> nDTR is 0
  64.  
  65. #define UART_MSR_DCD            0x80
  66. #define UART_MSR_RI             0x40
  67. #define UART_MSR_DSR            0x20
  68. #define UART_MSR_CTS            0x10
  69. #define UART_MSR_DDCD           0x08    //dcd changed since last read
  70. #define UART_MSR_TERI           0x04    //ri has changed from 0 to 1 since last read
  71. #define UART_MSR_DDSR           0x02    //dsr changed since last read
  72. #define UART_MSR_DCTS           0x01    //cts changed since last read
  73.  
  74.  
  75.  
  76. static void pxa255uartPrvRecalc(Pxa255uart* uart);
  77.  
  78.  
  79. static void pxa255uartPrvIrq(Pxa255uart* uart, Boolean raise){
  80.        
  81.         pxa255icInt(uart->ic, uart->irq, !(uart->MCR & UART_MCR_LOOP) && (uart->MCR & UART_MCR_OUT2) && raise/* only raise if ints are enabled */);
  82. }
  83.  
  84. static UInt16 pxa255uartPrvDefaultRead(_UNUSED_ void* userData){                        //these are special funcs since they always get their own userData - the uart pointer :)
  85.        
  86.         return UART_CHAR_NONE;  //we read nothing..as always
  87. }
  88.  
  89. static void pxa255uartPrvDefaultWrite(_UNUSED_ UInt16 chr, _UNUSED_ void* userData){    //these are special funcs since they always get their own userData - the uart pointer :)
  90.        
  91.         //nothing to do here
  92. }
  93.  
  94. static UInt16 pxa255uartPrvGetchar(Pxa255uart* uart){
  95.        
  96.         Pxa255UartReadF func = uart->readF;
  97.         void* data = (func == pxa255uartPrvDefaultRead) ? uart : uart->accessFuncsData;
  98.        
  99.         return func(data);
  100. }
  101.  
  102. static void pxa255uartPrvPutchar(Pxa255uart* uart, UInt16 chr){
  103.        
  104.         Pxa255UartWriteF func = uart->writeF;
  105.         void* data = (func == pxa255uartPrvDefaultWrite) ? uart : uart->accessFuncsData;
  106.        
  107.         func(chr, data);
  108. }
  109.  
  110. UInt8 pxa255uartPrvFifoUsed(UartFifo* fifo){    //return num spots used
  111.        
  112.         UInt8 v;
  113.        
  114.         if(fifo->read == UART_FIFO_EMPTY) return 0;
  115.         v = fifo->write + UART_FIFO_DEPTH - fifo->read;
  116.         if(v > UART_FIFO_DEPTH) v -=UART_FIFO_DEPTH;
  117.        
  118.         return v;
  119. }
  120.  
  121. void pxa255uartPrvFifoFlush(UartFifo* fifo){
  122.        
  123.         fifo->read = UART_FIFO_EMPTY;
  124.         fifo->write = UART_FIFO_EMPTY;
  125. }
  126.  
  127. Boolean pxa255uartPrvFifoPut(UartFifo* fifo, UInt16 val){       //return success
  128.        
  129.         if(fifo->read == UART_FIFO_EMPTY){
  130.                
  131.                 fifo->read = 0;
  132.                 fifo->write = 1;
  133.                 fifo->buf[0] = val;    
  134.         }
  135.         else if(fifo->read != fifo->write){     //only if not full
  136.                
  137.                 fifo->buf[fifo->write++] = val;
  138.                 if(fifo->write == UART_FIFO_DEPTH) fifo->write = 0;
  139.         }
  140.         else return false;
  141.        
  142.         return true;
  143. }
  144.  
  145. UInt16 pxa255uartPrvFifoGet(UartFifo* fifo){
  146.        
  147.         UInt16 ret;
  148.        
  149.         if(fifo->read == UART_FIFO_EMPTY){
  150.                
  151.                 ret = 0xFFFF;   //why not?
  152.         }
  153.         else{
  154.                
  155.                 ret = fifo->buf[fifo->read++];
  156.                 if(fifo->read == UART_FIFO_DEPTH) fifo->read = 0;
  157.                
  158.                 if(fifo->read == fifo->write){  //it is now empty
  159.                        
  160.                         fifo->read = UART_FIFO_EMPTY;
  161.                         fifo->write = UART_FIFO_EMPTY;
  162.                 }
  163.         }
  164.        
  165.         return ret;
  166. }
  167.  
  168. UInt16 pxa255uartPrvFifoPeekNth(UartFifo* fifo, UInt8 n){
  169.        
  170.         UInt16 ret;
  171.        
  172.        
  173.         if(fifo->read == UART_FIFO_EMPTY){
  174.                
  175.                 ret = 0xFFFF;   //why not?
  176.         }
  177.         else{
  178.                
  179.                 n += fifo->read;
  180.                 if(n >= UART_FIFO_DEPTH) n-= UART_FIFO_DEPTH;
  181.                 ret = fifo->buf[n];
  182.         }
  183.        
  184.         return ret;
  185. }
  186.  
  187. UInt16 pxa255uartPrvFifoPeek(UartFifo* fifo){
  188.        
  189.         return pxa255uartPrvFifoPeekNth(fifo, 0);
  190. }
  191.  
  192.  
  193. static void sendVal(Pxa255uart* uart, UInt16 v){
  194.        
  195.         if(uart->LSR & UART_LSR_TEMT){  //if transmit, put in shift register immediately if it's idle
  196.                        
  197.                 uart->transmitShift = v;
  198.                 uart->LSR &=~ UART_LSR_TEMT;   
  199.         }
  200.         else if(uart->FCR & UART_FCR_TRFIFOE){  //put in tx fifo if in fifo mode
  201.                
  202.                 pxa255uartPrvFifoPut(&uart->TX, v);
  203.                 if(pxa255uartPrvFifoUsed(&uart->TX) > UART_FIFO_DEPTH / 2){     //we go went below half-full buffer - set appropriate bit...
  204.                        
  205.                         uart->LSR &=~ UART_LSR_TDRQ;
  206.                 }
  207.         }
  208.         else if(uart->LSR & UART_LSR_TDRQ){     //send without fifo if in polled mode
  209.                        
  210.                 uart->transmitHolding = v;
  211.                 uart->LSR &=~ UART_LSR_TDRQ;
  212.         }
  213.         else{
  214.                
  215.                 //nothing to do - buffer is full so we ignore this request
  216.         }      
  217. }
  218.  
  219. static Boolean pxa255uartPrvMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf){
  220.  
  221.         Pxa255uart* uart = userData;
  222.         Boolean DLAB = (uart->LCR & UART_LCR_DLAB) != 0;
  223.         Boolean recalcValues = false;
  224.         UInt8 t, val = 0;
  225.        
  226.         if(size != 4 && size != 1) {
  227.                 err_str(__FILE__ ": Unexpected ");
  228.         //      err_str(write ? "write" : "read");
  229.         //      err_str(" of ");
  230.         //      err_dec(size);
  231.         //      err_str(" bytes to 0x");
  232.         //      err_hex(pa);
  233.         //      err_str("\r\n");
  234.                 return true;            //we do not support non-word accesses
  235.         }
  236.        
  237.         pa = (pa - uart->baseAddr) >> 2;
  238.        
  239.         if(write){
  240.                 recalcValues = true;
  241.                 val = (size == 1) ? *(UInt8*)buf : *(UInt32*)buf;
  242.                
  243.                 switch(pa){
  244.                         case 0:
  245.                                 if(DLAB){                               //if DLAB - set "baudrate"...
  246.                                         uart->DLL = val;
  247.                                         recalcValues = false;
  248.                                 }
  249.                                 else{
  250.                                        
  251.                                         sendVal(uart, val);
  252.                                 }
  253.                                 break;
  254.                        
  255.                         case 1:
  256.                                 if(DLAB){
  257.                                        
  258.                                         uart->DLH = val;
  259.                                         recalcValues = false;
  260.                                 }
  261.                                 else{
  262.                                         t = uart->IER ^ val;
  263.                                
  264.                                         if(t & UART_IER_DMAE){
  265.                                                
  266.                                                 err_str("pxa255UART: DMA mode cannot be enabled");
  267.                                                 t &=~ UART_IER_DMAE;    //undo the change
  268.                                         }
  269.                                        
  270.                                         if(t & UART_IER_UUE){
  271.                                                
  272.                                                 if(val & UART_IER_UUE){
  273.                                                        
  274.                                                         uart->LSR = UART_LSR_TEMT | UART_LSR_TDRQ;
  275.                                                         uart->MSR = UART_MSR_CTS;
  276.                                                 }      
  277.                                         }
  278.                                
  279.                                         uart->IER ^= t;
  280.                                 }
  281.                                 break;
  282.                        
  283.                         case 2:
  284.                                 t = uart->FCR ^ val;
  285.                                 if(t & UART_FCR_TRFIFOE){
  286.                                         if(val & UART_FCR_TRFIFOE){                     //fifos are now on - perform other actions as requested
  287.                                                
  288.                                                 if(val & UART_FCR_RESETRF){
  289.                                                        
  290.                                                         pxa255uartPrvFifoFlush(&uart->RX);      //clear the RX fifo now
  291.                                                 }
  292.                                                 if(val & UART_FCR_RESETTF){
  293.                                                        
  294.                                                         pxa255uartPrvFifoFlush(&uart->TX);      //clear the TX fifo now
  295.                                                         uart->LSR = UART_LSR_TEMT | UART_LSR_TDRQ;
  296.                                                 }
  297.                                                 uart->IIR = UART_IIR_FIFOES  |UART_IIR_NOINT;
  298.                                         }
  299.                                         else{
  300.                                                 pxa255uartPrvFifoFlush(&uart->TX);
  301.                                                 pxa255uartPrvFifoFlush(&uart->RX);
  302.                                                 uart->LSR = UART_LSR_TEMT | UART_LSR_TDRQ;
  303.                                                 uart->IIR = UART_IIR_NOINT;
  304.                                         }
  305.                                 }
  306.                                 uart->FCR = val;
  307.                                 break;
  308.                        
  309.                         case 3:
  310.                                 t = uart->LCR ^ val;
  311.                                 if(t & UART_LCR_SB){
  312.                                         if(val & UART_LCR_SB){  //break set (tx line pulled low)
  313.                                
  314.                                
  315.                                         }
  316.                                         else{                   //break cleared (tx line released)
  317.                                                
  318.                                                 sendVal(uart, UART_CHAR_BREAK);
  319.                                         }
  320.                                 }
  321.                                 uart->LCR = val;
  322.                                 break;
  323.                        
  324.                         case 4:
  325.                                 uart->MCR = val;
  326.                                 break;
  327.                        
  328.                         case 7:
  329.                                 uart->SPR = val;
  330.                                 break;
  331.                        
  332.                         case 8:
  333.                                 uart->ISR = val;
  334.                                 if(val & 3){
  335.                                         err_str("UART: IrDA mode set on UART\n");
  336.                                 }
  337.                                 break;
  338.                 }
  339.         }
  340.         else{
  341.                 switch(pa){
  342.                         case 0:
  343.                                 if(DLAB) val = uart->DLL;
  344.                                 else if(!(uart->LSR & UART_LSR_DR)){    //no data-> too bad
  345.                                                
  346.                                         val = 0;       
  347.                                 }
  348.                                 else if(uart->FCR & UART_FCR_TRFIFOE){  //fifo mode -> read fifo
  349.                                        
  350.                                         val = pxa255uartPrvFifoGet(&uart->RX);
  351.                                         if(!pxa255uartPrvFifoUsed(&uart->RX)) uart->LSR &=~ UART_LSR_DR;
  352.                                         recalcValues = true;            //error bits might have changed
  353.                                 }
  354.                                 else{                                   //polled mode -> read rx polled reg
  355.                                        
  356.                                         val = uart->receiveHolding;
  357.                                         uart->LSR &=~ UART_LSR_DR;
  358.                                 }
  359.                                 break;
  360.                        
  361.                         case 1:
  362.                                 if(DLAB) val = uart->DLH;
  363.                                 else val = uart->IER;
  364.                                 break;
  365.                        
  366.                         case 2:
  367.                                 val = uart->IIR;
  368.                                 break;
  369.                        
  370.                         case 3:
  371.                                 val = uart->LCR;
  372.                                 break;
  373.                        
  374.                         case 4:
  375.                                 val = uart->MCR;
  376.                                 break;
  377.                        
  378.                         case 5:
  379.                                 val = uart->LSR;
  380.                                 break;
  381.                        
  382.                         case 6:
  383.                                 val = uart->MSR;
  384.                                 break;
  385.                        
  386.                         case 7:
  387.                                 val = uart->SPR;
  388.                                 break;
  389.                        
  390.                         case 8:
  391.                                 val = uart->ISR;
  392.                                 break;
  393.                 }
  394.                 if(size == 1) *(UInt8*)buf = val;
  395.                 else *(UInt32*)buf = val;
  396.         }
  397.        
  398.         if(recalcValues) pxa255uartPrvRecalc(uart);
  399.        
  400.         return true;
  401. }
  402.  
  403. void pxa255uartSetFuncs(Pxa255uart* uart, Pxa255UartReadF readF, Pxa255UartWriteF writeF, void* userData){
  404.        
  405.         if(!readF) readF = pxa255uartPrvDefaultRead;            //these are special funcs since they get their own private data - the uart :)
  406.         if(!writeF) writeF = pxa255uartPrvDefaultWrite;
  407.        
  408.         uart->readF = readF;
  409.         uart->writeF = writeF;
  410.         uart->accessFuncsData = userData;
  411. }
  412.  
  413. Boolean pxa255uartInit(Pxa255uart* uart, ArmMem* physMem, Pxa255ic* ic, UInt32 baseAddr, UInt8 irq){
  414.        
  415.         __mem_zero(uart, sizeof(Pxa255uart));
  416.         uart->ic = ic;
  417.         uart->irq = irq;
  418.         uart->baseAddr = baseAddr;
  419.         uart->IIR = UART_IIR_NOINT;
  420.         uart->IER = UART_IER_UUE | UART_IER_NRZE;               //uart on
  421.         uart->LSR = UART_LSR_TEMT | UART_LSR_TDRQ;
  422.         uart->MSR = UART_MSR_CTS;
  423.         pxa255uartPrvFifoFlush(&uart->TX);
  424.         pxa255uartPrvFifoFlush(&uart->RX);
  425.        
  426.        
  427.         pxa255uartSetFuncs(uart, NULL, NULL, NULL);
  428.        
  429.         return memRegionAdd(physMem, baseAddr, PXA255_UART_SIZE, pxa255uartPrvMemAccessF, uart);
  430. }
  431.  
  432. void pxa255uartProcess(Pxa255uart* uart){               //send and rceive up to one character
  433.        
  434.         UInt8 t;
  435.         UInt16 v;
  436.        
  437.         //first process sending (if any)
  438.         if(!(uart->LSR & UART_LSR_TEMT)){
  439.                
  440.                 pxa255uartPrvPutchar(uart, uart->transmitShift);
  441.                
  442.                 if(uart->FCR & UART_FCR_TRFIFOE){       //fifo mode
  443.                        
  444.                         t = pxa255uartPrvFifoUsed(&uart->TX);
  445.                        
  446.                         if(t--){
  447.                                
  448.                                 uart->transmitShift = pxa255uartPrvFifoGet(&uart->TX);
  449.                                 if(t <= UART_FIFO_DEPTH / 2) uart->LSR |= UART_LSR_TDRQ;        //above half full - clear TDRQ bit
  450.                         }
  451.                         else{
  452.                                
  453.                                 uart->LSR |= UART_LSR_TEMT;
  454.                         }
  455.                 }
  456.                 else if (uart->LSR & UART_LSR_TDRQ){
  457.                        
  458.                         uart->LSR |= UART_LSR_TEMT;
  459.                 }
  460.                 else{
  461.                        
  462.                         uart->transmitShift = uart->transmitHolding;
  463.                         uart->LSR |= UART_LSR_TDRQ;
  464.                 }
  465.         }
  466.        
  467.         //now process receiving
  468.         v = pxa255uartPrvGetchar(uart);
  469.         if(v != UART_CHAR_NONE){
  470.                
  471.                 uart->cyclesSinceRecv = 0;
  472.                 uart->LSR |= UART_LSR_DR;
  473.                
  474.                 if(uart->FCR & UART_FCR_TRFIFOE){       //fifo mode
  475.                
  476.                         if(!pxa255uartPrvFifoPut(&uart->RX, v)){
  477.                                
  478.                                 uart->LSR |= UART_LSR_OE;      
  479.                         }
  480.                 }
  481.                 else{
  482.                        
  483.                         if(uart->LSR & UART_LSR_DR) uart->LSR |= UART_LSR_OE;
  484.                         else uart->receiveHolding = v;
  485.                 }
  486.         }
  487.         else if(uart->cyclesSinceRecv <= 4){
  488.                 uart->cyclesSinceRecv++;
  489.         }
  490.        
  491.         pxa255uartPrvRecalc(uart);
  492. }
  493.  
  494. static void pxa255uartPrvRecalcCharBits(Pxa255uart* uart, UInt16 c){
  495.        
  496.         if(c & UART_CHAR_BREAK) uart->LSR |= UART_LSR_BI;
  497.         if(c & UART_CHAR_FRAME_ERR) uart->LSR |= UART_LSR_FE;
  498.         if(c & UART_CHAR_PAR_ERR) uart->LSR |= UART_LSR_PE;
  499. }
  500.  
  501. static void pxa255uartPrvRecalc(Pxa255uart* uart){
  502.        
  503.         Boolean errorSet = false;
  504.         UInt8 v;
  505.        
  506.         uart->LSR &=~ UART_LSR_FIFOE;
  507.         uart->IIR &= UART_IIR_FIFOES;   //clear all other bits...
  508.         uart->LSR &=~ (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE);
  509.        
  510.         if(uart->FCR & UART_FCR_TRFIFOE){       //fifo mode
  511.                
  512.                
  513.                 //check rx fifo for errors
  514.                 for(v = 0; v < pxa255uartPrvFifoUsed(&uart->RX); v++){
  515.                        
  516.                         if((pxa255uartPrvFifoPeekNth(&uart->RX, v) >> 8) && (uart->IER & UART_IER_RLSE)){
  517.                                
  518.                                 uart->LSR |= UART_LSR_FIFOE;
  519.                                 uart->IIR |= UART_IIR_RECV_ERR;
  520.                                 errorSet = true;
  521.                                 break;
  522.                         }
  523.                 }
  524.                
  525.                 v = pxa255uartPrvFifoUsed(&uart->RX);
  526.                 if(v){
  527.                         pxa255uartPrvRecalcCharBits(uart, pxa255uartPrvFifoPeek(&uart->RX));
  528.                 }
  529.                
  530.                 switch(uart->FCR & UART_FCR_ITL_MASK){
  531.                        
  532.                         case UART_FCR_ITL_1:
  533.                                 v = v >= 1;
  534.                                 break;
  535.                        
  536.                         case UART_FCR_ITL_8:
  537.                                 v = v >= 8;
  538.                                 break;
  539.                        
  540.                         case UART_FCR_ITL_16:
  541.                                 v = v >= 16;
  542.                                 break;
  543.                        
  544.                         case UART_FCR_ITL_32:
  545.                                 v = v >= 32;
  546.                                 break;
  547.                 }
  548.                 if(v && (uart->IER & UART_IER_RAVIE) && !errorSet){
  549.                        
  550.                         errorSet = true;
  551.                         uart->IIR |= UART_IIR_RECV_DATA;
  552.                 }
  553.                 if(pxa255uartPrvFifoUsed(&uart->RX) && uart->cyclesSinceRecv >= 4 && (uart->IER & UART_IER_RAVIE) && !errorSet){
  554.                        
  555.                         errorSet = true;
  556.                         uart->IIR |= UART_IIR_RCV_TIMEOUT;     
  557.                 }
  558.         }
  559.         else{           //polling mode
  560.                
  561.                 UInt16 c = uart->receiveHolding;
  562.                
  563.                 if(uart->LSR & UART_LSR_DR){
  564.                        
  565.                         pxa255uartPrvRecalcCharBits(uart, c);
  566.                        
  567.                         if((c >> 8) && !errorSet && (uart->IER & UART_IER_RLSE)){
  568.                                
  569.                                 uart->IIR |= UART_IIR_RECV_ERR;
  570.                                 errorSet = true;
  571.                         }
  572.                         else if(!errorSet && (uart->IER & UART_IER_RAVIE)){
  573.                                
  574.                                 uart->IIR |= UART_IIR_RECV_DATA;
  575.                                 errorSet = true;
  576.                         }
  577.                 }
  578.         }
  579.        
  580.         if(uart->LSR & UART_LSR_TDRQ && !errorSet && (uart->IER & UART_IER_TIE)){
  581.                        
  582.                 errorSet = true;
  583.                 uart->IIR |= UART_IIR_SEND_DATA;
  584.         }
  585.        
  586.         if(!errorSet) uart->IIR |= UART_IIR_NOINT;
  587.         pxa255uartPrvIrq(uart, errorSet);
  588. }
  589.