Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I2C DMA on MAX32666 does not work #987

Open
sullivanmj opened this issue Apr 11, 2024 · 9 comments
Open

I2C DMA on MAX32666 does not work #987

sullivanmj opened this issue Apr 11, 2024 · 9 comments

Comments

@sullivanmj
Copy link

I am trying to get I2C working with DMA on a MAX32666 and finding that it does not work. I set up my code based on the example at https://github.com/analogdevicesinc/msdk/tree/main/Examples/MAX32665/I2C

I need to be able to do the following types of transactions - none of which currently work:

  1. Write a register address, followed by reading one or more bytes
  2. Write a register address, followed by writing one or more bytes
  3. Read one or more bytes

I made some changes in a i2c_reva.c that have 1 and 2 working, but I am unable to complete a transaction in the style of item 3 above.
https://github.com/sullivanmj/msdk/tree/fix(I2C-DMA)

I also was not able to get any of the above working with high speed I2C at ~3.2 MHz. This isn't a big pain point, but it would be nice to have working too.

@EricB-ADI
Copy link
Contributor

Hi @sullivanmj, Can you attach your code which you are trying to do 1-3? I am gonna tag @Jake-Carter and @sihyung-maxim. They may be able to help if I cannot.

@sullivanmj
Copy link
Author

Hi @EricB-ADI, this gist has an example that shows what I am trying to do. Everything works fine until we get to line 154. After making that call, the ISR/callback is never executed, and executeDmaTransaction spins forever, waiting for i2cResult to be set.

@Jake-Carter
Copy link
Contributor

Hi @sullivanmj, I think the main problems are related to making sure the correct IRQ is enabled.

I noticed this loop starts at DMA8, but you are using DMA1. So I suspect the DMA1 IRQ is not enabled, and the vector is not assigned.

MXC_DMA_Init(MXC_DMA1);
for (IRQn_Type i = DMA8_IRQn; i <= DMA15_IRQn; i++)
{
    MXC_NVIC_SetVector(i, DmaPoolIrqHandler);
    NVIC_SetPriority(i, 6);
    NVIC_EnableIRQ(i);
}

Our async and DMA I2C callback functions are reliant on MXC_I2C_AsyncHandler/MXC_DMA_Handler being called from the correct ISR, so if the NVIC routing is not enabled properly then the callbacks will not work.

Instead I would suggest explicitly enabling and routing the exact IRQ for the instance you're using.

NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(MXC_DMA_GET_IDX(MXC_DMA1)));
MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(MXC_DMA_GET_IDX(MXC_DMA1)), DmaPoolIrqHandler);
// ...

@sullivanmj
Copy link
Author

sullivanmj commented Apr 17, 2024

Hi @Jake-Carter,

Thanks for taking a look at this. I am able to hit the DMA ISR and see the callbacks executing. My example code gets successfully through everything, until it gets to the i2cRead call, where it is stuck inside waiting for i2cResult to be set by the callback. The ISR & callback all appear to be executing correctly for all of the transactions until we get to an I2C transaction that has mxc_i2c_req_t.rx_len of 0, at the very end of my sample program.

The DMA setup is a little confusing, but the intent is to initialize the DMA1 peripheral, which contains DMA channels 8-15, and then enable interrupts on each channel (8-15) in DMA1. I have used this approach in another codebase where we are using DMA channels 8-15 as a pool, with other peripherals, and they all need to call MXC_DMA_Handler in their respective ISRs, so this bit of code works well for that arrangement. In any case, I updated the code in the gist to setup the interrupts on an as-needed basis, depending on whatever channel is returned from MXC_I2C_DMA_GetTXChannel and MXC_I2C_DMA_GetRXChannel, I still don't see any change in the cases that work vs do not work.

I also updated my branch that fixes case 1, to only include the requisite change for that fix.

So, to summarize/clarify, here's where I am at:

  1. I am able to do transactions of this format, but only with the change in my branch.
    • Write slave address
    • Write n bytes (mxc_i2c_req_t.tx_len > 0)
  2. I am able to do transactions of this format, even without the change in my branch. It is possibly noteworthy that this is the only flavor of DMA-based I2C transaction in the I2C example for MAX32666, where both a read and a write occurs in the same transaction.
    • Write slave address
    • Write 1 byte (the example writes 255, I have not tried writing any more than 1, though)
    • Read n bytes (mxc_i2c_req_t.rx_len > 0)
  3. I am not able to do transactions of this format. I have tried a few things in the SDK code (such as adjusting the TX threshold, and doing a similar change as what i have in my branch for the line directly above it), but couldn't get it to work. What I see is that the slave address is shifted out, and then the MAX32666 holds SCL low, indefinitely. No DMA ISR ever triggers.
    • Write slave address
    • Write 0 bytes, this is the distinction between 2 above and this case
    • Read n bytes (mxc_i2c_req_t.rx_len > 0)

@Jake-Carter
Copy link
Contributor

Thanks @sullivanmj, this helps clarify. We'll definitely merge in your fix for case 1.

I'll take a deeper look at case 3. I went down a similar path as you and it's not immediately obvious what is holding up the TX side just looking through the software. I'll run some tests and take a look at what's going on in the hardware

@sullivanmj
Copy link
Author

Great, thanks. I'll be happy to help test this one as well, if/when you have a fix.

@Jake-Carter
Copy link
Contributor

@sullivanmj just want to shoot you a quick update on this - it's still the queue. We've been hit with some other really critical issues on a few other parts that we have to look into first, so there has been some delay

@sullivanmj
Copy link
Author

Just checking in - is there any ETA on a fix for this?

@Jake-Carter
Copy link
Contributor

@sullivanmj Last week I brought in some additional resources to help and we're simultaneously looking into some other I2C timing issues that seem to be related on the MAX78002. Your fix was relevant to fix some callback setups on that micro as well.

It's being more actively worked on now - no ETA yet just because we're still not exactly sure what the issue is. We should make some progress this week and I'll keep you updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants