Skip to content

Conversation

ZhaoxiangJin
Copy link
Contributor

@ZhaoxiangJin ZhaoxiangJin commented Oct 12, 2025

Add DMA transfer capability to LPADC

@ZhaoxiangJin ZhaoxiangJin force-pushed the enable-lpadc-edma-feature branch 4 times, most recently from 1769f55 to 4925d86 Compare October 13, 2025 06:22
Fix adc_dt run issue on frdm_mcxn236 board, the default
mode of vref is standby mode, the BUF21 is not enabled,
so the LPADC can not work normally. Need to set the vref
mode to 'NXP_VREF_MODE_LOW_POWER' or 'NXP_VREF_MODE_HIGH_POWER'
to enable the BUF21.

Signed-off-by: Zhaoxiang Jin <[email protected]>
Add dmas properties for lpadc node in nxp_mcxn23x_common.dtsi

Signed-off-by: Zhaoxiang Jin <[email protected]>
Adding DMA transfer capability to LPADC

Signed-off-by: Zhaoxiang Jin <[email protected]>
Enable DMA transfer of LPADC data in frdm_mcxn236

Signed-off-by: Zhaoxiang Jin <[email protected]>
@ZhaoxiangJin ZhaoxiangJin force-pushed the enable-lpadc-edma-feature branch from 4925d86 to 421bb34 Compare October 13, 2025 07:00
Copy link

@ZhaoxiangJin ZhaoxiangJin changed the title Enable lpadc edma feature Enable lpadc dma feature Oct 13, 2025
@ZhaoxiangJin
Copy link
Contributor Author

Hello @hakehuang, could you please help to test samples/adc/adc_dt for frdm_mcxn236 board? Thanks.

@hakehuang
Copy link
Contributor

hakehuang commented Oct 15, 2025

Hello @hakehuang, could you please help to test samples/adc/adc_dt for frdm_mcxn236 board? Thanks.

samples/adc/adc_dt/samples.yaml need add frdm_mcxn236 in platform_allow, besides, why tests/drivers/adc is not enabled for dma test in this platform? @ZhaoxiangJin

Copy link
Member

@decsny decsny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what's the point of this. This seems like an insane overcomplication of what is essentially reading one word. Previously, the CPU just reads the sample value from the register. Now, the CPU spends a ton of time to set up a DMA transfer to read still just one word from the register to a special one-word sized buffer, and then waits for DMA callback so that it can handle the dma interrupt from ADC driver, so that it can read the one word from the one-word buffer and restart the DMA transfer again. Can you explain what is the value of adding all this code, am I misunderstanding something?

return;
}

(void)dma_stop(config->dma_dev, config->dma_channel);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is return value ignored

Comment on lines +490 to +492
if (!data->use_dma) {
return;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like an unexpected situation, maybe log warning

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@decsny there is a warning down in the mcux_lpadc_init() function if use_dma is false when the Kconfig is true. The flag will not be changed any other time so not needing a log message here as it would overwhelm the output.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, this is the dma callback, which should only happen if dma is active, that's why it's unexpected and should log a warning

Comment on lines +540 to +554
if (data->ctx.sequence.resolution == 16) {
/* Keep raw 16-bit value; for differential, bit15 is sign. */
tmp = conv_result;
} else {
/* Right-align 12/13-bit payload from bit [3-14]. */
uint16_t value = (uint16_t)((conv_result >> 3) & 0xFFF);

if (is_diff && (conv_result & 0x8000)) {
/* 13-bit differential: apply two's complement sign
* using 12-bit magnitude.
*/
value = (uint16_t)(value - 0x1000);
}
tmp = value;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

turn this calculation into helper function

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? It only seems to be used in one place?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reduce cognitive complexity of this function

const struct device *dev = data->dev;
const struct mcux_lpadc_config *config = dev->config;

if (data->use_dma) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reverse the condition to if (!data->use_dma) { return; } to remove a level of nesting /cognitive complexity

@ZhaoxiangJin
Copy link
Contributor Author

ZhaoxiangJin commented Oct 15, 2025

I don't understand what's the point of this. This seems like an insane overcomplication of what is essentially reading one word. Previously, the CPU just reads the sample value from the register. Now, the CPU spends a ton of time to set up a DMA transfer to read still just one word from the register to a special one-word sized buffer, and then waits for DMA callback so that it can handle the dma interrupt from ADC driver, so that it can read the one word from the one-word buffer and restart the DMA transfer again. Can you explain what is the value of adding all this code, am I misunderstanding something?

Hello @decsny, in the zephyr samples, a sequence might only have one or two channels, but in real projects, many ADC channels might be used (this is why there are so many ADC channels in one SoC, for example, the MCXN236 has dozens of ADC channels). Without DMA, each channel's data would require an interrupt to retrieve it. If DMA is used, it can wait until all channels are converted, and then a single DMA callback is called. This operation reduces the number of ISRs and I think the overall efficiency will be improved.
Many ADCs can sample at rates up to 1M sps or even higher. At this sampling rate, DMA offers a greater advantage if there are many channels in a sequence. Furthermore, consider low-power scenarios. In tickless/low-power scenarios, DMA allows the core to sleep longer (the CPU doesn't have to wake up frequently to read registers), DMA wakes up the MCU after the transfer is complete, ultimately reducing energy consumption.

@decsny
Copy link
Member

decsny commented Oct 15, 2025

I am not talking about any sample, I'm talking about how your driver code works. Regardless of how many samples the application is doing, it looks like your code sets up a whole DMA transfer and callback for each 32 bit word. Do I misunderstand?

@ZhaoxiangJin
Copy link
Contributor Author

ZhaoxiangJin commented Oct 15, 2025

I am not talking about any sample, I'm talking about how your driver code works. Regardless of how many samples the application is doing, it looks like your code sets up a whole DMA transfer and callback for each 32 bit word. Do I misunderstand?

No, the callback will occur after channel_counts words have been transmitted. please check the dma configuration.

@dleach02
Copy link
Member

Hello @hakehuang, could you please help to test samples/adc/adc_dt for frdm_mcxn236 board? Thanks.

samples/adc/adc_dt/samples.yaml need add frdm_mcxn236 in platform_allow, besides, why tests/drivers/adc is not enabled for dma test in this platform? @ZhaoxiangJin

@ZhaoxiangJin to ensure regression test coverage, we want to do this testing from the tests/drivers/adc and ensure enablement of DMA for the specific target. Can you update your PR to include this.

@ZhaoxiangJin
Copy link
Contributor Author

Hello @hakehuang, could you please help to test samples/adc/adc_dt for frdm_mcxn236 board? Thanks.

samples/adc/adc_dt/samples.yaml need add frdm_mcxn236 in platform_allow, besides, why tests/drivers/adc is not enabled for dma test in this platform? @ZhaoxiangJin

@ZhaoxiangJin to ensure regression test coverage, we want to do this testing from the tests/drivers/adc and ensure enablement of DMA for the specific target. Can you update your PR to include this.

Hello @dleach02, yes, I will enable test for this board

@decsny
Copy link
Member

decsny commented Oct 16, 2025

I don't understand what's the point of this. This seems like an insane overcomplication of what is essentially reading one word. Previously, the CPU just reads the sample value from the register. Now, the CPU spends a ton of time to set up a DMA transfer to read still just one word from the register to a special one-word sized buffer, and then waits for DMA callback so that it can handle the dma interrupt from ADC driver, so that it can read the one word from the one-word buffer and restart the DMA transfer again. Can you explain what is the value of adding all this code, am I misunderstanding something?

Hello @decsny, in the zephyr samples, a sequence might only have one or two channels, but in real projects, many ADC channels might be used (this is why there are so many ADC channels in one SoC, for example, the MCXN236 has dozens of ADC channels). Without DMA, each channel's data would require an interrupt to retrieve it. If DMA is used, it can wait until all channels are converted, and then a single DMA callback is called. This operation reduces the number of ISRs and I think the overall efficiency will be improved. Many ADCs can sample at rates up to 1M sps or even higher. At this sampling rate, DMA offers a greater advantage if there are many channels in a sequence. Furthermore, consider low-power scenarios. In tickless/low-power scenarios, DMA allows the core to sleep longer (the CPU doesn't have to wake up frequently to read registers), DMA wakes up the MCU after the transfer is complete, ultimately reducing energy consumption.

I see I did misread a line and that the DMA transfer is for the number of channels. But I am still questioning the real value and "performance gain" of this code. It seems right now like we are doing this just to do it. Is there a specific requirement you are trying to meet (even if it's one you made up) that is clear about what actual benchmark/specification you are trying to accomplish and do you have testing proof that this actually meets it. Because right now, this is looking to me like a lot of new code and a new feature to maintain that I am not convinced of the real value yet, based on a hunch (you said you "think" the efficiency will be improved). Without real benchmarks and requirements, you could just as easily argue against this feature and say things like, it will increase latency and gaps in the ADC readings, it will cause the core to be awake for longer due to the complexity of setting up the DMA transfer and transferring the data between buffers with CPU at the end, I don't know. You are claiming it reduces energy consumption and improves efficiency, so where are the measurements of this.

@ZhaoxiangJin
Copy link
Contributor Author

ZhaoxiangJin commented Oct 16, 2025

I don't understand what's the point of this. This seems like an insane overcomplication of what is essentially reading one word. Previously, the CPU just reads the sample value from the register. Now, the CPU spends a ton of time to set up a DMA transfer to read still just one word from the register to a special one-word sized buffer, and then waits for DMA callback so that it can handle the dma interrupt from ADC driver, so that it can read the one word from the one-word buffer and restart the DMA transfer again. Can you explain what is the value of adding all this code, am I misunderstanding something?

Hello @decsny, in the zephyr samples, a sequence might only have one or two channels, but in real projects, many ADC channels might be used (this is why there are so many ADC channels in one SoC, for example, the MCXN236 has dozens of ADC channels). Without DMA, each channel's data would require an interrupt to retrieve it. If DMA is used, it can wait until all channels are converted, and then a single DMA callback is called. This operation reduces the number of ISRs and I think the overall efficiency will be improved. Many ADCs can sample at rates up to 1M sps or even higher. At this sampling rate, DMA offers a greater advantage if there are many channels in a sequence. Furthermore, consider low-power scenarios. In tickless/low-power scenarios, DMA allows the core to sleep longer (the CPU doesn't have to wake up frequently to read registers), DMA wakes up the MCU after the transfer is complete, ultimately reducing energy consumption.

I see I did misread a line and that the DMA transfer is for the number of channels. But I am still questioning the real value and "performance gain" of this code. It seems right now like we are doing this just to do it. Is there a specific requirement you are trying to meet (even if it's one you made up) that is clear about what actual benchmark/specification you are trying to accomplish and do you have testing proof that this actually meets it. Because right now, this is looking to me like a lot of new code and a new feature to maintain that I am not convinced of the real value yet, based on a hunch (you said you "think" the efficiency will be improved). Without real benchmarks and requirements, you could just as easily argue against this feature and say things like, it will increase latency and gaps in the ADC readings, it will cause the core to be awake for longer due to the complexity of setting up the DMA transfer and transferring the data between buffers with CPU at the end, I don't know. You are claiming it reduces energy consumption and improves efficiency, so where are the measurements of this.

@decsny, I've already provided my response, and I don't wish to engage in endless debate on this matter. If you insist on blocking this PR, I have no objection to closing it. However, I am certain that in the future, there will definitely be requests for this feature from SE/FAE/customers, because the same thing has happened many times in the SDK. It is quite surprising that the support for ADC DMA functionality is being questioned, even after I've explained so much.

@decsny
Copy link
Member

decsny commented Oct 16, 2025

I don't want to have an endless debate either. I asked for numbers that are backing up your claims that this code is improving something. I'm not fundamentally against this, but you should be able to have evidence of your claims, otherwise I don't want to be adding code just for the sake of it. The only reason we would have an endless debate is if those numbers were never produced and we went in circles talking about guesses and hunches, which is exactly what I don't want to be doing things based on, because I don't want to be wasting time and effort, which are very precious resources.

In fact, if people are requesting it, that is promising for this PR, because it means there must be specific requirements that you are trying to meet?

@ZhaoxiangJin
Copy link
Contributor Author

I don't want to have an endless debate either. I asked for numbers that are backing up your claims that this code is improving something. I'm not fundamentally against this, but you should be able to have evidence of your claims, otherwise I don't want to be adding code just for the sake of it. The only reason we would have an endless debate is if those numbers were never produced and we went in circles talking about guesses and hunches, which is exactly what I don't want to be doing things based on, because I don't want to be wasting time and effort, which are very precious resources.

In fact, if people are requesting it, that is promising for this PR, because it means there must be specific requirements that you are trying to meet?

Why do you always say I'm adding code just for the sake of adding code? Do you think I've really wasted so much time? I've already theoretically explained the advantages of DMA transfer, and there's no need for me to spend more time designing a case study to demonstrate the advantages of DMA transfer in a practical project. In my opinion, you haven't carefully read the code and my response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants