This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Restarting DMA xfer on USART RXNE event.

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);
    }
    }