AnsweredAssumed Answered

ADC scan on l series Kinetis

Question asked by Christian Lees on Nov 29, 2018
Latest reply on Dec 4, 2018 by Jorge Antonio Alcala Vazquez

I'attempting to get ADC channel scanning to work on a MKL17Z256.  There are examples of how to do it on a K series but not for the L series which has a different DMA controller.

 

I'm assuming it is possible in the same way using 2 DMA channels,  one loading the ADC channel and the other copying the data out.

 

Following is what I have but it is not working.  I'm not sure if I have the channel linking configured correctly

 

 

static void DMA_Callback_0(dma_handle_t *handle, void *userData)
{
uint32_t flags = DMA_GetChannelStatusFlags(DMA0, 0);
PRINTF("Flag 0: %u\r\n", flags);
DMA_ClearChannelStatusFlags(DMA0, 0, kDMA_TransactionsDoneFlag);


static void DMA_Callback_1(dma_handle_t *handle, void *userData)
{
uint32_t flags = DMA_GetChannelStatusFlags(DMA0, 1);
PRINTF("Flag 1: %u\r\n", flags);
if(flags & kDMA_TransactionsDoneFlag)
{

DMA_SubmitTransfer(&g_DMA_Handle_0, &transferConfig_0, kDMA_EnableInterrupt);
DMA_StartTransfer(&g_DMA_Handle_0);

DMA_SubmitTransfer(&g_DMA_Handle_1, &transferConfig_1, kDMA_EnableInterrupt);
DMA_StartTransfer(&g_DMA_Handle_1);

PRINTF("!");
DMA_ClearChannelStatusFlags(DMA0, 1, kDMA_TransactionsDoneFlag);
}

}

void adc_init()
{
//EnableIRQ(ADC0_IRQn);

adc16_config_t adc16ConfigStruct;
adc16_channel_config_t adc16ChannelConfigStruct;
/*
* adc16ConfigStruct.referenceVoltageSource = kADC16_ReferenceVoltageSourceVref;
* adc16ConfigStruct.clockSource = kADC16_ClockSourceAsynchronousClock;
* adc16ConfigStruct.enableAsynchronousClock = true;
* adc16ConfigStruct.clockDivider = kADC16_ClockDivider8;
* adc16ConfigStruct.resolution = kADC16_ResolutionSE12Bit;
* adc16ConfigStruct.longSampleMode = kADC16_LongSampleDisabled;
* adc16ConfigStruct.enableHighSpeed = false;
* adc16ConfigStruct.enableLowPower = false;
* adc16ConfigStruct.enableContinuousConversion = false;
*/
ADC16_GetDefaultConfig(&adc16ConfigStruct);
adc16ConfigStruct.resolution = kADC16_Resolution16Bit;
adc16ConfigStruct.enableContinuousConversion = true;
adc16ConfigStruct.clockSource = kADC16_ClockSourceAlt1;

adc16ConfigStruct.longSampleMode = kADC16_LongSampleCycle24;
adc16ConfigStruct.enableLowPower = true;

 

ADC16_Init( ADC0, &adc16ConfigStruct);

ADC16_DoAutoCalibration( ADC0 );

ADC16_EnableHardwareTrigger( ADC0, true);
ADC16_EnableDMA( ADC0, true);

adc16ChannelConfigStruct.channelNumber = g_ADC_mux[6];
adc16ChannelConfigStruct.enableInterruptOnConversionCompleted = true; /* Enable the interrupt. */
adc16ChannelConfigStruct.enableDifferentialConversion = false;
ADC16_SetChannelConfig( ADC0, 0, &adc16ChannelConfigStruct);

/* Configure SIM for ADC hw trigger source selection */
SIM->SOPT7 |= 0x8EU; // LPTMR, 1kHz
}

void dma_init()
{
/****************************************
* DMA Config
****************************************/

/* Configure DMAMUX */
DMAMUX_Init(DMAMUX0);

DMAMUX_SetSource(DMAMUX0, DMAChannel_0, 60); /* Channel 0 Source 60: DMA always enabled */
DMAMUX_EnableChannel(DMAMUX0, DMAChannel_0);

DMAMUX_SetSource(DMAMUX0, DMAChannel_1, 40); /* Channel 1 Source 40: ADC COCO trigger */
DMAMUX_EnableChannel(DMAMUX0, DMAChannel_1);

DMA_Init(DMA0);
DMA_CreateHandle(&g_DMA_Handle_0, DMA0, 0);
DMA_SetCallback(&g_DMA_Handle_0, DMA_Callback_0, NULL);

DMA_CreateHandle(&g_DMA_Handle_1, DMA0, 1);
DMA_SetCallback(&g_DMA_Handle_1, DMA_Callback_1, NULL);

DMA_PrepareTransfer(&transferConfig_0,
&g_ADC_mux[0], /* Source Address (ADC channels array) */
1, /* Source width (1 bytes) */
(uint32_t*)(ADC0->SC1),/* Destination Address (ADC_SC1A_ADCH)*/
1, /* Destination width (1 bytes) */
//sizeof(uint8_t), /* Bytes to transfer each minor loop (1 bytes) */
7, /* Total of bytes to transfer (3*1 bytes) */
kDMA_MemoryToPeripheral);/* From ADC channels array to ADCH register */

DMA_PrepareTransfer(&transferConfig_1,
(uint32_t*) (ADC0->R), /* Source Address (ADC0_RA) */
2, /* Source width (2 bytes) */
g_ADC0_resultBuffer, /* Destination Address (Internal buffer)*/
2, /* Destination width (2 bytes) */
//sizeof(uint16_t), /* Bytes to transfer each minor loop (2 bytes) */
B_SIZE * 2, /* Total of bytes to transfer (12*2 bytes) */
kDMA_PeripheralToMemory); /* From ADC to Memory */

DMA_SubmitTransfer(&g_DMA_Handle_0, &transferConfig_0, kDMA_EnableInterrupt);
DMA_SubmitTransfer(&g_DMA_Handle_1, &transferConfig_1, kDMA_EnableInterrupt);


link1.channel1 = 0;
link1.channel2 = 0;
link1.linkType = kDMA_ChannelLinkChannel1;
DMA_SetChannelLinkConfig(DMA0, 1, &link1);

DMA_StartTransfer(&g_DMA_Handle_1);

}

void adc_dma_init()
{

dma_init();
adc_init();
}

Outcomes