0
\$\begingroup\$

In a noisy media, I need to receive 10bytes with DMA (about 1Mb). I have set the DMA and its interrupt as shown below:


void DMA_Configuration(void)
{
    DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART3->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = sizeof(Buffer) - 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode =DMA_Mode_Normal  ;//DMA_Mode_Circular
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
/* Enable DMA Stream Transfer Complete interrupt */
DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA1_Channel3, ENABLE);

} void DMA1_Channel3_IRQHandler(void) // USART1_RX { if (DMA_GetITStatus(DMA1_IT_TC3)) { SendTest=Buffer[2]; DMA_ClearITPendingBit(DMA1_IT_TC3); } }

My buffer receives 10bytes. In a noisy media, some noises can deceive my receiver. I implement another pin for telling the receiver I need to send:


void EXTI15_10_IRQHandler(void){

if (EXTI_GetITStatus(EXTI_Line10) != RESET) { if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_10)==0 ){DMA_Configuration();GPIO_ResetBits(GPIOA,GPIO_Pin_5);} else { //USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE); GPIO_SetBits(GPIOA,GPIO_Pin_5); DMA_DeInit(DMA1_Channel3); //USART_DMACmd(USART3, USART_DMAReq_Rx, DISABLE); } EXTI_ClearITPendingBit(EXTI_Line10); }

}

But I can't Enable and Disable DMA correctly(for example by getting 1-10 bytes it stop working in receiving mode). I disabled my DMA with different ways:

Disabling: DMA_DeInit(DMA1_Channel3); USART_DMACmd(USART3, USART_DMAReq_Rx, DISABLE); DMA_Cmd(DMA1_Channel3, DISABLE);

Enabling: Calling DMA_Configuration(); USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE); DMA_Cmd(DMA1_Channel3, ENABLE);

I will be thankful if you could help me.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you for your comment. You assume that I need to start and stop DMA with an external interrupt to disable and enable USART receiver. The noise can be from an electerical motor, interruption in wire during sending the data and etc. I will be grateful if you could help me in stoping and starting the DMA during this cycle that I have mentioned. \$\endgroup\$
    – John Jin
    Commented Feb 24, 2020 at 19:05
  • \$\begingroup\$ I think I misunderstood your question. Your problem is that you can't get your DMA to work more than once, right? You have to reset your DMA counter (DMA_CNDTRx) every time it finishes. It doesn't reset on its own unless you are in circular mode. \$\endgroup\$
    – DKNguyen
    Commented Feb 24, 2020 at 19:11

1 Answer 1

1
\$\begingroup\$

You have to reset your DMA counter (DMA_CNDTRx) every time it finishes. It doesn't automatically reset on its own when it reaches zero unless you are in circular mode.

\$\endgroup\$
5
  • \$\begingroup\$ Thank you, but as you can see I used DMA_DeInit(DMA1_Channel3); and then DMA_Configuration(); before each transmission and in DMA_DeInit we have DMAx_Channey->CNDTR = 0; However, I have added DMA1_Channel3->CNDTR = 0;DMA1_Channel3->CMAR = 0; lines to my interrupt routine but it doesn't work again. \$\endgroup\$
    – John Jin
    Commented Feb 26, 2020 at 6:09
  • \$\begingroup\$ @Parisa Are you disabling the DMA before deinit? Or does deinit disable the channel itself? CNDTR is read only while the DMA channel is enabled \$\endgroup\$
    – DKNguyen
    Commented Feb 27, 2020 at 15:32
  • \$\begingroup\$ Thank you for your comment \$\endgroup\$
    – John Jin
    Commented Mar 3, 2020 at 16:34
  • \$\begingroup\$ @Parisa Did that solve the issue? \$\endgroup\$
    – DKNguyen
    Commented Mar 3, 2020 at 17:01
  • \$\begingroup\$ Sorry for the delay in my response. I just changed the mode to circular and disable end enable DMA,USART, Interrupts in EXTI function. In the disable and Enable function CMSIS library change the mentioned variables. \$\endgroup\$
    – John Jin
    Commented Mar 6, 2020 at 18:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.