2008-09-15 11:57 PM
Problem ARM912: DMA and ADC sems not working
2011-05-17 12:55 AM
Hi all,
I try to connect my ADC with a DMA access to push in memory, the result of a unique channel, but for an important number of sample .Problem:
When i read the register DDR, in my ADC interrupt
the registre DDR (ADC->DDR) is always 0.This register should receive something else... Especially because my channel 5 receive something like 1.5-2v. I can read 0x212 with the ADC->DR5 register, which is absolutely normal I have activated the ADC_DMA mode : via ADC_DMACmd(ENABLE);
Is somebody have already experienced this problem ?
Could be a silicium limitation?If somebody have already realized this operation, what is the value for the field : DMA_InitStruct.DMA_Channel_FlowCntrl
DMA_InitStruct.DMA_Channel_Des
DMA_InitStruct.DMA_Channel_Src
(i don't know really between DMA_FlowCntrl_Perip2 or DMA_FlowCntrl2_DMA, and i have some trouble with the documentation) thanks in advance. Damien. For the test, I m running my ADC in continuous mode, Clock Peripheral, before prescaler : 48 Mhz (Look Init code) My demo board is with a STR912FW44X6, silicon B (little bit old, but mounted by default). Compil: GCC / Yagarto ---- Init ADC_Setup.ADC_Channel_5_Mode = ADC_NoThreshold_Conversion; ADC_Setup.ADC_Select_Channel = ADC_Channel_5; ADC_Setup.ADC_Scan_Mode = DISABLE; ADC_Setup.ADC_Conversion_Mode = ADC_Continuous_Mode; ADC_PrescalerConfig(128); /* Enable DMA for ADC*/ ADC_DMACmd(ENABLE); ---- Interrupt ----- static u16 DMAData; static u16 ConvertResult; if (ADC_GetFlagStatus (ADC_FLAG_ECV) == SET ) { ADC_ClearFlag (ADC_FLAG_ECV); DMAData = ADC->DDR; // <- Receive always 0 ConvertResult = ADC->DR5; // <- Receive 0x212 }
2011-05-17 12:55 AM
Need to setup Linked Lists for the received data buffer, like this for SSP
(change SSP0_BASE+2 to your input, i.e. ADC->DR5 (ADC_BASE+offset)) // Receive Control Link List StructLinkList LLRxBuffer = { (long*)SSP0_BASE+2, // source pointer (long*)&usNetRxBuffer[0], // destination (long*)&LLRxBuffer, // rotating buffer // Channel Control (long) DMA_DesIncrement // destination increment, NewFWLib name | DMA_SrcWidth_HalfWord // source 16 bits | DMA_DesWidth_HalfWord // destination 16 bits | RX_BUFFER_SIZE, // length // Channel Configuration (long) DMA_FlowCntrl2_DMA // flow control | DMA_SRC_SSP0_RX // source SSP0 receive }; Also need to load this by using ExecLinkList(DMA_Channel0, &LLRxBuffer); where /*********************************** Configure Channel and Execute ExecLinkList(DMA_Channel0, &LLFpRxBuffer); ExecLinkList(DMA_Channel1, &LLFpTxCommand); ExecLinkList(DMA_Channel2, &LLNetRxBuffer); ExecLinkListLength(DMA_Channel3, &LLNetTxCommand, nLength); ************************************/ void ExecLinkList(DMA_Channel_TypeDef * Channel, StructLinkList * LinkList) { // Channel->CCNF &= ~DMA_ChannelEnable; DMA_ChannelCmd(Channel, DISABLE); Channel->SRC = (long)LinkList->p_lSource; Channel->DES = (long)LinkList->p_lDest; Channel->LLI = (long)LinkList->p_lNextList; Channel->CC = (long)LinkList->lControl; // CCNF not part of link list Channel->CCNF = (long)LinkList->lConfig; // Channel->CCNF |= DMA_ChannelEnable; DMA_ChannelCmd(Channel, ENABLE); } // End of Function ''ExecLinkList()''2011-05-17 12:55 AM
Hi rgreenthal,
Thanks for your help. I tried to change the ADC->DDR register to the adress of the ADC->DR5 Register. Problem is I don't know really how the ADC will be able to generate a DMA request transfert if this DDR register don't works. I tried to generate myself in the interrupt ADC end of convertion a DMA request, via these function : DMA_SetSReq (DMA_External_Req1_Mask); DMA_SetBReq (DMA_External_Req1_Mask); But nothing, no data is written in my destination buffer, stay with init value. Any idea welcome. Damien2011-05-17 12:55 AM
Well,
he seems the silicon version, present in my demo board: STR912F W44X6 (not A)... is limited.
The ADC Timer trigger is only available for rev A.
Same code running on a STR911FA W44X6 (A) seems work (TBC) regards