CMSIS driver I2C, support for DMA?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

CMSIS driver I2C, support for DMA?

1,409 Views
gunnarbohlen
Contributor II

Hello,

I'm writing code for LPC54618.

I want to use the CMSIS drivers for I2C, SPI and USART that I can find in the SDK.

File name that I found in the SDK_2.2_LPC54618J512 is "fsl_i2c_cmsis.c", unfortunately I cannot find a file version number in this file ...:-(

If I set in RTE_Device.h

#define RTE_I2C0 1
#define RTE_I2C0_DMA_EN 0

I2C0 is working as expected.

If I set

#define RTE_I2C0 1
#define RTE_I2C0_DMA_EN 1

I2C is not working. E.g. I see that in AHBCLKCTRL the clock for DMA is not enabled.

I see in the initialization for SPI :

case ARM_POWER_FULL:

...

   if (!spi->status.isPowerOn)
   {
          /* Enable flexcomm clock gate */
           CLOCK_EnableClock(s_flexcommClocks[spi->resource->instance]);
           /* Init DMA */

           ...

   }

but I cannot find the equivalent code in i2c code.

Could anyone give me an advice how to get the DMA working for i2c?

Thank you.

Tags (1)
0 Kudos
5 Replies

833 Views
gunnarbohlen
Contributor II

Hello,

my initial problem is solved, but now I see another problem (maybe I missunderstand what a function should do)

I'm using SDK 2.4 for LPC54618.

I2C communication works fine with and without DMA enabled in  RTE_device.h

#define RTE_I2C1 1
#define RTE_I2C1_DMA_EN 1

I read data from a I2C-device, and with the CMSIS-Function GetDataCount() I check that I received the requested number of databytes.

This  works fine if DMA is disabled. (in interrupt mode)

If DMA is enabled I see that the call of GetDataCount() calls the function I2C_MasterTransferGetCountDMA(), which should return the number of bytes.

I2C-communication is already finished and the variable "handle->state" is idle. This seems to make sense to me.

Problem that I see is that in this case this function returns a count of 0 and an error.

If this implementation is correct,I will not be able to use the function GetDataCount() once the communication is finished.

In the debugger I can look at handle->transferCount, and this shows the correct number of databytes.

status_t I2C_MasterTransferGetCountDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, size_t *count)
{
    assert(handle);

    if (!count)   {
        return kStatus_InvalidArgument;
    }

    /* Catch when there is not an active transfer. */
    if (handle->state == kIdleState)     {
        *count = 0;
        return kStatus_NoTransferInProgress;
    }

    /* There is no necessity to disable interrupts as we read a single integer value */
    *count = handle->transferCount;
    return kStatus_Success;
}

What is the correct usage of GetDataCount()?

Thank you.

0 Kudos

833 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Gunnar Bohlen

I'd highly recommend you to create a new thread for another question.
Thanks for your cooperation.
Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

833 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Gunnar Bohlen,

Thank you for your interest in NXP Semiconductor products and 
for the opportunity to serve you.

I've built the SDK 2.2 for the LPC54618, and I find the dma_transfer demo in the ~\SDK_2.2_LPCXpresso54S618\boards\lpcxpresso54s618\cmsis_driver_examples\i2c.

Please refer to it for details.

pastedImage_1.png

Have a great day,
TIC

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

833 Views
gunnarbohlen
Contributor II

Hello TIC,

thank you , I2C is working now in DMA mode.

But I still have a problem:

I want to use I2C to talk to an EEprom. To know when an EEprom has finished it internal write operation it is common to do an "ack polling".

The function "I2C_RunTransferStateMachineDMA()" detects the "no ack" condition of the eeprom, and returns an error code "kStatus_I2C_Nak" and initiates a i2c-stop .

Then,  because (result != kStatus_Success), interrupts are disabled and it seems the IRQ of the  already initiated i2c-stop is not evaluated any more. So the state machine stays in state "kWaitForCompletionState" forever.

The frollowing call of MasterTransmit() fails because the state machine is not is state "kIdleState"

What is the recommended method to see the "no ack" condition from the application using the CMSIS driver?

Regards, Gunnar

.

0 Kudos

833 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Gunnar Bohlen,,

Thanks for your reply.

To figure out the root cause of issue, I think you'd better to visualize the connection between the MCU and EEPROM in OSC, after doing that, you can locate the issue.

TIC

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos