Example #1
0
/**
 * \brief DMA driver configuration
 */
static void init_dma(void)
{
	uint32_t cfg;

	/* Enable DMA controller */
	dmac_enable(DMAC);

	/* Initialize and enable DMA controller */
	pmc_enable_periph_clk(ID_DMAC);
	dmac_init(DMAC);
	dmac_set_priority_mode(DMAC, DMAC_PRIORITY_ROUND_ROBIN);
	dmac_enable(DMAC);

	/* Disable the DMA channel for SSC */
	dmac_channel_disable(DMAC, DMA_CH);

	/* Set channel configuration register */
	cfg = DMAC_CFG_SOD_ENABLE | 	   /* Enable stop on done */
			DMAC_CFG_DST_H2SEL |	   /* Hardware Selection for the Destination */
			DMAC_CFG_DST_PER(3) | /* Destination with Peripheral identifier */
			DMAC_CFG_AHB_PROT(1) |	   /* Set AHB Protection */
			DMAC_CFG_FIFOCFG_ALAP_CFG; /* FIFO Configuration */

	dmac_channel_set_configuration(DMAC, DMA_CH, cfg);

	/* Set interrupt */
	NVIC_EnableIRQ(DMAC_IRQn);
	dmac_enable_interrupt(DMAC, (DMAC_EBCIER_CBTC0 << DMA_CH));
}
Example #2
0
/**
 * \brief Test DMA single buffer transfer with polling mode.
 *
 * \param test Current test case.
 */
static void run_single_buf_xfer_test(const struct test_case *test)
{
	uint32_t i;
	uint32_t cfg;
	dma_transfer_descriptor_t desc;

	/* Initialize DMA buffer */
	for (i = 0; i < DMA_BUF_SIZE; i++) {
		g_dma_buf[0][i] = i;
		g_dma_buf[1][i] = 0;
	}

	/* Initialize and enable DMA controller */
	pmc_enable_periph_clk(ID_DMAC);
	dmac_init(DMAC);
	dmac_set_priority_mode(DMAC, DMAC_PRIORITY_ROUND_ROBIN);
	dmac_enable(DMAC);

	/* Set for channel configuration register */
	cfg = DMAC_CFG_SOD_ENABLE |        /* Enable stop on done */
			DMAC_CFG_AHB_PROT(1) |     /* Set AHB Protection */
			DMAC_CFG_FIFOCFG_ALAP_CFG; /* FIFO Configuration */
	dmac_channel_set_configuration(DMAC, DMA_CH, cfg);

	/* Initialize single buffer transfer: buffer 0 -> buffer 1 */
	desc.ul_source_addr = (uint32_t) g_dma_buf[0];
	desc.ul_destination_addr = (uint32_t) g_dma_buf[1];
	desc.ul_ctrlA = DMAC_CTRLA_BTSIZE(DMA_BUF_SIZE) |   /* Set Buffer Transfer Size */
			DMAC_CTRLA_SRC_WIDTH_WORD |                 /* Source transfer size is set to 32-bit width */
			DMAC_CTRLA_DST_WIDTH_WORD;                  /* Destination transfer size is set to 32-bit width */
	desc.ul_ctrlB = DMAC_CTRLB_SRC_DSCR_FETCH_DISABLE | /* Buffer Descriptor Fetch operation is disabled for the source */
			DMAC_CTRLB_DST_DSCR_FETCH_DISABLE |         /* Buffer Descriptor Fetch operation is disabled for the destination */
			DMAC_CTRLB_FC_MEM2MEM_DMA_FC |              /* Memory-to-Memory Transfer */
			DMAC_CTRLB_SRC_INCR_INCREMENTING |          /* The source address is incremented */
			DMAC_CTRLB_DST_INCR_INCREMENTING;           /* The destination address is incremented */
	desc.ul_descriptor_addr = 0;                        /* No descriptor for single transfer */
	dmac_channel_single_buf_transfer_init(DMAC, DMA_CH, &desc);

	/* Start DMA transfer and wait for finish */
	dmac_channel_enable(DMAC, DMA_CH);
	while (!dmac_channel_is_transfer_done(DMAC, DMA_CH)) {
	}

	/* Verify the transferred data */
	for (i = 0; i < DMA_BUF_SIZE; i++) {
		test_assert_true(test, g_dma_buf[0][i] == g_dma_buf[1][i],
				"Data comparison failed.");
	}
}
Example #3
0
/**
 * \brief Test DMA single buffer transfer with polling mode.
 */
static void test_single_buf_xfer(void)
{
	//! [dmac_define_vars]
	uint32_t i;
	uint32_t cfg;
	dma_transfer_descriptor_t desc;
	//! [dmac_define_vars]
	
	printf("\n\rTest single buffer transfer...\n\r");

	//! [dmac_define_prepare_buffer]
	/** Initialize DMA buffer */
	for (i = 0; i < DMA_BUF_SIZE; i++) {
		g_dma_buf[0][i] = i;
		g_dma_buf[1][i] = 0;
	}
	//! [dmac_define_prepare_buffer]

	/* Initialize and enable DMA controller */
	//! [dmac_init_clock]
	pmc_enable_periph_clk(ID_DMAC);
	//! [dmac_init_clock]
	
	//! [dmac_init_module]
	dmac_init(DMAC);
	//! [dmac_init_module]
	
	//! [dmac_set_priority]
	dmac_set_priority_mode(DMAC, DMAC_PRIORITY_ROUND_ROBIN);
	//! [dmac_set_priority]
	
	//! [dmac_enable_module]	
	dmac_enable(DMAC);
	//! [dmac_enable_module]	

	//! [dmac_configure_channel]	
	/** Set for channel configuration register */
	cfg = DMAC_CFG_SOD_ENABLE |        /** Enable stop on done */
			DMAC_CFG_AHB_PROT(1) |     /** Set AHB Protection */
			DMAC_CFG_FIFOCFG_ALAP_CFG; /** FIFO Configuration */
	dmac_channel_set_configuration(DMAC, DMA_CH, cfg);
	//! [dmac_configure_channel]	

	//! [dmac_configure_for_single_transfer_1]	
	/** Initialize single buffer transfer: buffer 0 -> buffer 1 */
	desc.ul_source_addr = (uint32_t) g_dma_buf[0];
	desc.ul_destination_addr = (uint32_t) g_dma_buf[1];
	//! [dmac_configure_for_single_transfer_1]	
	
	/*
	 * Set DMA CTRLA:
	 * - Set Buffer Transfer Size
	 * - Source transfer size is set to 32-bit width
	 * - Destination transfer size is set to 32-bit width
	 */
	//! [dmac_configure_for_single_transfer_2]	
	desc.ul_ctrlA = DMAC_CTRLA_BTSIZE(DMA_BUF_SIZE) |
			DMAC_CTRLA_SRC_WIDTH_WORD |
			DMAC_CTRLA_DST_WIDTH_WORD;
	//! [dmac_configure_for_single_transfer_2]	
	
	/*
	 * Set DMA CTRLB:
	 * - Buffer Descriptor Fetch operation is disabled for the source
	 * - Buffer Descriptor Fetch operation is disabled for the destination
	 * - Memory-to-Memory Transfer
	 * - The source address is incremented
	 * - The destination address is incremented
	 */
	//! [dmac_configure_for_single_transfer_3]	
	desc.ul_ctrlB = DMAC_CTRLB_SRC_DSCR_FETCH_DISABLE |
			DMAC_CTRLB_DST_DSCR_FETCH_DISABLE |
			DMAC_CTRLB_FC_MEM2MEM_DMA_FC |
			DMAC_CTRLB_SRC_INCR_INCREMENTING |
			DMAC_CTRLB_DST_INCR_INCREMENTING;
	//! [dmac_configure_for_single_transfer_3]	
	
	/* No descriptor for single transfer */
	//! [dmac_configure_for_single_transfer_4]	
	desc.ul_descriptor_addr = 0;
	dmac_channel_single_buf_transfer_init(DMAC, DMA_CH, &desc);
	//! [dmac_configure_for_single_transfer_4]	

	/* Start DMA transfer and wait for finish */
	//! [dmac_start_transfer]	
	dmac_channel_enable(DMAC, DMA_CH);
	//! [dmac_start_transfer]	
	//! [dmac_wait_for_done]		
	while (!dmac_channel_is_transfer_done(DMAC, DMA_CH)) {
	}
	//! [dmac_wait_for_done]		

	/* Verify the transferred data */
	for (i = 0; i < DMA_BUF_SIZE; i++) {
		if (g_dma_buf[0][i] != g_dma_buf[1][i]) {
			printf("> Test NG.\n\r");
			while (1) {
			}
		}
	}
	printf("> Test OK\n\r");
}
Example #4
0
/**
 * \brief Test DMA multiple buffer transfer with interrupt mode.
 */
static void test_multi_buf_xfer(void)
{
	uint32_t i;
	uint32_t cfg;
	dma_transfer_descriptor_t desc[3];

	printf("\n\rTest multiple buffer transfer...\n\r");

	/* Initialize DMA buffer */
	for (i = 0; i < DMA_BUF_SIZE; i++) {
		g_dma_buf[0][i] = i;
		g_dma_buf[1][i] = i + 10;
		g_dma_buf[2][i] = i + 20;
		g_dma_buf[3][i] = 0;
		g_dma_buf[4][i] = 0;
		g_dma_buf[5][i] = 0;
	}

	/* Initialize and enable DMA controller */
	pmc_enable_periph_clk(ID_DMAC);
	dmac_init(DMAC);
	dmac_set_priority_mode(DMAC, DMAC_PRIORITY_ROUND_ROBIN);
	dmac_enable(DMAC);

	/* Set for channel configuration register */
	cfg = DMAC_CFG_SOD_DISABLE |        /* Disable stop on done */
			DMAC_CFG_AHB_PROT(1) |      /* Set AHB Protection */
			DMAC_CFG_FIFOCFG_ALAP_CFG;  /* FIFO Configuration */
	dmac_channel_set_configuration(DMAC, 0, cfg);

	/* Initialize multiple buffer transfer (LLI) :
	 *     buffer 0 -> buffer 3
	 *     buffer 1 -> buffer 4
	 *     buffer 2 -> buffer 5
	 */
	desc[0].ul_source_addr = (uint32_t) g_dma_buf[0];
	desc[0].ul_destination_addr = (uint32_t) g_dma_buf[3];
	/*
	 * Set DMA CTRLA:
	 * - Set Buffer Transfer Size
	 * - Source transfer size is set to 32-bit width
	 * - Destination transfer size is set to 32-bit width
	 */
	desc[0].ul_ctrlA = DMAC_CTRLA_BTSIZE(DMA_BUF_SIZE) |
			DMAC_CTRLA_SRC_WIDTH_WORD |
			DMAC_CTRLA_DST_WIDTH_WORD;
	/*
	 * Set DMA CTRLB:
	 * - Descriptor is fetched from the memory
	 * - Descriptor is fetched from the memory
	 * - Memory-to-Memory Transfer
	 * - The source address is incremented
	 * - The destination address is incremented
	 */
	desc[0].ul_ctrlB = DMAC_CTRLB_SRC_DSCR_FETCH_FROM_MEM |
			DMAC_CTRLB_DST_DSCR_FETCH_FROM_MEM |
			DMAC_CTRLB_FC_MEM2MEM_DMA_FC |
			DMAC_CTRLB_SRC_INCR_INCREMENTING |
			DMAC_CTRLB_DST_INCR_INCREMENTING;
	/* Pointer to next descriptor */
	desc[0].ul_descriptor_addr = (uint32_t) &desc[1];

	desc[1].ul_source_addr = (uint32_t) g_dma_buf[1];
	desc[1].ul_destination_addr = (uint32_t) g_dma_buf[4];
	/*
	 * Set DMA CTRLA:
	 * - Set Buffer Transfer Size
	 * - Source transfer size is set to 32-bit width
	 * - Destination transfer size is set to 32-bit width
	 */
	desc[1].ul_ctrlA = DMAC_CTRLA_BTSIZE(DMA_BUF_SIZE) |
			DMAC_CTRLA_SRC_WIDTH_WORD |
			DMAC_CTRLA_DST_WIDTH_WORD;
	/*
	 * Set DMA CTRLB:
	 * - Source descriptor is fetched from the memory
	 * - Destination descriptor is fetched from the memory
	 * - Memory-to-Memory Transfer
	 * - The source address is incremented
	 * - The destination address is incremented
	 */
	desc[1].ul_ctrlB = DMAC_CTRLB_SRC_DSCR_FETCH_FROM_MEM |
			DMAC_CTRLB_DST_DSCR_FETCH_FROM_MEM |
			DMAC_CTRLB_FC_MEM2MEM_DMA_FC |
			DMAC_CTRLB_SRC_INCR_INCREMENTING |
			DMAC_CTRLB_DST_INCR_INCREMENTING;
	/* Pointer to next descriptor */
	desc[1].ul_descriptor_addr = (uint32_t) &desc[2];

	desc[2].ul_source_addr = (uint32_t) g_dma_buf[2];
	desc[2].ul_destination_addr = (uint32_t) g_dma_buf[5];
	/*
	 * Set Buffer Transfer Size
	 * Source transfer size is set to 32-bit width
	 * Destination transfer size is set to 32-bit width
	 */
	desc[2].ul_ctrlA = DMAC_CTRLA_BTSIZE(DMA_BUF_SIZE) |
			DMAC_CTRLA_SRC_WIDTH_WORD |
			DMAC_CTRLA_DST_WIDTH_WORD;
	/*
	 * Set DMA CTRLB:
	 * - Source descriptor is fetched from the memory
	 * - Destination descriptor is fetched from the memory
	 * - Memory-to-Memory Transfer
	 * - The source address is incremented
	 * - The destination address is incremented
	 */
	desc[2].ul_ctrlB = DMAC_CTRLB_SRC_DSCR_FETCH_FROM_MEM |
			DMAC_CTRLB_DST_DSCR_FETCH_FROM_MEM |
			DMAC_CTRLB_FC_MEM2MEM_DMA_FC |
			DMAC_CTRLB_SRC_INCR_INCREMENTING |
			DMAC_CTRLB_DST_INCR_INCREMENTING;
	/* The end of LLI */
	desc[2].ul_descriptor_addr = 0;

	dmac_channel_multi_buf_transfer_init(DMAC, DMA_CH, &desc[0]);

	/* Set interrupt */
	NVIC_EnableIRQ(DMAC_IRQn);
	dmac_enable_interrupt(DMAC, (DMAC_EBCIER_CBTC0 << DMA_CH));

	/* Start DMA transfer and wait for finish */
	g_xfer_done = 0;
	dmac_channel_enable(DMAC, DMA_CH);
	while (!g_xfer_done) {
	}

	/* Verify the transferred data */
	for (i = 0; i < DMA_BUF_SIZE; i++) {
		if ((g_dma_buf[0][i] != g_dma_buf[3][i]) ||
				(g_dma_buf[1][i] != g_dma_buf[4][i]) ||
				(g_dma_buf[2][i] != g_dma_buf[5][i])) {
			printf("> Test NG.\n\r");
			while (1) {
			}
		}
	}
	printf("> Test OK.\n\r");
}