Keil ARM Cortex-M3 Forum, l can restart the DMA engine by set into circular dma mode, and the sem give and take works between the IRQ and the main task. However when I try use normal dma mode as opposed the cir que. I can't seem to restart the DMA.
task void mainTask() { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; memset(RxBuffer3,0,(DMA_TX_BUF_SIZE * MAX_Q_SLOTS) - 1); /* * Config RCC registers for USART3 DMA * */ /* DMA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Enable GPIO clock */ RCC_APB2PeriphClockCmd(USART3_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE); /* Enable USART3 Clock */ RCC_APB1PeriphClockCmd(USART3_CLK, ENABLE); //Enable DMA1 channel3 IRQ Channel. This channel is NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn; //USART 3 RX NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // Config GPIO registers for USART3 DMA // Enable the USART3 Pins Software Remapping */ GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE); /* Configure USART3 Rx as input floating */ GPIO_InitStructure.GPIO_Pin = USART3_RxPin; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(USART3_GPIO, &GPIO_InitStructure); /* Configure USART3 Tx as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = USART3_TxPin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(USART3_GPIO, &GPIO_InitStructure); // Config DMA engine for TX and RX on USART3 init_dma_channel_params(DMA_CHANNEL_USART_3_RX,&g_dma_usart3_rx_init_info); config_dma_channel(DMA_CHANNEL_USART_3_RX,&g_dma_usart3_rx_init_info); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART3, &USART_InitStructure); /* Enable USARTz DMA Rx and TX request */ USART_DMACmd(USART3, USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE); /* Setup the DMA semaphores to the empty state */ init_dma_sems(); /* Enable DMA1 Channel3 Transfer Complete interrupt */ DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE); /* Get Current Data Counter value before transfer begins */ CurrDataCounterBegin3 = DMA_GetCurrDataCounter(DMA1_Channel3); /* Enable the engine for recieving UIC messages */ DMA_Cmd(USART3_Rx_DMA_Channel, ENABLE); /* Enable the USART3 */ USART_Cmd(USART3, ENABLE);
// code continued while (1) // Do this forever { OS_RESULT res; u16 timeout = WAIT_FOREVER; static xfers; /* Wait until USARTy TX DMA1 Channel Transfer Complete */ res = os_sem_wait(dma_usart3_rx_sem,timeout); switch (res) { case OS_R_SEM: // The calling task waited until the semaphore was available. ++xfers; break; case OS_R_TMO: // The timeout expired before the token became available. ++xfers; break; case OS_R_OK://A token was avaible and the function returned immediately. ++xfers; break; default: break; } // Note I've tried to remove/add fuctional blocks below to get the DMA to restart NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn; //USART 3 RX NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable USARTz DMA Rx and TX request */ USART_DMACmd(USART3, USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE); init_dma_channel_params(DMA_CHANNEL_USART_3_RX,&g_dma_usart3_rx_init_info); config_dma_channel(DMA_CHANNEL_USART_3_RX,&g_dma_usart3_rx_init_info); /* Enable DMA1 Channel3 Transfer Complete interrupt */ DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE); /* Enable the engine for recieving UIC messages */ DMA_Cmd(USART3_Rx_DMA_Channel, ENABLE); USART_Cmd(USART3, ENABLE); } //IRQ Handler extern __IO uint32_t CurrDataCounterEnd3; void DMA1_Channel3_IRQHandler(void) { /* Test on DMA1 Channel3 Transfer Complete interrupt */ if(DMA_GetITStatus(DMA1_IT_TC3)) { /* Disable DMA1_Channel2 transfer*/ DMA_Cmd(DMA1_Channel3, DISABLE); /* Get Current Data Counter value after complete transfer */ CurrDataCounterEnd3 = DMA_GetCurrDataCounter(DMA1_Channel3); /* Clear DMA1 Channel6 Half Transfer, Transfer Complete and Global interrupt pending bits */ DMA_ClearITPendingBit(DMA1_IT_GL3); isr_sem_send(dma_usart3_rx_sem); } }