revision 21:fda269b432a7
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 21:fda269b432a7 |
parent | 20:3ffb66aa25c7 |
child | 22:f0703013049f |
author | nkeynes |
date | Thu Dec 22 13:52:02 2005 +0000 (17 years ago) |
Implement status clearing correctly
![]() | src/sh4/scif.c | view | annotate | diff | log |
1.1 --- a/src/sh4/scif.c Thu Dec 22 13:28:16 2005 +00001.2 +++ b/src/sh4/scif.c Thu Dec 22 13:52:02 2005 +00001.3 @@ -1,5 +1,5 @@1.4 /**1.5 - * $Id: scif.c,v 1.1 2005-12-22 13:28:16 nkeynes Exp $1.6 + * $Id: scif.c,v 1.2 2005-12-22 13:52:02 nkeynes Exp $1.7 * SCIF (Serial Communication Interface with FIFO) implementation - part of the1.8 * SH4 standard on-chip peripheral set. The SCIF is hooked up to the DCs1.9 * external serial port1.10 @@ -208,7 +208,7 @@1.11 tmp = MMIO_READ( SCIF, SCFSR2 ) & (~tmp);1.12 MMIO_WRITE( SCIF, SCFSR2, tmp );1.13 /* If both flags are cleared, clear the interrupt as well */1.14 - if( tmp & (SCFSR2_DR|SCFSR2_RDF) == 0 )1.15 + if( (tmp & (SCFSR2_DR|SCFSR2_RDF)) == 0 && IS_RECEIVE_IRQ_ENABLED() )1.16 intc_clear_interrupt( INT_SCIF_RXI );1.17 }1.19 @@ -257,7 +257,8 @@1.20 SCIF_recvq.head = SCIF_recvq.tail = 0;1.21 MMIO_WRITE( SCIF, SCFDR2, MMIO_READ( SCIF, SCFDR2 ) & 0xF0 );1.22 MMIO_WRITE( SCIF, SCFSR2, MMIO_READ( SCIF, SCFSR2 ) & ~(SCFSR2_DR|SCFSR2_RDF) );1.23 - intc_clear_interrupt( INT_SCIF_RXI );1.24 + if( IS_RECEIVE_IRQ_ENABLED() )1.25 + intc_clear_interrupt( INT_SCIF_RXI );1.26 }1.28 static inline uint8_t SCIF_sendq_size( )1.29 @@ -337,7 +338,8 @@1.30 tmp = SCFSR2_TEND;1.31 if( length > SCIF_sendq.trigger ) {1.32 tmp |= SCFSR2_TDFE;1.33 - intc_clear_interrupt( INT_SCIF_TXI );1.34 + if( IS_TRANSMIT_IRQ_ENABLED() )1.35 + intc_clear_interrupt( INT_SCIF_TXI );1.36 }1.37 tmp = MMIO_READ( SCIF, SCFSR2 ) & (~tmp);1.38 MMIO_WRITE( SCIF, SCFSR2, tmp );1.39 @@ -355,6 +357,43 @@1.40 }1.41 }1.43 +/**1.44 + * Update the SCFSR2 status register with the given mask (ie clear any values1.45 + * that are set to 0 in the mask. According to a strict reading of the doco1.46 + * though, the bits will only actually clear if the flag state is no longer1.47 + * true, so we need to recheck everything...1.48 + */1.49 +void SCIF_update_status( uint32_t mask )1.50 +{1.51 + uint32_t value = MMIO_READ( SCIF, SCFSR2 );1.52 + uint32_t result = value & mask;1.53 + uint32_t sendq_size = SCIF_sendq_size();1.54 + uint32_t recvq_size = SCIF_recvq_size();1.55 +1.56 + if( sendq_size != 0 )1.57 + result |= SCFSR2_TEND;1.58 +1.59 + if( sendq_size <= SCIF_sendq.trigger )1.60 + result |= SCFSR2_TDFE;1.61 + else if( result & SCFSR2_TDFE == 0 && IS_TRANSMIT_IRQ_ENABLED() )1.62 + intc_clear_interrupt( INT_SCIF_TXI );1.63 +1.64 + if( recvq_size >= SCIF_recvq.trigger )1.65 + result |= SCFSR2_RDF;1.66 + if( (value & SCFSR2_DR) != 0 && (result & SCFSR2_DR) == 0 &&1.67 + recvq_size != 0 )1.68 + result |= SCFSR2_DR;1.69 + if( (result & (SCFSR2_DR|SCFSR2_RDF)) == 0 && IS_RECEIVE_IRQ_ENABLED() )1.70 + intc_clear_interrupt( INT_SCIF_RXI );1.71 +1.72 + if( IS_RECEIVE_ERROR_IRQ_ENABLED() ) {1.73 + if( (result & SCFSR2_BRK) == 0 )1.74 + intc_clear_interrupt( INT_SCIF_BRI );1.75 + if( (result & SCFSR2_ER) == 0 &&1.76 + (MMIO_READ( SCIF, SCLSR2 ) & SCLSR2_ORER) == 0 )1.77 + intc_clear_interrupt( INT_SCIF_ERI );1.78 + }1.79 +}1.81 /**1.82 * Set the break detected flag1.83 @@ -469,10 +508,8 @@1.84 * Bit 1 - Receive FIFO data full1.85 * Bit 0 - Receive data ready1.86 */1.87 - tmp = MMIO_READ( SCIF, SCFSR2 );1.88 - tmp &= val;1.89 /* Clear off any flags/interrupts that are being set to 0 */1.90 - MMIO_WRITE( SCIF, reg, tmp );1.91 + SCIF_update_status( val );1.92 break;1.93 case SCFCR2: /* FIFO control register */1.94 val &= 0x0F;1.95 @@ -490,12 +527,14 @@1.96 case SCSPTR2: /* Serial Port Register */1.97 MMIO_WRITE( SCIF, reg, val );1.98 /* NOT IMPLEMENTED */1.99 + WARN( "SCSPTR2 not implemented: Write %08X", val );1.100 break;1.101 case SCLSR2:1.102 val = val & SCLSR2_ORER;1.103 if( val == 0 ) {1.104 MMIO_WRITE( SCIF, SCLSR2, val );1.105 - if( MMIO_READ( SCIF, SCFSR2 ) & SCFSR2_ER == 0)1.106 + if( (MMIO_READ( SCIF, SCFSR2 ) & SCFSR2_ER) == 0 &&1.107 + IS_RECEIVE_ERROR_IRQ_ENABLED() )1.108 intc_clear_interrupt( INT_SCIF_ERI );1.109 }
.