Hi All,
I have been trying to configure PDB/ADC/DMA chain. I achieved PDB and ADC related configuration. PDB is working in one-shot mode for debugging. I saw that ADC conversion is done when I start PDB timer. I also manage configuring DMA to copy memory to memory with manual start but I can't do it for ADC0 to memory.
I am using K64F, Kinetis SDK 1.20, Processor Expert. Could you please check the configuration code and point what I am missing?
Thanks in Advance
Serdar
// ADC Config
const adc16_converter_config_t adc_InitConfig0 = {
.lowPowerEnable = false,
.clkDividerMode = kAdc16ClkDividerOf1,
.longSampleTimeEnable = true,
.resolution = kAdc16ResolutionBitOfSingleEndAs12,
.clkSrc = kAdc16ClkSrcOfBusClk,
.asyncClkEnable = false,
.highSpeedEnable = false,
.longSampleCycleMode = kAdc16LongSampleCycleOf24,
.hwTriggerEnable = true,
.refVoltSrc = kAdc16RefVoltSrcOfVref,
.continuousConvEnable = false,
.dmaEnable = true,
};
const adc16_hw_cmp_config_t adc_HwConfig0 = {
.hwCmpEnable = false,
.hwCmpGreaterThanEnable = false,
.hwCmpRangeEnable = false,
.cmpValue1 = 0U,
.cmpValue2 = 0U,
};
const adc16_chn_config_t adc_ChnConfig0 = {
.chnIdx = kAdc16Chn14,
.convCompletedIntEnable = false,
.diffConvEnable = false
};
// PDB config
pdb_timer_config_t adcTimer_InitConfig1 = {
.loadValueMode = kPdbLoadValueImmediately,
.seqErrIntEnable = false,
.clkPreDiv = kPdbClkPreDivBy128,
.clkPreMultFactor = kPdbClkPreMultFactorAs1,
.triggerInput = kPdbSoftTrigger,
.continuousModeEnable = false,
.dmaEnable = false,
.intEnable = true,
};
// EDMA config
const edma_user_config_t dmaController1_InitConfig0 = {
.chnArbitration = kEDMAChnArbitrationRoundrobin,
.notHaltOnError = false,
};
// init
ADC16_DRV_Deinit(FSL_ADC);
ADC16_DRV_Init(FSL_ADC, &adc_InitConfig0);
ADC16_DRV_ConfigConvChn(FSL_ADC, 0U, &adc_ChnConfig0);
PDB_DRV_Deinit(FSL_ADCTIMER);
PDB_DRV_Init(FSL_ADCTIMER, &adcTimer_InitConfig1);
//
PDB_DRV_ConfigAdcPreTrigger(FSL_ADCTIMER, 0, &adcTimer_AdcTrigInitConfig0);
PDB_DRV_SetTimerModulusValue(FSL_ADCTIMER, 0xFFFU);
PDB_DRV_SetValueForTimerInterrupt(FSL_ADCTIMER, 0xFFFU);
PDB_DRV_LoadValuesCmd(FSL_ADCTIMER);
// Configure SIM for ADC hw trigger source PDB
SIM_HAL_SetAdcAlternativeTriggerCmd(gSimBase[0], FSL_ADC, false);
EDMA_DRV_Deinit();
EDMA_DRV_Init(&dmaController1_State, &dmaController1_InitConfig0);
// EDMA channel request.
edmaStatus = EDMA_DRV_RequestChannel(channel, kDmaRequestMux0ADC0, &chnState);
edma_transfer_config_t configDMA; // FIXME cikart buradan
edma_software_tcd_t stcdDmaChn0;
// Configure DMA
configDMA.srcAddr = (uint32_t) (&ADC0_RA);
configDMA.destAddr = (uint32_t) (images[0]);
configDMA.srcTransferSize = kEDMATransferSize_2Bytes; // Source data transfer size.
configDMA.destTransferSize = kEDMATransferSize_2Bytes; // Destination data transfer size.
configDMA.srcOffset = 0;
configDMA.destOffset = 2;
configDMA.srcLastAddrAdjust = 0; // Last source address adjustment.
configDMA.destLastAddrAdjust = 2; /*!< Last destination address adjustment. Note here it is only valid when scatter/gather feature is not enabled. */
configDMA.srcModulo = kEDMAModuloDisable; // Source address modulo. FIXME: bu ne
configDMA.destModulo = kEDMAModuloDisable; // Destination address modulo.
configDMA.minorLoopCount = 1; // Minor bytes transfer count. Number of bytes to be transferred in each service request of the channel.
configDMA.majorLoopCount = 1; // Major iteration count.
edmaStatus = EDMA_DRV_PrepareDescriptorTransfer(&chnState, &stcdDmaChn0, &configDMA, true, false);
if (edmaStatus == kStatus_EDMA_Success)
edmaStatus = EDMA_DRV_PushDescriptorToReg(&chnState, &stcdDmaChn0);
// Install callback for eDMA handler
edmaStatus = EDMA_DRV_InstallCallback(&chnState, edma_isr_callback, NULL);
Hello serdar,
You said the PDB trigger the ADC can work well , while the DMA can not transfer ADC result ,
so i think maybe the DMA configure have some error , please check the register "DMA_ES".
(1) When using the eDMA you have to respect its rules:
- all source and destination addresses MUST be aligned (if using 32 bits the last 2 bits of the address MUST bei 00) - check UART_RINGBUFFER address.
- also the transfer count MUST match with the transfer width. If using 32 bit width the total size must be a multiple of this value (4, 8, 12, 16, 20 etc.) If not there will be an error and an abort.
Always check what the error register is telling you - it tells you the reason and whether it was due to the destination or the source. Then you should be able to see why and correct it. (It quoted from my colleague Mark Butcher )
(2) About use the PDB trigger ADC , the use DMA transfer data , you can refer to this demo :
PIT- ADC- DMA Example for FRDM-KL25z, FRDM-K64F, TWR-K60D100 and TWR-K70 "
Hope it helps
Have a great day,
Alice Yang
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
HI Alice,
I realized that minor count should be 2 in my configuration. After updating that, DMA is working at the first trigger but not continue although ADC conversions exist.
To understand cause of DMA error/inconstancy which exact registers should I look?
Could you please check my configuration, is there any missing point?
Thanks,
Serdar
Hello Serdar,
- First you need check the register " Error Status Register (DMA_ES) "
- I think here have problem when configure the destination address :
the images[0] is a address ?
- and this
,
i think the smallest data should be 2 , or 4 , 6, ...
- And first i recommend you not enable the DMA interrupt , when the dma can work well , then configure the interrupt.
BR
Alice