Search
lxdream.org :: lxdream/src/sh4/scif.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/scif.c
changeset 21:fda269b432a7
prev20:3ffb66aa25c7
next22:f0703013049f
author nkeynes
date Thu Dec 22 13:52:02 2005 +0000 (14 years ago)
permissions -rw-r--r--
last change Implement status clearing correctly
file annotate diff log raw
1.1 --- a/src/sh4/scif.c Thu Dec 22 13:28:16 2005 +0000
1.2 +++ b/src/sh4/scif.c Thu Dec 22 13:52:02 2005 +0000
1.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 the
1.8 * SH4 standard on-chip peripheral set. The SCIF is hooked up to the DCs
1.9 * external serial port
1.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.18
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.27
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.42
1.43 +/**
1.44 + * Update the SCFSR2 status register with the given mask (ie clear any values
1.45 + * that are set to 0 in the mask. According to a strict reading of the doco
1.46 + * though, the bits will only actually clear if the flag state is no longer
1.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.80
1.81 /**
1.82 * Set the break detected flag
1.83 @@ -469,10 +508,8 @@
1.84 * Bit 1 - Receive FIFO data full
1.85 * Bit 0 - Receive data ready
1.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 }
1.110
.