Example #1
0
/**
 * \brief Test the error handling of the module
 *
 * \note Test error handling by disabling a channel which is in use
 *
 * \param test              Current test
 */
static void run_dma_error_handling_test(const struct test_case *test)
{
	/* Enable DMA */
	dma_enable();

	/* Reset the channel */
	dma_channel_reset(DMA_CHANNEL_0);

	/* Set up channel 0 to do some work, check that is it busy,
	 * change some settings and verify a transfer error */
	dma_channel_write_burst_length(DMA_CHANNEL_0,
			DMA_CH_BURSTLEN_1BYTE_gc);
	dma_channel_write_transfer_count(DMA_CHANNEL_0,
			MEMORY_BLOCK_SIZE);
	dma_channel_write_source(DMA_CHANNEL_0,
			(uint16_t)(uintptr_t)memory_block_src);
	dma_channel_write_destination(DMA_CHANNEL_0,
			(uint16_t)(uintptr_t)memory_block_dest);

	/* Enable the channel */
	dma_channel_enable(DMA_CHANNEL_0);

	/* Start a block transfer */
	dma_channel_trigger_block_transfer(DMA_CHANNEL_0);

	/* Wait for the channel to become busy */
	while (!dma_channel_is_busy(DMA_CHANNEL_0)) {
		/* Intentionally left empty */
	}

	/* Disable the channel while it is busy */
	if (dma_channel_is_busy(DMA_CHANNEL_0)) {
		dma_channel_disable(DMA_CHANNEL_0);
	}

	/* Test whether the channel is in error */
	test_assert_true(test,
			dma_get_channel_status(
			DMA_CHANNEL_0) == DMA_CH_TRANSFER_ERROR,
			"DMA channel not in error after disabling during transfer"
			" write");

	dma_disable();
}
Example #2
0
/**
 * \brief Setup a DMA channel for CRC calculation
 *
 * \param buf_length    Length of buffer to transfer
 * \param src_buffer    Pointer to transfer buffer
 * \param dst_buffer    Pointer to receive buffer
 */
static void setup_dma_channel(uint8_t buf_length,
		uint8_t *src_buffer, uint8_t *dst_buffer)
{
	struct dma_channel_config config;

	dma_enable();

	dma_channel_write_source(CONF_TEST_DMACH, (uint16_t)src_buffer);
	dma_channel_write_destination(CONF_TEST_DMACH, (uint16_t)dst_buffer);
	dma_channel_write_burst_length(CONF_TEST_DMACH, 1);
	dma_channel_write_transfer_count(CONF_TEST_DMACH, buf_length);
	dma_channel_write_repeats(CONF_TEST_DMACH, 1);

	dma_channel_read_config(CONF_TEST_DMACH, &config);
	dma_channel_set_src_dir_mode(&config, DMA_CH_SRCDIR_INC_gc);
	dma_channel_set_dest_dir_mode(&config, DMA_CH_DESTDIR_INC_gc);
	dma_channel_write_config(CONF_TEST_DMACH, &config);

	dma_channel_enable(CONF_TEST_DMACH);
}
Example #3
0
/**
 *
 * \brief Set DMA configuration, and read it back
 *
 * \note This function writes a configuration to the DMA
 * controller, and reads it back to verify settings have
 * been correctly set.
 *
 * \param test   Current test case
 */
static void run_dma_config_interface_test(const struct test_case *test)
{
	struct dma_channel_config config_params;
	struct dma_channel_config read_config;

	const uint16_t transfer_count = 1024;
	const uint8_t repeats         = 64;
	uint8_t channel_index;

#ifdef CONFIG_HAVE_HUGEMEM
	hugemem_ptr_t dest_huge_addr  = HUGEMEM_NULL;
	hugemem_ptr_t src_huge_addr   = HUGEMEM_NULL;

	hugemem_write32(dest_huge_addr, 0xABCD1234);
	hugemem_write32(src_huge_addr, 0xAAAABBBB);
#else
	const uint16_t dest_addr      = 0xBEEF;
	const uint16_t src_addr       = 0xABCD;
#endif

	memset(&config_params, 0, sizeof(config_params));

	dma_enable();

	/* Apply some parameters */
	dma_channel_set_burst_length(&config_params,
			DMA_CH_BURSTLEN_4BYTE_gc);
	dma_channel_set_single_shot(&config_params);
	dma_channel_set_interrupt_level(&config_params,
			PMIC_LVL_HIGH);
	dma_channel_set_src_reload_mode(&config_params,
			DMA_CH_SRCRELOAD_BLOCK_gc);
	dma_channel_set_dest_reload_mode(&config_params,
			DMA_CH_DESTRELOAD_BURST_gc);
	dma_channel_set_src_dir_mode(&config_params,
			DMA_CH_SRCDIR_DEC_gc);
	dma_channel_set_dest_dir_mode(&config_params,
			DMA_CH_DESTDIR_DEC_gc);
	dma_channel_set_trigger_source(&config_params,
			DMA_CH_TRIGSRC_TCC0_CCA_gc);
	dma_channel_set_transfer_count(&config_params,
			transfer_count);
	dma_channel_set_repeats(&config_params,
			repeats);

#ifdef CONFIG_HAVE_HUGEMEM
	dma_channel_set_destination_hugemem(&config_params, dest_huge_addr);
	dma_channel_set_source_hugemem(&config_params, src_huge_addr);
#else
	dma_channel_set_destination_address(&config_params, dest_addr);
	dma_channel_set_source_address(&config_params, src_addr);
#endif

	/* Loop through all channels, read back config from them, and verify */
	for (channel_index = 0; channel_index < DMA_NUMBER_OF_CHANNELS; channel_index++) {
		dma_channel_write_config(channel_index, &config_params);

		/* Null out the read_config struct */
		memset(&read_config, 0, sizeof(read_config));

		/* Read the config back from the module */
		dma_channel_read_config(channel_index, &read_config);

		test_assert_true(test,
				read_config.addrctrl == config_params.addrctrl,
				"CH %d: Address control register does not match configuration",
				channel_index);

		test_assert_true(test, read_config.ctrla == config_params.ctrla,
				"CH %d: Control register A does not match configuration",
				channel_index);

		test_assert_true(test,
				read_config.repcnt == config_params.repcnt,
				"CH %d: Repeat counter register does not match configuration",
				channel_index);

		test_assert_true(test,
				read_config.trfcnt == config_params.trfcnt,
				"CH %d: Transfer counter register does not"
				" match configuration", channel_index);

		test_assert_true(test,
				read_config.trigsrc == config_params.trigsrc,
				"CH %d: Trigger source register does not match configuration",
				channel_index);

#ifdef CONFIG_HAVE_HUGEMEM
		test_assert_true(test,
				read_config.destaddr == config_params.destaddr,
				"CH %d: Destination address register does not"
				" match configuration", channel_index);

		test_assert_true(test,
				read_config.srcaddr == config_params.srcaddr,
				"CH %d: Source address register does not match configuration",
				channel_index);
#else
		test_assert_true(test,
				read_config.destaddr16 == config_params.destaddr16,
				"CH %d: DESTADDR16 does not match configuration",
				channel_index);

		test_assert_true(test,
				read_config.srcaddr16 == config_params.srcaddr16,
				"CH %d: SRCADDR16 does not match configuration");
#endif
	}

	/* Reset the channel */
	dma_channel_reset(DMA_CHANNEL_0);

	/* Check set and unset single shot */
	memset(&config_params, 0, sizeof(config_params));
	memset(&read_config, 0, sizeof(read_config));

	dma_channel_set_single_shot(&config_params);

	dma_channel_write_config(DMA_CHANNEL_0, &config_params);
	dma_channel_read_config(DMA_CHANNEL_0, &read_config);

	test_assert_true(test, read_config.ctrla == config_params.ctrla,
			"Single shot mode not set correctly");

	memset(&config_params, 0, sizeof(config_params));
	dma_channel_unset_single_shot(&config_params);

	dma_channel_write_config(DMA_CHANNEL_0, &config_params);
	dma_channel_read_config(DMA_CHANNEL_0, &read_config);

	test_assert_true(test, read_config.ctrla == config_params.ctrla,
			"Single shot mode not unset correctly");

	/* Reset it again, and test the direct configuration functions */
	memset(&read_config, 0, sizeof(read_config));

	dma_channel_write_burst_length(DMA_CHANNEL_0, DMA_CH_BURSTLEN_4BYTE_gc);
	dma_channel_write_transfer_count(DMA_CHANNEL_0, transfer_count);
	dma_channel_write_repeats(DMA_CHANNEL_0, repeats);

#ifdef CONFIG_HAVE_HUGEMEM
	dma_channel_write_source_hugemem(DMA_CHANNEL_0, src_huge_addr);
	dma_channel_write_destination_hugemem(DMA_CHANNEL_0, dest_huge_addr);
#else
	dma_channel_write_source(DMA_CHANNEL_0, src_addr);
	dma_channel_write_destination(DMA_CHANNEL_0, dest_addr);
#endif

	/* Verify that settings have been set correctly */
	dma_channel_read_config(DMA_CHANNEL_0, &read_config);

	test_assert_true(test,
			(read_config.ctrla & DMA_CH_BURSTLEN_gm)
			== DMA_CH_BURSTLEN_4BYTE_gc,
			"Read burst length does not match configuration");

	test_assert_true(test, read_config.trfcnt == transfer_count,
			"Read transfer count does not match configuration");

	test_assert_true(test, read_config.repcnt == repeats,
			"Read repeat value does not match configuration");

#ifdef CONFIG_HAVE_HUGEMEM
	test_assert_true(test, read_config.srcaddr == src_huge_addr,
			"Read source address does not match configuration");

	test_assert_true(test, read_config.destaddr == dest_huge_addr,
			"Read destination address does not match configuration");
#else
	test_assert_true(test, read_config.srcaddr16 == src_addr,
			"Read source address does not match configuration");

	test_assert_true(test, read_config.destaddr16 == dest_addr,
			"Read destination address does not match configuration");
#endif

	dma_disable();
}