bool CipherExample (KCipher * cipher) { uint8_t cipher_text [16]; rc_t rc; bool passed_key; bool passed_block; memset (cipher_text, 0, sizeof cipher_text); rc = KCipherSetEncryptKey (cipher, b.key, 128/8); if (rc) ; else { passed_key = key_compare (&b.key_schedule, cipher->encrypt_key); rc = KCipherEncrypt (cipher, b.plain, cipher_text); if (rc) ; else { passed_block = block_compare (b.cipher, cipher_text); } } if (rc) { STSMSG (1,("Could not run test")); return false; } return passed_key && passed_block; }
/** * * \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"); }
/** * \brief Test read from fixed location, trigger from timer and callback * * \note This test sets up a timer to trigger the EDMA module, * which in turn reads the timer45_overflow_counter variable and writes * it to memory sequentially. It then checks to see that the memory block * written is sequential according to the overflow count. This test uses the * event system wired on timer45 overflow as trigger. * * \param test Current test */ static void run_edma_triggered_with_callback(const struct test_case *test) { struct edma_channel_config config_params; bool success; /* Null the buffer */ set_buffer(dest_block_tc45, 0x0000); /* Null out the config parameter struct */ memset(&config_params, 0, sizeof(config_params)); /* Enable the Event System on EVSYS_CH_2 */ EVSYS.CH2MUX = EVSYS_CHMUX_TCC4_OVF_gc; /* * Enable the timer, and set it to count up. * When it overflows, it triggers the EDMA to * read timer45_overflow_counter. */ tc45_set_overflow_interrupt_callback(&TIMER45, timer45_overflow_callback); tc45_enable(&TIMER45); tc45_set_overflow_interrupt_level(&TIMER45, TC45_INT_LVL_LO); tc45_set_direction(&TIMER45, TC45_UP); tc45_write_period(&TIMER45, TIMER45_PERIOD); tc45_set_resolution(&TIMER45, TIMER45_RESOLUTION); /* * Enable the EDMA module, standard channel 0, * peripheral channels 2 and 3 */ edma_enable(EDMA_CHMODE_STD0_gc); /* Set callback for transfer done */ edma_set_callback(EDMA_CH_0, ut_edma_transfer_is_complete); /* Set low interrupt level */ edma_channel_set_interrupt_level(&config_params, EDMA_INT_LVL_LO); /* Set up the EDMA to read the timer value * * - Single shot transfer mode * - 1 byte (16-bit) burst length * - Increment on source and destination * - Reload on burst for source * - No reload for destination */ edma_channel_set_single_shot(&config_params); edma_channel_set_burst_length(&config_params, EDMA_CH_BURSTLEN_1BYTE_gc); edma_channel_set_src_reload_mode(&config_params, EDMA_CH_RELOAD_BURST_gc); edma_channel_set_src_dir_mode(&config_params, EDMA_CH_DIR_FIXED_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); /* Set trigger source to Event Channel 2 (set to TCC4's overflow) */ edma_channel_set_trigger_source(&config_params, EDMA_CH_TRIGSRC_EVSYS_CH2_gc); /* Transfer DEST_BLOCK_TC45_SIZE bytes */ edma_channel_set_transfer_count16(&config_params, DEST_BLOCK_TC45_SIZE); /* Set address */ edma_channel_set_source_address(&config_params, (uint16_t)(uintptr_t)&timer45_overflow_counter); edma_channel_set_destination_address(&config_params, (uint16_t)(uintptr_t)dest_block_tc45); /* Reset the channel */ edma_channel_reset(EDMA_CH_0); /* Write the config */ edma_channel_write_config(EDMA_CH_0, &config_params); /* Enable the channel */ edma_channel_enable(EDMA_CH_0); /* Wait for transfer to finish */ while (!edma_has_completed) { /* Intentionally left empty */ } /* Disable EDMA and stop TC45 interrupts */ tc45_set_overflow_interrupt_level(&TIMER45, TC45_INT_LVL_OFF); edma_disable(); /* Verify that the result is as expected */ success = block_compare(dest_block_tc45, expected_result_tc, DEST_BLOCK_TC45_SIZE); test_assert_true(test, success, "Result is not as expected"); /* * Stop TIMER45: * Already done in EDMA callback "ut_edma_transfer_is_complete()" */ }
/** * \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); }
bool ExampleVector (KCipher * cipher, const example_vectors * ev) { uint8_t cipher_text [16]; uint8_t plain_text [16]; uint32_t Nk; rc_t rc; bool passed_enckey; bool passed_deckey; bool passed_enc; bool passed_dec; switch (ev->key_enc.rounds) { default: STSMSG (1,("Bad test vector")); return false; case 10: Nk = 16; break; case 12: Nk = 24; break; case 14: Nk = 32; break; } memset (cipher_text, 0, sizeof cipher_text); memset (plain_text, 0, sizeof plain_text); rc = KCipherSetEncryptKey (cipher, ev->key, Nk); if (rc) ; else { passed_enckey = key_compare (&ev->key_enc, cipher->encrypt_key); rc = KCipherSetDecryptKey (cipher, ev->key, Nk); if (rc) ; else { #if COMPARE_INV_CIPHER passed_deckey = key_compare (&ev->key_dec, cipher->decrypt_key); #endif #if COMPARE_EQ_INV_CIPHER passed_deckey = key_compare (&ev->key_dec_alt, cipher->decrypt_key); #endif rc = KCipherEncrypt (cipher, ev->plain, cipher_text); if (rc) ; else { passed_enc = block_compare (ev->cipher, cipher_text); rc = KCipherDecrypt (cipher, ev->cipher, plain_text); if (rc) ; else { passed_dec = block_compare (ev->plain, plain_text); } } } } if (rc) { STSMSG (1,("Could not run test")); return false; } return passed_enckey && passed_deckey && passed_enc && passed_dec; }
/** * \brief Test read from fixed location, trigger from timer and callback * * \note This test sets up a timer to trigger the DMA module, * which in turn reads the timer_overflow_counter variable and writes * it to memory sequentially. It then checks to see that the memory block * written is sequential according to the overflow count. * * \param test Current test */ static void run_dma_triggered_with_callback(const struct test_case *test) { struct dma_channel_config config_params; bool success; /* Null the buffer */ set_buffer(dest_block_tc, 0x0000); /* Null out the config parameter struct */ memset(&config_params, 0, sizeof(config_params)); /* * Enable the timer, and set it to count up. * When it overflows, it triggers the DMA to * read timer_overflow_counter. */ tc_enable(&TIMER); tc_set_direction(&TIMER, TC_UP); tc_write_period(&TIMER, TIMER_PERIOD); tc_set_resolution(&TIMER, TIMER_RESOLUTION); tc_set_overflow_interrupt_level(&TIMER, PMIC_LVL_LOW); tc_set_overflow_interrupt_callback(&TIMER, timer_overflow_callback); /* Enable the DMA module */ dma_enable(); /* Set callback for transfer done */ dma_set_callback(DMA_CHANNEL_0, dma_transfer_is_complete); /* Set low interrupt level */ dma_channel_set_interrupt_level(&config_params, PMIC_LVL_LOW); /* Set up the DMA to read the timer value * * - Single shot transfer mode * - Two byte (16-bit) burst length * - Increment on source and destination * - Reload on burst for source * - No reload for destination */ dma_channel_set_single_shot(&config_params); dma_channel_set_burst_length(&config_params, DMA_CH_BURSTLEN_1BYTE_gc); dma_channel_set_src_reload_mode(&config_params, DMA_CH_SRCRELOAD_BURST_gc); dma_channel_set_src_dir_mode(&config_params, DMA_CH_SRCDIR_FIXED_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); /* Set trigger source to TCC0's overflow */ dma_channel_set_trigger_source(&config_params, DMA_CH_TRIGSRC_TCC0_OVF_gc); /* Transfer DEST_BLOCK_TC_SIZE bytes */ dma_channel_set_transfer_count(&config_params, DEST_BLOCK_TC_SIZE); /* Set address */ dma_channel_set_source_address(&config_params, (uint16_t)(uintptr_t)&timer_overflow_counter); dma_channel_set_destination_address(&config_params, (uint16_t)(uintptr_t)dest_block_tc); /* Reset the channel */ dma_channel_reset(DMA_CHANNEL_0); /* Write the config */ dma_channel_write_config(DMA_CHANNEL_0, &config_params); /* Enable the channel */ dma_channel_enable(DMA_CHANNEL_0); /* Wait for transfer to finish */ while (!dma_has_completed) { /* Intentionally left empty */ } /* Disable DMA */ dma_disable(); /* Verify that the result is as expected */ success = block_compare(dest_block_tc, expected_result_tc, DEST_BLOCK_TC_SIZE); test_assert_true(test, success, "Result is not as expected"); }
/** * \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); }