9 Replies Latest reply on Oct 17, 2017 10:37 AM by milkfish1227_2635671

    How to recompile libcyu3lpp.a?

    milkfish1227_2635671

      Hi,

      I am looking to have CyU3PSpiTransmitWords() and CyU3PSpiReceiveWords() in same SS low/high period. Is there any existing function doing that? Or how can I re-compile the libcyu3lpp source?

       

      Thanks,

      Dick

        • 1. Re: How to recompile libcyu3lpp.a?
          srdr
          We have added a new API to handle both Transmit and Receive in one API in the attached modified library.

          Please replace the libcyu3lpp.a in the Cypress\EZ-USB FX3 SDK\1.3\fw_lib\1_3_3\fx3_release Folder with the attached libcyu3lpp.a.

          The API is, CyU3PSpiTransferWords ( uint8_t *txBuf, uint32_t txByteCount, uint8_t *rxBuf, uint32_t rxByteCount) 

          Here, txBuf and rxBuf are Source data pointers. These need to be padded to nearest byte if the word length is not byte aligned.  txByteCount, rxByteCount need to be a multiple of the word length aligned to the next byte

          Please use this API with modified library.
          Note that this API will be added in the next release of SDK 1.3.4 .

          How to Recompile the libcyu3lpp.a?

           

          Import the lpp_source project (default SDK path: C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\lpp_source) into Eclipse.

          And do modifications required in the .c files (spi or i2c ). Then Build using release mode or debug mode.

           

          You can see that the libcyu3lpp.a is built.

          Replace the older libcyu3lpp.a file with newly built file in the following path: Cypress\EZ-USB FX3 SDK\1.3\fw_lib\1_3_3\fx3_release Folder with the attached libcyu3lpp.a, if you do release build.

           

          Source of the CyU3PSpiTransferWords SPI is here

           

          /* Function to do combined read/writes in register mode. */

          CyU3PReturnStatus_t

          CyU3PSpiTransferWords (

            uint8_t *txBuf,

            uint32_t txByteCount,

            uint8_t *rxBuf,

            uint32_t rxByteCount)

          {

            CyU3PReturnStatus_t status;

            uint32_t byteCount, i;

            uint32_t temp, intrMask;

            uint32_t timeout;

            uint8_t wordLen;

           

            if (!glIsSpiConfigured)

            {

            return CY_U3P_ERROR_NOT_CONFIGURED;

            }

           

            if (((txBuf == 0) && (rxBuf == 0)) || ((txByteCount == 0) && (rxByteCount == 0)))

            {

            return CY_U3P_SUCCESS;

            }

           

            if (((txByteCount != 0) && (txBuf == 0)) || ((rxByteCount != 0) && (rxBuf == 0)))

            {

            return CY_U3P_ERROR_NULL_POINTER;

            }

           

            status = CyU3PSpiGetLock ();

            if (status != CY_U3P_SUCCESS)

            {

            return status;

            }

           

            /* Maximum number of words to transfer. */

            byteCount = CY_U3P_MAX (txByteCount, rxByteCount);

           

            /* Get the wordLen from the config register and convert it to byte length. */

            temp = SPI->lpp_spi_config;

            wordLen = ((temp & CY_U3P_LPP_SPI_WL_MASK) >> CY_U3P_LPP_SPI_WL_POS);

            if ((wordLen & 0x07) != 0)

            {

            wordLen = (wordLen >> 3) + 1;

            }

            else

            {

            wordLen = (wordLen >> 3);

            }

           

            /* We can only transfer data in multiples of the word length. */

            if (((txByteCount % wordLen) != 0) || ((rxByteCount % wordLen) != 0))

            {

            status = CY_U3P_ERROR_BAD_ARGUMENT;

            }

           

            /* Check if the DMA mode is running. */

            if ((temp & (CY_U3P_LPP_SPI_DMA_MODE | CY_U3P_LPP_SPI_ENABLE)) == (CY_U3P_LPP_SPI_DMA_MODE | CY_U3P_LPP_SPI_ENABLE))

            {

            status = CY_U3P_ERROR_ALREADY_STARTED;

            }

           

            if (status != CY_U3P_SUCCESS)

            {

            CyU3PSpiReleaseLock();

            return status;

            }

           

            CyU3PSpiResetFifo (CyTrue, CyTrue);

           

            /* Disable interrupts. */

            intrMask = SPI->lpp_spi_intr_mask;

            SPI->lpp_spi_intr_mask = 0;

           

            /* Enable the TX and RX bits. */

            if (rxByteCount != 0)

            SPI->lpp_spi_config |= CY_U3P_LPP_SPI_TX_ENABLE | CY_U3P_LPP_SPI_RX_ENABLE;

            else

            SPI->lpp_spi_config |= CY_U3P_LPP_SPI_TX_ENABLE;

           

            /* Re-enable SPI block. */

            SPI->lpp_spi_config |= CY_U3P_LPP_SPI_ENABLE;

            timeout = CY_U3P_MAX (glSpiWriteTimeout, glSpiReadTimeout);

           

            /* As in the ReceiveWords case, we transmit two data words before starting to look for RX_DATA. */

            for (i = 0; i <= byteCount; i += wordLen)

            {

            if (i < byteCount)

            {

            /* Form the data value to be transferred out. While the txByteCount has not run out, take data

            from the buffer. After that, transmit 0's.

            */

            temp = 0;

            if (i < txByteCount)

            {

            switch (wordLen)

            {

            case 4:

            temp |= (txBuf[i + 3] << 24);

            case 3:

            temp |= (txBuf[i + 2] << 16);

            case 2:

            temp |= (txBuf[i + 1] << 8);

            default:

            temp |= txBuf[i];

            break;

            }

            }

           

            SPI->lpp_spi_egress_data = temp;

            }

           

            /* On the first iteration, wait for TX_SPACE only. From then on, wait for RX_DATA and TX_SPACE. */

            if (i > 0)

            temp = CY_U3P_LPP_SPI_TX_SPACE;

            else

            temp = CY_U3P_LPP_SPI_TX_SPACE | CY_U3P_LPP_SPI_RX_DATA;

           

            while ((SPI->lpp_spi_status & temp) != temp)

            {

            if (timeout-- == 0)

            {

            status = CY_U3P_ERROR_TIMEOUT;

            break;

            }

            }

           

            if (status != CY_U3P_SUCCESS)

            {

            break;

            }

           

            /* If receive is not complete, wait for the RX_DATA interrupt and read the data. */

            if ((i > 0) && (i <= rxByteCount))

            {

            temp = SPI->lpp_spi_ingress_data;

            switch (wordLen)

            {

            case 4:

            rxBuf[i + 3 - wordLen] = (uint8_t)((temp >> 24) & 0xFF);

            case 3:

            rxBuf[i + 2 - wordLen] = (uint8_t)((temp >> 16) & 0xFF);

            case 2:

            rxBuf[i + 1 - wordLen] = (uint8_t)((temp >> 8) & 0xFF);

            default:

            rxBuf[i - wordLen] = (uint8_t)(temp & 0xFF);

            break;

            }

            }

            }

           

            /* There is no need to wait for TX_DONE as we are waiting for RX_DATA in all loop iterations. */

           

            /* Disable the TX and RX. */

            SPI->lpp_spi_config &= ~(CY_U3P_LPP_SPI_TX_ENABLE | CY_U3P_LPP_SPI_RX_ENABLE);

           

            /* Clear all interrupts and restore interrupt mask. */

            SPI->lpp_spi_intr |= CY_U3P_LPP_SPI_TX_DONE | CY_U3P_LPP_SPI_RX_DATA;

            SPI->lpp_spi_intr_mask = intrMask;

           

            /* Wait until the SPI block is no longer busy and disable. */

            while ((SPI->lpp_spi_status & CY_U3P_LPP_SPI_BUSY) != 0);

            SPI->lpp_spi_config &= ~CY_U3P_LPP_SPI_ENABLE;

           

            CyU3PSpiReleaseLock ();

            return status;

          }

           

          Regards,

          Sridhar

          • 2. Re: How to recompile libcyu3lpp.a?
            milkfish1227_2635671

            Thank you so much. I do have DMA mode working which use CyU3PSpiSetBlockXfer() API.

            • 3. Re: How to recompile libcyu3lpp.a?
              milkfish1227_2635671

              How about the host app? Currently control point API can use either Read or Write. We need a function can Write/Read at same time.

               

              In your example code, Write have no way to get the SPI response. Read can't have much data other than Value and Index. We need to Write 4 bytes address and data and able to get response from SPI.

               

              Thanks,

              Dick

              • 4. Re: How to recompile libcyu3lpp.a?
                milkfish1227_2635671

                Hi,

                The new CyU3PSpiTransferWords() function doesn't seems to work. At least in my case, I don't see the data out in the FPGA waveform.

                 

                 

                I am sending 4 0 0 0 1 1 1 1 to SPI.

                 

                 

                Not sure what's going on. I can't post .png file to this post, but from the waveform the "1 1 1 1" is missing.

                 

                 

                I haven't really looking the code yet.

                 

                 

                Any thoughts what might be wrong?

                 

                 

                I think I need go back to use reg mode instead of DMA due to the limit of DMA TX/RX size at least 32. I need to be able to send single byte.

                 

                Any way to post .png file?

                 

                     CyU3PSpiSetSsnLine (CyFalse);

                    status = CyU3PSpiTransmitWords (txBuf, byteCount);

                    CyU3PSpiSetSsnLine (CyTrue);

                 

                    CyU3PSpiSetSsnLine (CyFalse);

                    status = CyU3PSpiTransferWords (txBuf, byteCount, rxBuf, byteCount);

                    CyU3PSpiSetSsnLine (CyTrue);

                • 5. Re: How to recompile libcyu3lpp.a?
                  milkfish1227_2635671

                  The other question I have is - how come there is no break in switch case?

                   

                                  switch (wordLen)

                                  {

                                  case 4:

                                      temp |= (txBuf[i + 3] << 24);

                                  case 3:

                                      temp |= (txBuf[i + 2] << 16);

                                  case 2:

                                      temp |= (txBuf[i + 1] << 8);

                                  default:

                                      temp |= txBuf[i];

                                      break;

                                  }

                  • 6. Re: How to recompile libcyu3lpp.a?
                    milkfish1227_2635671

                    Never mind, I guess it's in the comments - Do fallthrough switch instead of a loop

                    • 7. Re: How to recompile libcyu3lpp.a?
                      milkfish1227_2635671

                      Correction - I am sending 4 0 0 0 1 1 1 1 to SPI. Only 4 goes out. Might be something wrong in the loop.

                      • 8. Re: How to recompile libcyu3lpp.a?
                        milkfish1227_2635671

                        I am able to get the Write waveform correctly after modify the code in following. Oiginal code doesn't even match to the coomments.

                         

                         

                        Original code is "if (i > 0).

                         

                         

                        So I am kind of wondering if there is any testing running against this new code?

                         

                         

                                /* On the first iteration, wait for TX_SPACE only. From then on, wait for RX_DATA and TX_SPACE. */

                        // mlin

                                if (i == 0)

                                    temp = CY_U3P_LPP_SPI_TX_SPACE;

                                else

                                    temp = CY_U3P_LPP_SPI_TX_SPACE | CY_U3P_LPP_SPI_RX_DATA;

                        • 9. Re: How to recompile libcyu3lpp.a?
                          milkfish1227_2635671

                          'I just have it working now. The only code need to change is the if statement to "if (i == 0)"