Thanks for coming back, @myke_predko! Sorry for the confusion. Please be patient with me; this whole DMA and large data hustle in general is quite new to me. Also I took over this project with quite a large code base already existing, so it's not unlikely I haven't got hold of some details yet.
I'm still not 100% sure what you mean, but the container is declared to be in RAM2. which starts at 0x1FFF'0000 and barely fits the section; the buffer size is 0xFF80 while the size of RAM2 is 0x1'0000. I have verified at runtime that &dataset indeed starts 0x1FFF'0000. Is that what you mean?
TPM timers are configured to trigger both the ADC conversion as well as the DMA requests (at least that's the intention), but maybe it's best if a provide the ADC and DMA code sections:
static void TPM_Configuration(adc_samplerate_e sample_rate)
{
/* configure ADC0/ADC1 alternate trigger via TPM */
tmp32 = SIM->SOPT7 & ~(SIM_SOPT7_ADC0TRGSEL_MASK | SIM_SOPT7_ADC1TRGSEL_MASK);
tmp32 |= SIM_SOPT7_ADC1ALTTRGEN_MASK | SIM_SOPT7_ADC1TRGSEL(15U) | SIM_SOPT7_ADC0ALTTRGEN_MASK | SIM_SOPT7_ADC0TRGSEL(15U);
SIM->SOPT7 = tmp32;
tpm_config_t tpmConfig;
CLOCK_SetTpmClock(1U);
CLOCK_SetPllFllSelClock(1,0,0);
TPM_GetDefaultConfig(&tpmConfig);
TPM_Init(TPM1, &tpmConfig);
TPM_Init(TPM2, &tpmConfig);
TPM_SetTimerPeriod(TPM1, NSEC_TO_COUNT(800U, CLOCK_GetFreq(kCLOCK_PllFllSelClk)));
TPM_SetTimerPeriod(TPM2, NSEC_TO_COUNT(800U, CLOCK_GetFreq(kCLOCK_PllFllSelClk)));
TPM_SetupOutputCompare(TPM1, kTPM_Chnl_0, kTPM_HighPulseOutput, 0U);
TPM_SetupOutputCompare(TPM1, kTPM_Chnl_1, kTPM_HighPulseOutput, NSEC_TO_COUNT(400U, CLOCK_GetFreq(kCLOCK_PllFllSelClk)));
TPM_SetupOutputCompare(TPM2, kTPM_Chnl_0, kTPM_HighPulseOutput, 0U);
TPM_SetupOutputCompare(TPM2, kTPM_Chnl_1, kTPM_HighPulseOutput, NSEC_TO_COUNT(400U, CLOCK_GetFreq(kCLOCK_PllFllSelClk)));
TPM1->CONTROLS[kTPM_Chnl_0].CnSC |= TPM_CnSC_DMA_MASK;
TPM1->CONTROLS[kTPM_Chnl_1].CnSC |= TPM_CnSC_DMA_MASK;
TPM2->CONTROLS[kTPM_Chnl_0].CnSC |= TPM_CnSC_DMA_MASK;
TPM2->CONTROLS[kTPM_Chnl_1].CnSC |= TPM_CnSC_DMA_MASK;
TPM_EnableInterrupts(TPM1, kTPM_TimeOverflowInterruptEnable); // only for the mentioned debugging
EnableIRQ(TPM1_IRQn); // only for the mentioned debugging
}
static void ADC16_Configuration(void)
{
adc16_config_t adcConfig;
adc16_channel_config_t adcChannelConfig;
ADC16_GetDefaultConfig(&adcConfig);
adcConfig.clockDivider = kADC16_ClockDivider1;
adcConfig.clockSource = kADC16_ClockSourceAlt0;
adcConfig.enableHighSpeed = true;
adcConfig.longSampleMode = kADC16_LongSampleCycle6;
adcConfig.resolution = kADC16_ResolutionSE12Bit;
adcConfig.enableContinuousConversion = false;
ADC16_Init(ADC0, &adcConfig);
ADC16_Init(ADC1, &adcConfig);
ADC16_EnableHardwareTrigger(ADC0, true);
ADC16_EnableHardwareTrigger(ADC1, true);
adcChannelConfig.enableDifferentialConversion = false;
adcChannelConfig.enableInterruptOnConversionCompleted = false;
adcChannelConfig.channelNumber = ADC0_CHANNEL_I1;
ADC16_SetChannelConfig(ADC0, 0U, &adcChannelConfig);
adcChannelConfig.channelNumber = ADC0_CHANNEL_Q1;
ADC16_SetChannelConfig(ADC0, 1U, &adcChannelConfig);
adcChannelConfig.channelNumber = ADC1_CHANNEL_I2;
ADC16_SetChannelConfig(ADC1, 0U, &adcChannelConfig);
adcChannelConfig.channelNumber = ADC1_CHANNEL_Q2;
ADC16_SetChannelConfig(ADC1, 1U, &adcChannelConfig)
}
static void DMAMUX_Configuration(void)
{
DMAMUX_Init(DMAMUX0);
DMAMUX_SetSource(DMAMUX0, ADC0_CHANNEL10_EDMA0, 28U);
DMAMUX_SetSource(DMAMUX0, ADC0_CHANNEL11_EDMA1, 29U);
DMAMUX_SetSource(DMAMUX0, ADC1_CHANNEL10_EDMA2, 30U);
DMAMUX_SetSource(DMAMUX0, ADC1_CHANNEL11_EDMA3, 31U);
DMAMUX_EnableChannel(DMAMUX0, ADC0_CHANNEL10_EDMA0);
DMAMUX_EnableChannel(DMAMUX0, ADC0_CHANNEL11_EDMA1);
DMAMUX_EnableChannel(DMAMUX0, ADC1_CHANNEL10_EDMA2);
DMAMUX_EnableChannel(DMAMUX0, ADC1_CHANNEL11_EDMA3);
}
static void EDMA_Configuration(void)
{
EDMA_GetDefaultConfig(&edmaConfig);
EDMA_Init(DMA0, &edmaConfig);
EDMA_CreateHandle(&g_edmaHandle[ADC0_CHANNEL10_EDMA0], DMA0, ADC0_CHANNEL10_EDMA0);
EDMA_CreateHandle(&g_edmaHandle[ADC0_CHANNEL11_EDMA1], DMA0, ADC0_CHANNEL11_EDMA1);
EDMA_CreateHandle(&g_edmaHandle[ADC1_CHANNEL10_EDMA2], DMA0, ADC1_CHANNEL10_EDMA2);
EDMA_CreateHandle(&g_edmaHandle[ADC1_CHANNEL11_EDMA3], DMA0, ADC1_CHANNEL11_EDMA3);
EDMA_SetCallback(&g_edmaHandle[ADC0_CHANNEL10_EDMA0], EDMA_Callback, (void *) ADC0_CHANNEL10_EDMA0);
EDMA_SetCallback(&g_edmaHandle[ADC0_CHANNEL11_EDMA1], EDMA_Callback, (void *) ADC0_CHANNEL11_EDMA1);
EDMA_SetCallback(&g_edmaHandle[ADC1_CHANNEL10_EDMA2], EDMA_Callback, (void *) ADC1_CHANNEL10_EDMA2);
EDMA_SetCallback(&g_edmaHandle[ADC1_CHANNEL11_EDMA3], EDMA_Callback, (void *) ADC1_CHANNEL11_EDMA3);
EDMA_PrepareTransfer(&edmaTransferConfig,
(void *)&ADC0->R[0U],
sizeof(uint16_t),
(void *)&dataset.RX1.chirp[0].IQ_pair[0].I,
sizeof(uint16_t),
sizeof(uint16_t),
sizeof(uint16_t)*SAMPLES_PER_CHIRP, kEDMA_PeripheralToMemory);
EDMA_SubmitTransfer(&g_edmaHandle[ADC0_CHANNEL10_EDMA0], &edmaTransferConfig);
DMA0->TCD[ADC0_CHANNEL10_EDMA0].DLAST_SGA = -(sizeof(uint16_t)*SAMPLES_PER_CHIRP);
DMA0->TCD[ADC0_CHANNEL10_EDMA0].DOFF = 4;
DMA0->TCD[ADC0_CHANNEL10_EDMA0].CSR &= ~DMA_CSR_DREQ_MASK; // don't disable DMA REQ line
...
EDMA_EnableChannelInterrupts(DMA0, ADC0_CHANNEL10_EDMA0, kEDMA_HalfInterruptEnable);
EDMA_EnableChannelInterrupts(DMA0, ADC0_CHANNEL11_EDMA1, kEDMA_HalfInterruptEnable);
EDMA_EnableChannelInterrupts(DMA0, ADC1_CHANNEL10_EDMA2, kEDMA_HalfInterruptEnable);
EDMA_EnableChannelInterrupts(DMA0, ADC1_CHANNEL11_EDMA3, kEDMA_HalfInterruptEnable);
}
I start the sampling and transfer via
EDMA_StartTransfer(&g_edmaHandle[ADC0_CHANNEL10_EDMA0]);
EDMA_StartTransfer(&g_edmaHandle[ADC0_CHANNEL11_EDMA1]);
EDMA_StartTransfer(&g_edmaHandle[ADC1_CHANNEL10_EDMA2]);
EDMA_StartTransfer(&g_edmaHandle[ADC1_CHANNEL11_EDMA3]);
TPM_StartTimer(TPM1, kTPM_SystemClock);
TPM_StartTimer(TPM2, kTPM_SystemClock);