LPC54016 I2C DMA user data pointer

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

LPC54016 I2C DMA user data pointer

跳至解决方案
1,408 次查看
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,313 次查看
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,385 次查看
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,380 次查看
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,357 次查看
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,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 项奖励
回复
1,274 次查看
Harry_Zhang
NXP Employee
NXP Employee

Hi @andrewsglenn 

I think so.

BR

Hang

0 项奖励
回复