コード例 #1
0
ファイル: main3.c プロジェクト: edwardpoore/EE587
void main (void) 
{
   char keypress;

   WDTCN = 0xde;                    // disable watchdog timer
   WDTCN = 0xad;


   SYSCLK_Init ();                     // initialize oscillator
   //PORT_Init ();                       // initialize crossbar and GPIO
   UART0_Init ();                      // initialize UART0

   //OSCICN |= 0x03;                  // Set internal oscillator to highest setting
                                    // (16 MHz)


   XBR0 = 0x05;                     // Route SMBus to GPIO pins through crossbar
   XBR2 = 0x44;                     // Enable crossbar and weak pull-ups
   P1MDOUT = 0x03;

   SMB0CN = 0x44;                   // Enable SMBus with ACKs on acknowledge 
                                    // cycle
   SMB0CR = -80;                    // SMBus clock rate = 100kHz.

   EIE1 |= 2;                       // SMBus interrupt enable
   EA = 1;                          // Global interrupt enable

   SM_BUSY = 0;                     // Free SMBus for first transfer.
   

   //SMBus_Init();
   //Timer3_Init();
   //Interrupts_Init();
   //SI = 0;

   printf ("EE587 Experiment #3\n");
   printf ("Initialization Complete...\n");
  
   while (1) {

       printf("what would you like to do? (d,b,r,w):");
    
       keypress = getchar();

       printf("\n");

    
       switch(keypress) {
           case 'd': dump_eeprom(); break;
           case 'b': block_fill(); break;
           case 'r': read_eeprom(); break;
           case 'w': write_eeprom(); break;
           case ' ':;
           default:
               printf("Invalid Command '%c'\n",keypress);
               break;
       }
    
    
    
    }  // while(1)
    
}  // main
コード例 #2
0
/**
 *
 * \brief Test search and double buffering (link) modes
 *
 * \note This function tests search and double buffering features of the EDMA
 * controller by configuring channel 2 searching data. In case of success, the
 * channel 0 is automatically (double buffering) enables (if it is
 * successfull) and copies a memory block. The copy is verified.
 *
 * \param test   Current test case
 */
static void run_edma_search_dbuf_test(const struct test_case *test)
{
	struct edma_channel_config ch0_config_params;
	struct edma_channel_config ch2_config_params;

	bool success;

	/* Fill source block with pattern data */
	set_buffer(memory_block_src, 0x00);
	block_fill(memory_block_src, MEMORY_BLOCK_SIZE);

	/* Null out the destination block */
	set_buffer(memory_block_dest, 0x00);

	/* Null out the config params */
	memset(&ch0_config_params, 0, sizeof(ch0_config_params));
	memset(&ch2_config_params, 0, sizeof(ch2_config_params));

	/* Enable EDMA module, Channels 0 and 2 in standard configuration */
	edma_enable(EDMA_CHMODE_STD02_gc);

	/* Enable double buffering mode on channel 0 and 1 */
	edma_set_double_buffer_mode(EDMA_DBUFMODE_BUF0123_gc);

	/* Set channel 2 to search data (last byte of memory_block_src[]) */
	edma_channel_set_src_reload_mode(&ch2_config_params,
			EDMA_CH_RELOAD_NONE_gc);
	edma_channel_set_src_dir_mode(&ch2_config_params, EDMA_CH_DIR_INC_gc);
	edma_channel_set_dest_reload_mode(&ch2_config_params,
			EDMA_CH_RELOAD_NONE_gc);
	edma_channel_set_search_mode(&ch2_config_params,
			EDMA_CH_DESTDIR_MP1_gc);
	edma_channel_set_burst_length(&ch2_config_params,
			EDMA_CH_BURSTLEN_1BYTE_gc);
	edma_channel_set_trigger_source(&ch2_config_params,
			EDMA_CH_TRIGSRC_OFF_gc);
	edma_channel_set_transfer_count16(&ch2_config_params,
			MEMORY_BLOCK_SIZE);
	edma_channel_set_source_address(&ch2_config_params,
			(uint16_t)(uintptr_t)memory_block_src);
	edma_channel_set_search_data(&ch2_config_params,
			memory_block_src[MEMORY_BLOCK_SIZE - 1], 0xFF);

	/* Write config channel 2 */
	edma_channel_write_config(EDMA_CH_2, &ch2_config_params);

	/*
	 * Set channel 0 to copy from memory_block_src[] to memory_block_dest[]
	 * once a match will occur on channel 2. There will be no transfer if no
	 * match occurs.
	 */
	edma_channel_set_repeat(&ch0_config_params);
	edma_channel_set_burst_length(&ch0_config_params,
			EDMA_CH_BURSTLEN_2BYTE_gc);
	edma_channel_set_src_reload_mode(&ch0_config_params,
			EDMA_CH_RELOAD_TRANSACTION_gc);
	edma_channel_set_dest_reload_mode(&ch0_config_params,
			EDMA_CH_RELOAD_TRANSACTION_gc);
	edma_channel_set_src_dir_mode(&ch0_config_params, EDMA_CH_DIR_INC_gc);
	edma_channel_set_dest_dir_mode(&ch0_config_params,
			EDMA_CH_DESTDIR_INC_gc);
	edma_channel_set_trigger_source(&ch0_config_params,
			EDMA_CH_TRIGSRC_OFF_gc);
	edma_channel_set_transfer_count16(&ch0_config_params,
			MEMORY_BLOCK_SIZE);
	edma_channel_set_source_address(&ch0_config_params,
			(uint16_t)(uintptr_t)memory_block_src);
	edma_channel_set_destination_address(&ch0_config_params,
			(uint16_t)(uintptr_t)memory_block_dest);

	/* Write config channel 0 */
	edma_channel_write_config(EDMA_CH_0, &ch0_config_params);

	/* Enable only channel 2 */
	edma_channel_enable(EDMA_CH_2);

	/* Transfer block and wait for it to finish */
	edma_channel_trigger_block_transfer(EDMA_CH_2);
	edma_channel_trigger_block_transfer(EDMA_CH_0);

	/* Wait for search completion */
	while (edma_get_channel_status(EDMA_CH_2) !=
			EDMA_CH_TRANSFER_COMPLETED) {
		/* Intentionally left empty */
	}

	/* Wait for transfer completion */
	while (edma_get_channel_status(EDMA_CH_0) !=
			EDMA_CH_TRANSFER_COMPLETED) {
		/* Intentionally left empty */
	}

	/* Disable EDMA */
	edma_disable();

	/* Verify that the search result is as expected */
	success = block_compare(
			edma_channel_get_search_pointer(EDMA_CH_2),
			&memory_block_src[MEMORY_BLOCK_SIZE - 1], 1);

	test_assert_true(test, success,
			"SEARCH mode did not function properly");

	/* Verify that the transfer result is as expected */
	success = block_compare(memory_block_src, memory_block_dest,
			MEMORY_BLOCK_SIZE);

	test_assert_true(test, success,
			"DOUBLE BUFFER mode did not function properly");
}
コード例 #3
0
/**
 *
 * \brief Test double buffering mode
 *
 * \note This function tests the double buffering feature of the DMA
 * controller by configuring channel 0 and 1 to do the same copy,
 * and verify that the channels enable each other according to
 * the double buffering process.
 *
 * \param test   Current test case
 */
static void run_dma_double_buffering_test(const struct test_case *test)
{
	struct dma_channel_config config_params;
	bool success = true; /* Assume everything goes well */

	/* Fill source block with pattern data */
	set_buffer(memory_block_src, 0x00);
	block_fill(memory_block_src, MEMORY_BLOCK_SIZE);

	/* Null out the destination block */
	set_buffer(memory_block_dest, 0x00);

	/* Null out the config params */
	memset(&config_params, 0, sizeof(config_params));

	/* Enable DMA */
	dma_enable();

	/* Enable double buffering mode on channel 0 and 1 */
	dma_set_double_buffer_mode(DMA_DBUFMODE_CH01_gc);

	/* Set channel 1 to copy from memory_block_src to memory_block_dest */
	dma_channel_set_src_reload_mode(&config_params,
			DMA_CH_SRCRELOAD_NONE_gc);
	dma_channel_set_src_dir_mode(&config_params,
			DMA_CH_SRCDIR_INC_gc);
	dma_channel_set_dest_reload_mode(&config_params,
			DMA_CH_DESTRELOAD_NONE_gc);
	dma_channel_set_dest_dir_mode(&config_params,
			DMA_CH_DESTDIR_INC_gc);
	dma_channel_set_burst_length(&config_params,
			DMA_CH_BURSTLEN_1BYTE_gc);
	dma_channel_set_transfer_count(&config_params,
			MEMORY_BLOCK_SIZE);
	dma_channel_set_source_address(&config_params,
			(uint16_t)(uintptr_t)memory_block_src);
	dma_channel_set_destination_address(&config_params,
			(uint16_t)(uintptr_t)memory_block_dest);
	dma_channel_set_repeats(&config_params,
			DOUBLE_BUFFER_REPEATS);

	/* Write config and enable */
	dma_channel_write_config(DMA_CHANNEL_0, &config_params);
	dma_channel_write_config(DMA_CHANNEL_1, &config_params);

	/* Enable only channel 0 */
	dma_channel_enable(DMA_CHANNEL_0);

	/* Transfer block and wait for it to finish */
	dma_channel_trigger_block_transfer(DMA_CHANNEL_0);

	while (dma_get_channel_status(DMA_CHANNEL_0) !=
			DMA_CH_TRANSFER_COMPLETED) {
		/* Intentionally left empty */
	}

	/*
	 * If double buffering is working, channel 1
	 * will be enabled now by the controller
	 */
	if (!(dma_channel_is_enabled(DMA_CHANNEL_1))) {
		success = false;
	}

	/*
	 * Disable channel 0, transfer channel 1,
	 * and verify that channel 0 is enabled again by the controller
	 */
	dma_channel_disable(DMA_CHANNEL_0);

	/* Transfer block and wait for it to finish */
	dma_channel_trigger_block_transfer(DMA_CHANNEL_1);

	while (dma_get_channel_status(DMA_CHANNEL_1) !=
			DMA_CH_TRANSFER_COMPLETED) {
		/* Intentionally left empty */
	}

	/* Verify that channel 0 is enabled again */
	if (!(dma_channel_is_enabled(DMA_CHANNEL_0))) {
		success = false;
	}

	test_assert_true(test, success,
			"Double buffering mode did not function properly");
}
コード例 #4
0
/**
 * \brief Test the different burst lengths by copying on all channels
 *
 * \note This test copies a memory block using different burst lengths,
 * and verifies that they have been copied correctly, thereby testing both
 * burst lengths and memory transfer.
 *
 * \param test              Current test
 */
static void run_edma_memory_copy_burst_length_test(const struct test_case *test)
{
	struct edma_channel_config config_params;
	edma_channel_num_t channel_index;
	bool success = true; /* Assume everything goes well */

	/* Fill the source block with our known pattern */
	set_buffer(memory_block_src, 0x00);
	block_fill(memory_block_src, MEMORY_BLOCK_SIZE);

	/* Null out the config params */
	memset(&config_params, 0, sizeof(config_params));

	/* Enable EDMA, channels 0 and 2 in standard conf. */
	edma_enable(EDMA_CHMODE_STD02_gc);

	/*
	 * - No reload on source and destination
	 * - Increment source and destination
	 */
	edma_channel_set_src_reload_mode(&config_params,
			EDMA_CH_RELOAD_NONE_gc);
	edma_channel_set_src_dir_mode(&config_params, EDMA_CH_DIR_INC_gc);
	edma_channel_set_dest_reload_mode(&config_params,
			EDMA_CH_RELOAD_NONE_gc);
	edma_channel_set_dest_dir_mode(&config_params, EDMA_CH_DESTDIR_INC_gc);
	edma_channel_set_transfer_count16(&config_params, MEMORY_BLOCK_SIZE);
	edma_channel_set_source_address(&config_params,
			(uint16_t)(uintptr_t)memory_block_src);
	edma_channel_set_destination_address(&config_params,
			(uint16_t)(uintptr_t)memory_block_dest);

	/* Test burst lengths on all standard channels */
	for (channel_index = EDMA_CH_0;
			channel_index < EDMA_NUMBER_OF_STANDARD_CHANNELS;
			channel_index += 2) {
		edma_channel_set_burst_length(&config_params,
				EDMA_CH_BURSTLEN_1BYTE_gc);
		edma_channel_write_config(channel_index, &config_params);

		/* Clear destination */
		set_buffer(memory_block_dest, 0x00);

		/* Enable channel, transfer, and disable it */
		edma_channel_enable(channel_index);
		ut_edma_transfer_block(channel_index);
		edma_channel_disable(channel_index);

		/* Check that source and destination are equal */
		success = block_compare(memory_block_src, memory_block_dest,
				MEMORY_BLOCK_SIZE);

		if (!success) {
			break;
		}

		/* Reset channel and write 2 byte burst length */
		edma_channel_reset(channel_index);
		edma_channel_set_burst_length(&config_params,
				EDMA_CH_BURSTLEN_2BYTE_gc);
		edma_channel_write_config(channel_index, &config_params);

		/* Clear destination */
		set_buffer(memory_block_dest, 0x00);

		/* Enable channel, transfer, and disable it */
		edma_channel_enable(channel_index);
		ut_edma_transfer_block(channel_index);
		edma_channel_disable(channel_index);

		/* Check that source and destination are equal */
		success = block_compare(memory_block_src, memory_block_dest,
				MEMORY_BLOCK_SIZE);

		/* test_assert_true(test, false, "Test-1 "); */

		if (!success) {
			break;
		}
	}
	/* Disable EDMA */
	edma_disable();

	test_assert_true(test,
			success,
			"EDMA burst mode memory copy tests failed on StdCH_%d",
			channel_index);
}
コード例 #5
0
/**
 * \brief Test different directions on all channels
 *
 * \note This test copies the source memory block into the destination block
 * in different ways.
 *
 * \param test              Current test
 */
static void run_dma_direction_test(const struct test_case *test)
{
	struct dma_channel_config config_params;
	uint8_t channel_index;
	bool success = true; /* Assume everything goes well */

	/* Fill the source block with our known pattern */
	set_buffer(memory_block_src, 0x00);
	block_fill(memory_block_src, MEMORY_BLOCK_SIZE);

	/* Null out the config params */
	memset(&config_params, 0, sizeof(config_params));

	/* Enable DMA */
	dma_enable();

	/* No reload on source and destination */
	dma_channel_set_src_reload_mode(&config_params,
			DMA_CH_SRCRELOAD_NONE_gc);
	dma_channel_set_dest_reload_mode(&config_params,
			DMA_CH_DESTRELOAD_NONE_gc);
	dma_channel_set_transfer_count(&config_params,
			MEMORY_BLOCK_SIZE);
	dma_channel_set_burst_length(&config_params,
			DMA_CH_BURSTLEN_1BYTE_gc);

	/* Test a memory transfer on all channels */
	for (channel_index = 0; channel_index < DMA_NUMBER_OF_CHANNELS;
			channel_index++) {
		/* Reset channel and write the configuration */
		dma_channel_reset(channel_index);
		/* Increment source, increment destination */
		dma_channel_set_src_dir_mode(&config_params,
				DMA_CH_SRCDIR_INC_gc);
		dma_channel_set_dest_dir_mode(&config_params,
				DMA_CH_DESTDIR_INC_gc);
		/* Data starts from the first byte */
		dma_channel_set_source_address(&config_params,
				(uint16_t)(uintptr_t)memory_block_src);
		dma_channel_set_destination_address(&config_params,
				(uint16_t)(uintptr_t)memory_block_dest);

		/* Write the config */
		dma_channel_write_config(channel_index, &config_params);

		/* Clear destination */
		set_buffer(memory_block_dest, 0x00);

		/* Enable channel, transfer, and disable it */
		dma_channel_enable(channel_index);
		dma_transfer_block(channel_index);
		dma_channel_disable(channel_index);

		/* Check that source and destination are equal */
		success = block_compare(memory_block_src,
				memory_block_dest, MEMORY_BLOCK_SIZE);

		if (!success) {
			break;
		}

		/* Reset channel and write the configuration */
		dma_channel_reset(channel_index);
		/* Decrement source, increment destination */
		dma_channel_set_src_dir_mode(&config_params,
				DMA_CH_SRCDIR_DEC_gc);
		dma_channel_set_dest_dir_mode(&config_params,
				DMA_CH_DESTDIR_INC_gc);
		/* Data starts from the first byte */
		dma_channel_set_source_address(&config_params,
				(uint16_t)(uintptr_t)
				(memory_block_src + MEMORY_BLOCK_SIZE - 1));
		dma_channel_set_destination_address(&config_params,
				(uint16_t)(uintptr_t)memory_block_dest);

		/* Write the config */
		dma_channel_write_config(channel_index, &config_params);

		/* Clear destination */
		set_buffer(memory_block_dest, 0x00);

		/* Enable channel, transfer, and disable it */
		dma_channel_enable(channel_index);
		dma_transfer_block(channel_index);
		dma_channel_disable(channel_index);

		/* Check that destination is the reverse of source */
		success = block_compare_reverse(memory_block_src,
				memory_block_dest, MEMORY_BLOCK_SIZE);

		if (!success) {
			break;
		}

		/* Reset channel and write the configuration */
		dma_channel_reset(channel_index);
		/* Decrement source, increment destination */
		dma_channel_set_src_dir_mode(&config_params,
				DMA_CH_SRCDIR_INC_gc);
		dma_channel_set_dest_dir_mode(&config_params,
				DMA_CH_DESTDIR_DEC_gc);
		/* Data starts from the first byte */
		dma_channel_set_source_address(&config_params,
				(uint16_t)(uintptr_t)memory_block_src);
		dma_channel_set_destination_address(&config_params,
				(uint16_t)(uintptr_t)
				(memory_block_dest + MEMORY_BLOCK_SIZE - 1));

		/* Write the config */
		dma_channel_write_config(channel_index, &config_params);

		/* Clear destination */
		set_buffer(memory_block_dest, 0x00);

		/* Enable channel, transfer, and disable it */
		dma_channel_enable(channel_index);
		dma_transfer_block(channel_index);
		dma_channel_disable(channel_index);

		/* Check that destination is the reverse of source */
		success = block_compare_reverse(memory_block_src,
				memory_block_dest, MEMORY_BLOCK_SIZE);

		if (!success) {
			break;
		}

		/* Reset channel and write the configuration */
		dma_channel_reset(channel_index);
		/* Decrement source, Decrement destination */
		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);
		/* Data starts from the first byte */
		dma_channel_set_source_address(&config_params,
				(uint16_t)(uintptr_t)
				(memory_block_src + MEMORY_BLOCK_SIZE - 1));
		dma_channel_set_destination_address(&config_params,
				(uint16_t)(uintptr_t)
				(memory_block_dest + MEMORY_BLOCK_SIZE - 1));

		/* Write the config */
		dma_channel_write_config(channel_index, &config_params);

		/* Clear destination */
		set_buffer(memory_block_dest, 0x00);

		/* Enable channel, transfer, and disable it */
		dma_channel_enable(channel_index);
		dma_transfer_block(channel_index);
		dma_channel_disable(channel_index);

		/* Check that source and destination are equal */
		success = block_compare(memory_block_src,
				memory_block_dest, MEMORY_BLOCK_SIZE);

		if (!success) {
			break;
		}
	}

	/* Disable DMA */
	dma_disable();

	test_assert_true(test, success,
			"DMA direction copy test failed on channel %d",
			channel_index);
}