使用dma方式采集adc数据

公告

大中华汽车电子生态圈社区并入开发者社区- 更多资讯点击此

Tip / 登入 to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
kobot
Level 1
Level 1
First reply posted First question asked First like given

芯片:cyt4bf

我使用dma的方式采集adc数据,运行以下程序没有反应。我在调试模式下,查看srcAddr 的数据,发现数据已经采集到了,而且一直在变化。有没有人能看下有没有什么问题,这段程序是根据官方手册上写的,只改了TRIG_OUT_1TO1_1_PASS_CH_DONE_TO_PDMA031这个触发器。我觉得是这个触发器的问题,我该如何发现问题。

I use DMA to collect adc data, but there is no response when I run the following program. I checked the data of srcAddr in the debug mode and found that the data has been collected and it has been changing. Can anyone see if there is any problem? This program is based on the official manual, only the trigger TRIG_OUT_1TO1_1_PASS_CH_DONE_TO_PDMA031 is changed.I think it is the problem of this trigger, how can I find the problem.

#include "cy_project.h"
#include "cy_device_headers.h"

#define ADC_MACRO PASS0_SAR0
#define ADC_GROUP_NUMBER_OF_CHANNELS (32ul)


/* ADC logical channel to be used */
#define ADC_GROUP_FIRST_CHANNEL (0ul)
#define ADC_GROUP_LAST_CHANNEL (ADC_GROUP_FIRST_CHANNEL + ADC_GROUP_NUMBER_OF_CHANNELS - 1ul)
#define ADC_CH_INTR_BASE pass_0_interrupts_sar_0_IRQn
#define BUFFER_SIZE_IN_WORD (32*50ul) //adc0 32channel, collect 50 datas per channel in 50ms.
#define BUFFER_SIZE_IN_BYTE (BUFFER_SIZE_IN_WORD * 4ul)


#define DW_CHANNEL 27ul
#define DW_CH_INTR cpuss_interrupts_dw0_27_IRQn
#define ADC_TO_DMA_TRIG TRIG_OUT_1TO1_1_PASS_CH_DONE_TO_PDMA031

static uint32_t adc_DestBuffer[BUFFER_SIZE_IN_BYTE] = {0ul};

static cy_stc_pdma_descr_t stcDescr;

static const cy_stc_pdma_chnl_config_t chnlConfig =
{
.PDMA_Descriptor = &stcDescr,
.preemptable = 0ul,
.priority = 0ul,
.enable = 1ul,
};


static const cy_stc_pdma_descr_config_t stcDmaDescrConfig =
{
.deact = 0ul,
.intrType = CY_PDMA_INTR_DESCR_CMPLT,
.trigoutType = CY_PDMA_TRIGOUT_DESCR_CMPLT,
.chStateAtCmplt = CY_PDMA_CH_ENABLED,
.triginType = CY_PDMA_TRIGIN_XLOOP,
.dataSize = CY_PDMA_WORD,
.srcTxfrSize = 0ul, /* as specified in DATA_SIZE */
.destTxfrSize = 0ul, /* as specified in DATA_SIZE */
.descrType = CY_PDMA_2D_TRANSFER,
.srcAddr = (void *)&ADC_MACRO->CH[ADC_GROUP_FIRST_CHANNEL].unRESULT.u32Register,
.destAddr = (void *)adc_DestBuffer,
.srcXincr = 16ul, /* address +40h */
.destXincr = 50ul, /* 50 datas of per channel */
.xCount = ADC_GROUP_NUMBER_OF_CHANNELS,
.srcYincr = 0ul, /* Not increments */
.destYincr = 1ul, /* Destination address +4h */
.yCount = 50ul, /* Store results for 50 times */
.descrNext = &stcDescr
};


static const cy_stc_sysint_irq_t stc_sysint_irq_cfg =
{
.sysIntsrc=DW_CH_INTR,
.intIdx = CPUIntIdx2_IRQn,
.isEnabled = true,
};

void DW0_Ch_IntHandler(void)
{
uint32_t masked;
masked = Cy_PDMA_Chnl_GetInterruptStatusMasked(DW0, DW_CHANNEL);
if ((masked & CY_PDMA_INTRCAUSE_COMPLETION) != 0ul)
{
/* Clear Complete DMA interrupt flag */
Cy_PDMA_Chnl_ClearInterrupt(DW0, DW_CHANNEL);
/* Read the port status */
}
else
{
CY_ASSERT(false);
}
}


void DW0_Ch_IntHandler(void);
void adcPDMAInit(void)
{
/* Initialize & Enable DW */
Cy_PDMA_Disable(DW0);
Cy_PDMA_Chnl_DeInit(DW0, DW_CHANNEL);
Cy_PDMA_Descr_Init(&stcDescr,&stcDmaDescrConfig);
Cy_PDMA_Chnl_Init(DW0, DW_CHANNEL, &chnlConfig);
Cy_PDMA_Chnl_Enable(DW0, DW_CHANNEL);
Cy_PDMA_Chnl_SetInterruptMask(DW0, DW_CHANNEL);
Cy_PDMA_Enable(DW0);
/* Trigger MUX */
Cy_TrigMux_Connect1To1(ADC_TO_DMA_TRIG, CY_TR_MUX_TR_INV_DISABLE, TRIGGER_TYPE_EDGE, 0ul);
/* Interrupt Initialization */
Cy_SysInt_InitIRQ(&stc_sysint_irq_cfg);
Cy_SysInt_SetSystemIrqVector(stc_sysint_irq_cfg.sysIntSrc, DW0_Ch_IntHandler);
NVIC_SetPriority(stc_sysint_irq_cfg.intIdx, 0ul);
NVIC_EnableIRQ(stc_sysint_irq_cfg.intIdx);
/* Issue SW trigger */
Cy_Adc_Channel_SoftwareTrigger(&ADC_MACRO->CH[ADC_GROUP_FIRST_CHANNEL]); //has been called in period function.
}

0 点赞
1 解答
yanf
Moderator
Moderator
Moderator
50 replies posted 50 sign-ins 25 solutions authored

Hi kobot,

To use DMA with ADC, they have to be connected internally using trigger mux. For example, you are using ADC SAR0 logical channel 0, in this case, DW_CHANNEL should be 47 and the ADC_TO_DMA_TRIG should be TRIG_OUT_1TO1_1_PASS_CH_DONE_TO_PDMA00.

You can find their relationship on datasheet, Chapter 18. 

https://www.cypress.com/documentation/datasheets/cyt4bf-datasheet-32-bit-arm-cortex-m7-microcontroll...

 

Best Regards,

Finn

在原帖中查看解决方案

0 点赞
2 回复数
yanf
Moderator
Moderator
Moderator
50 replies posted 50 sign-ins 25 solutions authored

Hi kobot,

To use DMA with ADC, they have to be connected internally using trigger mux. For example, you are using ADC SAR0 logical channel 0, in this case, DW_CHANNEL should be 47 and the ADC_TO_DMA_TRIG should be TRIG_OUT_1TO1_1_PASS_CH_DONE_TO_PDMA00.

You can find their relationship on datasheet, Chapter 18. 

https://www.cypress.com/documentation/datasheets/cyt4bf-datasheet-32-bit-arm-cortex-m7-microcontroll...

 

Best Regards,

Finn

0 点赞
yanf
Moderator
Moderator
Moderator
50 replies posted 50 sign-ins 25 solutions authored

Hi kobot,

A code example has been created regarding using DMA to acquire ADC data.

https://community.infineon.com/t5/Resource-Library/Sample-code-for-ADC-DMA-for-Traveo-II-AutoMCU/ta-...

I am going to close this case now. Should you have other question, feel free to post a new question.

Best Regards,

Finn