This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

SMC serial driver, code in eCos wrong, PART II ? Made some changes and now it works fine.....


Hello,
I'm glad if someone who works with eCos takes a look at the changes I
have done in quicc_smc_serial.c. I'm using a MBX860 PowerPC. I wrote a
testprogram and found out a rather funny thing. If i first used
cyg_io_write( ) and after this tried to receive with the function
cyg_io_read( ) everything just worked fine. But after this I tried first
to send out with the function cyg_io_read( ) and after this to send out
with  cyg_io_write( ). NOW NOTHING WORKED!!!

The reason why this later alternative don't work is that in the
initialization of the interrupts of the SMC2 are masked. Shouldn't it be
unmasked?
However, if it's right that the SMC2 interrupt is going to be masked
after initialization I can't see how the receiving of  bytes is going to
work! The functions that take care of receiving characters works
together with the interrupt routine quicc_smc_serial_DSR(cyg_vector_t
vector, cyg_ucount32 count, cyg_addrword_t data). If the interrupts are
not unmasked you will never come to the interrupt routine and thus never
take the characters out of the receive-buffers. If you dont believe me
test by your self.

Ok, so now I have changed the initialization and can run cyg_io_read( )
without first using cyg_io_write( ). But I made one more change. In the
function quicc_smc_serial_start_xmit(serial_channel *chan). In the
beginning of this function I mask the interrupts. I don't know if this
is necessary but my thought was that I don't want anything to play
around with the txbd-buffers when the interrupts are unmasked.

After a lot of hours of debugging and testing I have made the following
changes to the eCos code.

In file quicc_smc_serial.c

static bool
quicc_smc_serial_init(struct cyg_devtab_entry *tab)
{
.
 cyg_drv_interrupt_create(smc_chan->int_num,
                                 CYGARC_SIU_PRIORITY_HIGH, // Priority -
unused (but asserted)
                                 (cyg_addrword_t)chan,   //  Data item
passed to interrupt handler
                                 quicc_smc_serial_ISR,
                                 quicc_smc_serial_DSR,
                                 &smc_chan->serial_interrupt_handle,
                                 &smc_chan->serial_interrupt);
        cyg_drv_interrupt_attach(smc_chan->serial_interrupt_handle);
  #ifdef CYGDBG_IO_INIT
   diag_printf("QUICC_SMC_2 init - interrupt number %d , calls
cyg_drv_interrupt_mask( ) \n", smc_chan->int_num);
   //diag_printf("QUICC_SMC_2 init, calls cyg_drv_interrupt_mask( )
\n");
  #endif
        //cyg_drv_interrupt_mask(smc_chan->int_num);
  cyg_drv_interrupt_unmask(smc_chan->int_num); //Change by Daniel Lind
!?!?!??!?!?!?!?!?HERE IS A CHANGE!!!!!!!!!!!!!!!!!!!!!!!!
        smc_chan->tx_enabled = false;
.
}



static void
quicc_smc_serial_start_xmit(serial_channel *chan)
{
    quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info
*)chan->dev_priv;
 cyg_drv_interrupt_mask(smc_chan->int_num); //Change by Daniel Lind
!?!??!?!?!?!?!??!?!?!?!?!HERE IS A CHANGE!?!?!?!?!?!?!?!?!?!?
    if (smc_chan->txbd->length == 0) {
        // See if there is anything to put in this buffer, just to get
it going
        cyg_drv_dsr_lock();
        (chan->callbacks->xmt_char)(chan);
        cyg_drv_dsr_unlock();
    }
    if (smc_chan->txbd->length != 0) {
        // Make sure it gets started
        quicc_smc_serial_flush(smc_chan);
    }
    smc_chan->tx_enabled = true;
    cyg_drv_interrupt_unmask(smc_chan->int_num);
}

/Daniel Lind


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]