Cypress Perform

Home > Design Support > Cypress Developer CommunityTM > Cypress Forums > USB Controllers > USB3.0 FX3 Programming issues with SDK 321 BETA

Bookmark and Share
Cypress Developer CommunityTM
Forums | Videos | Blogs | Training | Rewards Program | Community Components



USB3.0 FX3 Programming issues with SDK 321 BETA
Moderator:
RSKV

Post Reply
Follow this topic



USB3.0 FX3 Programming issues with SDK 321 BETA

Lumpi6 posted on 18 May 2011 1:46 AM PST
Top Contributor
213 Forum Posts

Hello,

I try to get the I2C interface working correct with DMA. So far so good the point is, I can send and receive each one time with the function "CyU3PI2cSendCommand". The Callback with the event "CY_U3P_I2C_EVENT_RX_DONE" and "CY_U3P_I2C_EVENT_TX_DONE" occurs in each case too. I think it needs anything to be done at this time but I do not know what! I tried some DMA functions:

- CyU3PDmaChannelAbort

- CyU3PDmaChannelResume

- CyU3PDmaChannelReset

The second send or receive does each time nothing. The I2cSendCommand call return SUCCESS but nothing happened.

 

How can I use the I2C module more than one time in DMA mode?

 

 C - Code:

 

CyU3PErrorCode_t IS_I2cInit(void)
{
    CyU3PErrorCode_t status = CY_U3P_SUCCESS;
    CyU3PI2cConfig_t config;

    status = CyU3PI2cInit();

    if(status != CY_U3P_SUCCESS)
    {
        return status;
    }

    status = IS_I2cCreateDmaChannel();
    if(status != CY_U3P_SUCCESS)
    {
        return status;
    }

    glWriteBuffer.buffer = &glWriteData[0];
    glWriteBuffer.count  = 0;
    glWriteBuffer.size   = I2C_DMA_BUF_SIZE;
    glWriteBuffer.status = NULL;

    glReadBuffer.buffer  = &glReadData[0];
    glReadBuffer.count   = 0;
    glReadBuffer.size    = I2C_DMA_BUF_SIZE;
    glReadBuffer.status  = NULL;

    glI2cLock = CyFalse;


    config.bitRate = 400000; // 400 kHz
    config.isDma = CyTrue;  // Register transfer mode
    config.busTimeout = 0xFFFFFFFFU; // no timeout
    config.dmaTimeout = 0xFFFF; // no timeout

    status = CyU3PI2cSetConfig(&config, &IS_I2cIR);

    if(status != CY_U3P_SUCCESS)
    {
        return status;
    }

    return status;
}
 

void IS_I2cIR(CyU3PI2cEvt_t evt, CyU3PI2cError_t error)
{
    CyU3PErrorCode_t status = CY_U3P_SUCCESS;
    switch(evt)
    {
    case CY_U3P_I2C_EVENT_RX_DONE:
        if(glI2cLock == CyTrue)
        {
            status = CyU3PDmaChannelAbort(&glDmaChannelHandleI2c);
            glI2cLock = CyFalse;
        }
        else
        {
            IS_I2cErrorEvent(error);
        }
        break;
    case CY_U3P_I2C_EVENT_TX_DONE:
        if(glI2cLock == CyTrue)
        {
            status = CyU3PDmaChannelAbort(&glDmaChannelHandleI2c);
            glI2cLock = CyFalse;
        }
        else
        {
            IS_I2cErrorEvent(error);
        }
        break;
    case CY_U3P_I2C_EVENT_TIMEOUT:
        break;
    case CY_U3P_I2C_EVENT_LOST_ARBITRATION:
        break;
    case CY_U3P_I2C_EVENT_ERROR:
        IS_I2cErrorEvent(error);
        break;
    default:
        break;
    }
}

 

CyU3PErrorCode_t IS_I2cWrite(uint8_t dvcAdr, uint8_t sizeAdr, uint8_t *pAdr, uint8_t sizeData, uint8_t *pData)
{
    while(glI2cLock==CyTrue);

    CyU3PErrorCode_t status = CY_U3P_SUCCESS;

    glWriteBuffer.buffer = pData;
    glWriteBuffer.count = sizeData;

    status = CyU3PDmaChannelSetupSendBuffer(&glDmaChannelHandleI2c, &glWriteBuffer);
    //if(status == CY_U3P_SUCCESS)
    {
        glI2cLock = CyTrue;
        status = IS_I2cCommunicate(CyFalse, dvcAdr, sizeAdr, pAdr, sizeData, pData);
    }
    return status;
}
CyU3PErrorCode_t IS_I2cRead(uint8_t dvcAdr, uint8_t sizeAdr, uint8_t *pAdr, uint8_t sizeData, uint8_t *pData)
{
    while(glI2cLock==CyTrue);

    CyU3PErrorCode_t status = CY_U3P_SUCCESS;

    glReadBuffer.buffer = pData;
    glReadBuffer.count = sizeData;

    status = CyU3PDmaChannelSetupRecvBuffer(&glDmaChannelHandleI2c, &glReadBuffer);
    //if(status == CY_U3P_SUCCESS)
    {
        glI2cLock = CyTrue;
        status = IS_I2cCommunicate(CyTrue, dvcAdr, sizeAdr, pAdr, sizeData, pData);
    }
    return status;
}
CyU3PErrorCode_t IS_I2cCommunicate(CyBool_t read, uint8_t dvcAdr, uint8_t sizeAdr, uint8_t *pAdr, uint8_t sizeData, uint8_t *pData)
{
    CyU3PErrorCode_t status = CY_U3P_SUCCESS;
    CyU3PI2cPreamble_t preamble;
    uint8_t CntBytesPreamble = 0;
    uint8_t LengthAdr = 0;
    uint8_t dvcAdrWrite = dvcAdr & 0xFE;
    uint8_t dvcAdrRead = dvcAdr | 0x01;

    preamble.ctrlMask = 0;
    preamble.length = 0;

    if(sizeAdr > 0)
    {
        preamble.buffer[0] = dvcAdrWrite;
        CntBytesPreamble++;
    }

    for(LengthAdr = 0; LengthAdr < sizeAdr; LengthAdr++)
    {
        preamble.buffer[LengthAdr+1] = pAdr[LengthAdr];
        CntBytesPreamble++;
    }

    if(read == CyTrue)
    {
        if(sizeAdr > 0)
        {
            preamble.buffer[++LengthAdr] = dvcAdrRead;
            preamble.length = (++CntBytesPreamble);
            preamble.ctrlMask = 0x01 << (CntBytesPreamble-2);
        }
    }
    else
    {
        preamble.length = CntBytesPreamble;
        preamble.ctrlMask = 0x00;
    }

    //status = CyU3PI2cSetBlockXfer(sizeData);
    status = CyU3PI2cSendCommand(&preamble, sizeData, read);

    return status;
}

CyU3PErrorCode_t IS_I2cCreateDmaChannel(void)
{
    CyU3PDmaChannelConfig_t dmaI2cConfig;
    CyU3PErrorCode_t status = CY_U3P_SUCCESS;


    /* Create a DMA MANUAL Channel between two sockets of the U port */
    dmaI2cConfig.size = I2C_DMA_BUF_SIZE;
    dmaI2cConfig.count = I2C_DMA_BUF_COUNT;
    dmaI2cConfig.prodSckId = CY_U3P_LPP_SOCKET_I2C_PROD;
    dmaI2cConfig.consSckId = CY_U3P_LPP_SOCKET_I2C_CONS;
    dmaI2cConfig.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaI2cConfig.notification = CY_U3P_DMA_CB_XFER_CPLT;
    dmaI2cConfig.cb = Is_I2cDmaCallback;
    dmaI2cConfig.prodHeader = 0;
    dmaI2cConfig.prodFooter = 0;
    dmaI2cConfig.consHeader = 0;
    dmaI2cConfig.prodAvailCount = 0;

    /* Create the channel */
    status = CyU3PDmaChannelCreate(&glDmaChannelHandleI2c, CY_U3P_DMA_TYPE_AUTO, &dmaI2cConfig);
    return status;
}

 




Re: USB3.0 FX3 Programming issues with SDK 321 BETA

Lumpi6 posted on 19 May 2011 12:46 AM PST
Top Contributor
213 Forum Posts

Sorry I forgot something....

The functions

- CyU3PDmaChannelAbort

- CyU3PDmaChannelResume

- CyU3PDmaChannelReset

returns with "CY_U3P_ERROR_MUTEX_FAILURE"



Re: USB3.0 FX3 Programming issues with SDK 321 BETA

kys posted on 19 May 2011 04:04 AM PST
Cypress Employee
7 Forum Posts

CyU3PDmaChannelReset is the correct API call to be used to clear the DMA channel between operations. The difference is that you need to ensure that the DMA channel is back to idle state before you reset it.

I am attaching your code with the changes required to make this work correctly. I am also summarizing the changes below:

1. Changed the list of DMA notifications (in the parameter to CyU3PDmaChannelCreate) to include CY_U3P_DMA_CB_SEND_CPLT and CY_U3P_DMA_CB_RECV_CPLT. The CY_U3P_DMA_CB_XFER_CPLT will not work when you are using the CyU3PDmaChannelSetupSend/RecvBuffer API calls.

2. Added a new flag to track the status of the DMA channel. This flag is being made true after the CyU3PDmaChannelSetupSendBuffer or RecvBuffer is called, and made false when the DMA callback is received. I have also added a sample implementation of the DMA callback because the original code did not include this.

3. In the I2C callback (IS_I2cIR), wait for the DMA callback to come and then call CyU3PDmaChannelReset to clear up the channel.

4. Enabled the return status checks for the CyU3PDmaChannelSetupSend/RecvBuffer API calls. If these API calls fail, the I2C callback will not be called as the transfer will not get complete. Therefore, it is necessary to check the status here.

5. Changed all CyU3PErrorCode_t variables to CyU3PReturnStatus_t variables. This is the correct type to be used for FX3 API return codes.

6. Added some sample test code that calls the read/write functions repeatedly. Please note that a delay (of about 10 ms) is required between any I2C write operation and the next I2C read/write operation when using the current version of the drivers. This restriction is noted in our release notes as well.

I have marked all places where I changed your code with comments including the word "FIX". This code was tested with an I2C EEPROM device and is working fine.

Regards,

Karthik S



Re: USB3.0 FX3 Programming issues with SDK 321 BETA

Lumpi6 posted on 20 May 2011 06:28 AM PST
Top Contributor
213 Forum Posts

Hi kys,

//

many thanks for your answer. I tried to implement your fixes into my code but actually can not get it to work.

//

//

I get just one DMA Callback after the first write or read. If I write or read next time I did not get the DMA Callback again so the DMA-Busy Flag gets never be reseted and it stays forever in the endless loop.

//

I attached my example.



Re: USB3.0 FX3 Programming issues with SDK 321 BETA

kys posted on 21 May 2011 10:05 AM PST
Cypress Employee
7 Forum Posts

Hi Lumpi6,

Your code looks fine and a similar application is working correctly on my test setup.

I will look into this and get back with debug suggestions within a day.

Thanks and regards,

Karthik



Re: USB3.0 FX3 Programming issues with SDK 321 BETA

kys posted on 22 May 2011 02:46 AM PST
Cypress Employee
7 Forum Posts

Hi Lumpi6,

I have a couple of questions on your application.

1. What is the priority level you have assigned to the thread from which you are making the I2cDmaWrite and I2cDmaRead calls?

2. Are you getting error returns from any of the API calls that you are making as of now (DmaChannelReset, DmaChannelSetupSendBuffer, DmaChannelSetupRecvBuffer or I2cSendCommand)?

3. If possible, please provide a pointer to the I2C device that you are trying to access via the FX3.

Thanks,

Karthik



Re: USB3.0 FX3 Programming issues with SDK 321 BETA

Lumpi6 posted on 23 May 2011 11:53 PM PST
Top Contributor
213 Forum Posts

Hi Karthik,

|

1. Thread - Creation

    /* Create the thread for the application */
    retThrdCreate = CyU3PThreadCreate (&I2cAppThread,           /* I2C in DMA Thread structure */
                          "I2C in DMA Mode TEST",               /* Thread ID and Thread name */
                          I2cAppThread_Entry,                   /* I2C in DMA Thread Entry function */
                          0,                                    /* No input parameter to thread */
                          ptr,                                  /* Pointer to the allocated thread stack */
                          THREAD_I2C_THREAD_STACK,              /* I2C in DMA Thread stack size */
                          THREAD_I2C_THREAD_PRIORITY,           /* I2C in DMA Thread priority */
                          THREAD_I2C_THREAD_PRIORITY,           /* I2C in DMA Thread priority */
                          CYU3P_NO_TIME_SLICE,                  /* No time slice for the application thread */
                          CYU3P_AUTO_START                      /* Start the Thread immediately */
                          );

#define THREAD_I2C_THREAD_STACK       (0x1000)                  /* I2C in DMA thread stack size */
#define THREAD_I2C_THREAD_PRIORITY    (8)                       /* I2C in DMA thread priority */
|

2. I get no Errors of any API calls.

|

3. The I2C EEPROM is a M24C64 and this is working fine with the standard send and receive functions of the I2C.

|

Best regards

lumpi6



Re: USB3.0 FX3 Programming issues with SDK 321 BETA

Lumpi6 posted on 23 May 2011 01:14 AM PST
Top Contributor
213 Forum Posts

Hi Karthik,

I can write two times, four times so that I think the write mechnism works fine. The problem is that I can just read once and then the DMA-Busy flag will never be set to zero.

The send notification "CY_U3P_DMA_CB_SEND_CPLT" happens each time at the DMA callback but the receive notification "CY_U3P_DMA_CB_RECV_CPLT" or any other call never happens. Why? I think there is the problem...

Best regards

lumpi6



Re: USB3.0 FX3 Programming issues with SDK 321 BETA

kys posted on 23 May 2011 09:32 AM PST
Cypress Employee
7 Forum Posts

Hi Lumpi6,

Thanks for providing the data.

You are seeing this problem because the read data (2 bytes in your case) is not filling the DMA buffer (64 bytes in your case). In such a case, the DMA channel is on hold waiting for more data to come in and fill the buffer.

The DMA buffer size is specified through the g_DmaBufferRead.size parameter and needs to be a multiple of 16 bytes.

We will work on updating the API to take care of this case by the time of the next release.

For now, please use one of the following work-arounds:

1. Use the CyU3PI2cReceiveBytes API instead of a DMA operation when you want to read small amounts of data. You can use the DMA read operation as you are currently doing when you want to read data that will fill the entire DMA buffer.

2. Use the "CyU3PDmaChannelSetWrapUp (&g_HandleI2cDmaCh)" from the I2cDmaIR function on receipt of a CY_U3P_I2C_EVENT_RX_DONE event. This will cause the DMA buffer to be committed and result in receipt of the DMA callback.

Please let me know if you have problems/concerns with these work-arounds.

With regards,

Karthik



Re: USB3.0 FX3 Programming issues with SDK 321 BETA

Teonikije posted on 11 Feb 2013 11:57 AM PST

1 Forum Post

 Hi guys,

I'm trying to use I2C in DMA mode as Lumpi6 wanted. So, I would like to know has this been supported in newest version of FX3 SDK?

Thanks!

Teo






ALL CONTENT AND MATERIALS ON THIS SITE ARE PROVIDED "AS IS". CYPRESS SEMICONDUCTOR AND ITS RESPECTIVE SUPPLIERS MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY OF THESE MATERIALS FOR ANY PURPOSE AND DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD TO THESE MATERIALS, INCLUDING BUT NOT LIMITED TO, ALL IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT OF ANY THIRD PARTY INTELLECTUAL PROPERTY RIGHT. NO LICENSE, EITHER EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, IS GRANTED BY CYPRESS SEMICONDUCTOR. USE OF THE INFORMATION ON THIS SITE MAY REQUIRE A LICENSE FROM A THIRD PARTY, OR A LICENSE FROM CYPRESS SEMICONDUCTOR.

Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms and Conditions of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms and Conditions of this site. Cypress Semiconductor and its suppliers reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

Spec No: None; Sunset Owner: KXP; Secondary Owner: VWA; Sunset Date: 01/01/20