LPC54016 I2C DMA user data pointer

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

LPC54016 I2C DMA user data pointer

ソリューションへジャンプ
1,409件の閲覧回数
andrewsglenn
Contributor III

I'm writing an application that communicates with multiple identical peripherals on different I2C busses using DMA.

I set up four Flexcomm interfaces (2,3,4,5) as I2C DMA, but am running into a small problem with the I2C DMA Handle User Data Pointer.

Since everything is identical I want a single callback function that receives a user data pointer, and since they're identical I'd like to make an array of data items.

i.e.

struct my_user_data user_data[4];

What I'm running into is that the Peripherals page won't let me use

&user_data[0] 

as a valid user data pointer.

I seem to be forced to doing:

struct my_user_data *p_user_data_0 = &user_data[0];
struct my_user_data *p_user_data_1 = &user_data[1];
struct my_user_data *p_user_data_2 = &user_data[2];
struct my_user_data *p_user_data_3 = &user_data[3];

And using them in the peripherals page.

Is there an easier way to do this?

 

 

 

 

0 件の賞賛
返信
1 解決策
1,314件の閲覧回数
andrewsglenn
Contributor III

Hi Hang,

This was the solution I provided in my initial post, yes?

So the correct answer is there is no way to directly put an array element in the Peripherals tab, you either

  1. Do it yourself
  2. Make intermediate pointers that can be put in the peripherals tab

Correct?

Glenn

元の投稿で解決策を見る

0 件の賞賛
返信
5 返答(返信)
1,386件の閲覧回数
Harry_Zhang
NXP Employee
NXP Employee

Hi @andrewsglenn 

To streamline the use of a single callback function for multiple I2C peripherals with DMA, you can maintain an array of user data pointers and set them directly when initializing each I2C DMA handle. This approach avoids the need to declare individual pointer variables for each I2C instance. 

1. Define the User Data Structure and Array:
Define your user data structure and create an array to store user data for each I2C instance.
struct my_user_data {
// Add your specific fields here
int some_field;
};
struct my_user_data user_data[4];

2. Declare the I2C DMA Handles:
Declare an array of i2c_master_dma_handle_t to store handles for each I2C instance.
i2c_master_dma_handle_t i2c_dma_handles[4];

3. Initialize I2C DMA Handles with a Loop:
Use a loop to initialize the I2C instances and set the user data pointers.
// Array of I2C base addresses for the Flexcomm interfaces
I2C_Type *i2c_bases[4] = {I2C2, I2C3, I2C4, I2C5};
for (int i = 0; i < 4; i++) {
// Initialize the I2C instance (configure I2C peripheral, clock, etc.)
I2C_MasterInit(i2c_bases[i], &i2c_master_config, CLOCK_GetFreq(kCLOCK_Flexcomm2 + i));
// Initialize the DMA for this I2C instance
I2C_MasterCreateHandleDMA(i2c_bases[i], &i2c_dma_handles[i], i2c_master_dma_callback, &user_data[i], &dma_handle);
}

4. Define the Callback Function:
Define a callback function that can handle callbacks for any of the I2C instances.
void i2c_master_dma_callback(I2C_Type *base, i2c_master_dma_handle_t *handle, status_t status, void *userData) {
struct my_user_data *data = (struct my_user_data *)userData;
// Process the callback using the user data
// Example: data->some_field = status;
}

BR

Hang

0 件の賞賛
返信
1,381件の閲覧回数
andrewsglenn
Contributor III

Hi Hang,

I was hoping for a solution that allows me to continue to use the Peripherals page in MCUXpressoIDE.

I take it that if you want to use an array of user data, you have to initialize everything manually?

Regards,

Glenn

0 件の賞賛
返信
1,358件の閲覧回数
Harry_Zhang
NXP Employee
NXP Employee

Hi @andrewsglenn 

If you want to use Peripherals Page.

You would  assign these pointers in the Peripherals page. This allows the tool to generate the correct initialization code while keeping your setup manageable.
A Hybrid Approach: Using Peripherals Page with Manual Adjustments
To maintain the benefits of the Peripherals page while achieving your goal of using an array, you could use a hybrid approach:
1. Configure the I2C Peripherals in the Peripherals Page:
• Use the Peripherals page to set up the basic I2C configurations and DMA handles. Assign the static pointers (p_user_data_0, etc.) as user data.
2. Manually Adjust the User Data Pointers:
• After the code is generated, add a small section in your application to reassign the user data pointers to elements of your array.
Here’s how it might look in practice:
// Define your user data array
struct my_user_data user_data[4];
// Configure I2C in the Peripherals page, assign static pointers p_user_data_0, p_user_data_1, etc.
// After the generated initialization code, reassign pointers
p_user_data_0 = &user_data[0];
p_user_data_1 = &user_data[1];
p_user_data_2 = &user_data[2];
p_user_data_3 = &user_data[3];

BR

Hang

0 件の賞賛
返信
1,315件の閲覧回数
andrewsglenn
Contributor III

Hi Hang,

This was the solution I provided in my initial post, yes?

So the correct answer is there is no way to directly put an array element in the Peripherals tab, you either

  1. Do it yourself
  2. Make intermediate pointers that can be put in the peripherals tab

Correct?

Glenn

0 件の賞賛
返信
1,275件の閲覧回数
Harry_Zhang
NXP Employee
NXP Employee

Hi @andrewsglenn 

I think so.

BR

Hang

0 件の賞賛
返信