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();
}