Hi all,
How does the DMA asynchronous wake up work?
It takes a bit longer than i expected but im not sure ive got the full picture.
e.g. below i have guessed that section 4+5 is the bus clock booting up, then 6+7 is the DMA getting ready, why does it take 4.3~4us at 48MHz? (equivalent of >200 cycles).
Does it have to wake up the flash through the flash controller (i.e. it doesn't know if it might have to access flash?)
and if so, can it be configured to let it know it wont access flash, so it starts up quicker?
Im using K22 freedom board. i have code working where the ADC wakes up the DMA (from VLPS mode) to move the result. the DMA is using the bus clock at 48MHz or 4MHz. The DMA is dominating the time/energy.
from attached picture (green trace is current monitor on Vdd), i have verified 1 and 2 are adc sampling and processing, but not sure my explanation below for the rest of the sections are correct?
(There is no other isr/wakeup except the dma loop complete (every 512 times). the scope is triggered from the current trace and heavily averaged, so this is negligible) . the blue trace shows the ADC pin at 2mV/div ac coupled.
section 8 is around 1.2us for bus=48MHz, and 9~11us for bus=4MHz
1 ADC Sampling
2 ADC Converting
3 ADC Processing
4 Bus clock booting up from datasheet: IRC48 takes 2-3us to start. Pulse current starting up flash?
5 " " "
6 DMA booting up
7 " " "
8 DMA complete actions This section is roughly the actual DMA active time
9 " " " 9 and 10 are time constants of the circuit. To be used
10 " " " for integrating current, but not for estimate of DMA time
if anyone has an idea of alternatives for these sections it would be very helpful.
Thanks,
Michael.
Hi
Could you provide the ADC module initialization code?
The MK22FN512VLH12 Reference manual chapter 7.2.2 DMA Wakeup shows the detailed info about DMA Async Operation.
Thank you for the attention.
Have a great day,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi,
Thanks. this is the ADC init code:
/*!
* @brief setup ADC trigger from LPTMR*/
void APP_ADC0_ConfigTriggerSource(void)
{
/* clear ADC0 setup
* Pre-trig A default. maybe use B later.
*/
SIM->SOPT7 &= 0xFFFFFF00U;
/* Configure SIM for ADC hw trigger source selection */
SIM->SOPT7 |= SIM_SOPT7_ADC0ALTTRGEN_MASK | SIM_SOPT7_ADC0TRGSEL(0xEU);
}/*!
* @brief simpler ADC init.
* Setup configuration before calibration (hw trig / channel(?) is ignored)
* HSC, LPC, CLK, conv/sampl times important for cal.
* @param base (ADC0 or 1), hwTrig = true for hardware triggering, false for s/w
*/
bool APP_InitADC(ADC_Type *base, bool hwTrig)
{
/******************************************************
* Initialization ADC for 16bit resolution, interrupt mode,
* hw trigger enabled. normal convert speed, VREFH/L as reference,
* disable continuous convert mode.
*******************************************************/
/*
* adcUserConfig.referenceVoltageSource = kADC16_ReferenceVoltageSourceVref;
* adcUserConfig.clockSource = kADC16_ClockSourceAsynchronousClock;
* adcUserConfig.enableAsynchronousClock = true;
* adcUserConfig.clockDivider = kADC16_ClockDivider8;
* adcUserConfig.resolution = kADC16_ResolutionSE12Bit;
* adcUserConfig.longSampleMode = kADC16_LongSampleDisabled;
* adcUserConfig.enableHighSpeed = false;
* adcUserConfig.enableLowPower = false;
* adcUserConfig.enableContinuousConversion = false;
*/
ADC16_GetDefaultConfig(&g_APP_Adc_Config_Setup);
g_APP_Adc_Config_Setup.resolution = kADC16_ResolutionSE12Bit; //12b single-ended
g_APP_Adc_Config_Setup.clockSource = kADC16_ClockSourceAsynchronousClock; //ADACK
g_APP_Adc_Config_Setup.clockDivider = kADC16_ClockDivider1; // div by 1
g_APP_Adc_Config_Setup.longSampleMode = kADC16_LongSampleDisabled; //Short sample (4 cyc)
g_APP_Adc_Config_Setup.enableLowPower = false; //Low power ADACK TYP = 2.4MHz
//or normal, typ = 5.2MHz
g_APP_Adc_Config_Setup.enableAsynchronousClock = false; //Auto-wake mode.
ADC16_Init(base, &g_APP_Adc_Config_Setup);/* enabled/disable hardware trigger */
ADC16_EnableHardwareTrigger(base, hwTrig);
ADC16_SetHardwareAverage(base,kADC16_HardwareAverageDisabled);
/*! Do calibration. @todo - what about OFS? */
ADC16_DoAutoCalibration(base);
/******************************************************
* Setup Channel Config
*******************************************************/
g_APP_Adc_Channel_Setup.channelNumber = APP_ADC16_USER_CHANNEL;
#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
g_APP_Adc_Channel_Setup.enableDifferentialConversion = false;
#endif
g_APP_Adc_Channel_Setup.enableInterruptOnConversionCompleted = false;
/* Setup the channel, ready for conversions */
if(hwTrig)
{
/* Configure channel 0 */
ADC16_SetChannelConfig(base, APP_ADC16_CHANNEL_GROUP, &g_APP_Adc_Channel_Setup);
}
//else calling set channel starts a conversion, do later.
return true;
}
I also call these after setting up the ADC:
ADC16_EnableDMA(APP_ADC16_BASEADDR, true);
SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK; //DMAMUX Clock Gate
DMACH0_CH1_Init();
Hi Michael,
I got the feedback from Kinetis product team:
There without user access to DMA wake up processing.
Customer can not set the DMA wake up processing.
Wish it helps.
Have a great day,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Michael,
Sorry for the later reply.
About DMA wakeup setting, I need to check with the Kinetis product team.
I will let you know when there with any feedback.
Thank you for the patience.
best regards,
Hui