void dma_stream_reset(u32 dma, u8 stream)
{
/* Disable stream (must be done before register is otherwise changed). */
	DMA_SCR(dma, stream) &= ~DMA_SxCR_EN;
/* Reset all config bits. */
	DMA_SCR(dma, stream) = 0;
/* Reset data transfer number. */
	DMA_SNDTR(dma, stream) = 0;
/* Reset peripheral and memory addresses. */
	DMA_SPAR(dma, stream) = 0;
	DMA_SM0AR(dma, stream) = 0;
	DMA_SM1AR(dma, stream) = 0;
/* This is the default setting */
	DMA_SFCR(dma, stream) = 0x21;
/* Reset all stream interrupt flags using the interrupt flag clear register. */
	u32 mask = DMA_ISR_MASK(stream);
	if (stream < 4)
	{
		DMA_LIFCR(dma) |= mask;
	}
	else
	{
		DMA_HIFCR(dma) |= mask;
	}	
}
Exemple #2
0
/** Setup the USART for transmission with DMA.
 * This function sets up the DMA controller and additional USART parameters for
 * DMA transmit. The USART must already be configured for normal operation.
 *
 * \param s The USART DMA state structure.
 * \oaram usart The USART base address.
 * \param dma The DMA controller base address.
 * \param stream The DMA stream number to use.
 * \param channel The DMA channel to use. The stream and channel must
 *                correspond to a USART RX channel.
 */
void usart_tx_dma_setup(usart_tx_dma_state* s, u32 usart,
                        u32 dma, u8 stream, u8 channel)
{
    s->dma = dma;
    s->usart = usart;
    s->stream = stream;
    s->channel = channel;

    s->byte_counter = 0;
    s->last_byte_ticks = chTimeNow();

    /* Enable clock to DMA peripheral. */
    if (dma == DMA1)
        RCC_AHB1ENR |= RCC_AHB1ENR_DMA1EN;
    else if (dma == DMA2)
        RCC_AHB1ENR |= RCC_AHB1ENR_DMA2EN;

    /* Enable TX DMA on the USART. */
    usart_enable_tx_dma(usart);

    /* Make sure stream is disabled to start. */
    DMA_SCR(dma, stream) &= ~DMA_SxCR_EN;

    /* Configure the DMA controller. */
    DMA_SCR(dma, stream) = 0;
    DMA_SCR(dma, stream) =
        /* Error interrupts. */
        DMA_SxCR_DMEIE | DMA_SxCR_TEIE |
        /* Transfer complete interrupt. */
        DMA_SxCR_TCIE |
        DMA_SxCR_DIR_MEM_TO_PERIPHERAL |
        /* Increment the memory address after each transfer. */
        DMA_SxCR_MINC |
        /* 4 bytes written to the FIFO from memory at a time */
        DMA_SxCR_MBURST_INCR4 |
        /* 8 bit transfers from USART peripheral. */
        DMA_SxCR_PSIZE_8BIT |
        /* and to memory. */
        DMA_SxCR_MSIZE_8BIT |
        /* TODO: what priority level is necessary? */
        /* Very high priority. */
        DMA_SxCR_PL_VERY_HIGH |
        /* The channel selects which request line will trigger a transfer.
         * (see CD00225773.pdf Table 23). */
        DMA_SxCR_CHSEL(channel);

    /* For now, don't transfer any number of datas
     * (will be set in the initiating function). */
    DMA_SNDTR(dma, stream) = 0;

    /* DMA into the USART data register... */
    DMA_SPAR(dma, stream) = &USART_DR(usart);
    /* ...from the TX buffer. */
    DMA_SM0AR(dma, stream) = s->buff;

    /* TODO: Investigate more about the best FIFO settings. */
    DMA_SFCR(dma, stream) =
        DMA_SxFCR_DMDIS |         /* Enable DMA stream FIFO. */
        DMA_SxFCR_FTH_2_4_FULL |  /* Trigger level 2/4 full. */
        DMA_SxFCR_FEIE;           /* Enable FIFO error interrupt. */

    s->wr = s->rd = 0;  /* Buffer is empty to begin with. */

    /* Enable DMA interrupts for this stream with the NVIC. */
    if (dma == DMA1)
        nvicEnableVector(dma_irq_lookup[0][stream],
                         CORTEX_PRIORITY_MASK(USART_DMA_ISR_PRIORITY));
    else if (dma == DMA2)
        nvicEnableVector(dma_irq_lookup[1][stream],
                         CORTEX_PRIORITY_MASK(USART_DMA_ISR_PRIORITY));
}
void dma_set_fifo_threshold(u32 dma, u8 stream, u32 threshold)
{
	u32 reg32 = (DMA_SFCR(dma, stream) & ~DMA_SxFCR_FTH_MASK);
	DMA_SFCR(dma, stream) = (reg32 | threshold);
}
void dma_enable_fifo_mode(u32 dma, u8 stream)
{
	DMA_SFCR(dma, stream) |= DMA_SxFCR_DMDIS;
}
void dma_enable_direct_mode(u32 dma, u8 stream)
{
	DMA_SFCR(dma, stream) &= ~DMA_SxFCR_DMDIS;
}
u32 dma_fifo_status(u32 dma, u8 stream)
{
	return (DMA_SFCR(dma, stream) & DMA_SxFCR_FS_MASK);
}
void dma_disable_fifo_error_interrupt(u32 dma, u8 stream)
{
	DMA_SFCR(dma, stream) &= ~DMA_SxFCR_FEIE;
}
void dma_enable_fifo_error_interrupt(u32 dma, u8 stream)
{
	dma_clear_interrupt_flags(dma, stream, DMA_ISR_FEIF);
	DMA_SFCR(dma, stream) |= DMA_SxFCR_FEIE;
}