Sunday, June 16, 2013

Renesas USB Function driver does not return from RecvWait()

Problem:

Renesas USB Function driver does not return from USBRecvWait(), even though the USB host keeps sending the data. It seems that BRDYSTS status register is not set and corresponding BRDYSTS interrupt does not occur, even though the data is received on the pipe and CBST bit is set on the PIPECTR register.

This occurs only when the data is transmitted and received simultaneously.
Solution:

Please check the udc_bulk_in0() function. If the BRDYSTS register is cleared using the following function, it will not only clear the intended bit. But, it will clear other status bits too. For example, it will clear the BRDY status of data which is received at the instant between the reading of BRDYSTS register and writing back the logical AND result.

    PRU_REG_CLR_BIT( PUO_HWF_REG_BRDYSTS, PUO_HWF_BRDYSTS_BRDY(pipeno) );

The solution is, it needs to be replaced as follows. Write the logical negation of the bit that has to be cleared.

    PRU_REG_WRITE16( PUO_HWF_REG_BRDYSTS, ~PUO_HWF_BRDYSTS_BRDY(pipeno) );

As mentioned above, the clear of BEMPSTS and INTSTS0 register also has to be replaced as follows:

    PRU_REG_CLR_BIT( PUO_HWF_REG_BEMPSTS, PUO_HWF_BEMPSTS_BEMP(pipeno) );
                             ↓
    PRU_REG_WRITE16( PUO_HWF_REG_BEMPSTS, ~PUO_HWF_BEMPSTS_BEMP(pipeno) );



    PRU_REG_CLR_BIT( PUO_HWF_REG_INTSTS0, xxxxxx );
                             ↓
    PRU_REG_WRITE16( PUO_HWF_REG_INTSTS0, ~xxxxxx );



Step towards a non buggy world!

No comments: