/** * \brief 16-bit checksum of data block test * * This test does a checksum of a data block with a known checksum, * and verifies that they are equal. It then appends the 16-bit CRC * to the end of the data, and does another checksum operation, which * should result in the zero flag being set. * * \param test Current test case */ static void run_16bit_io_test(const struct test_case *test) { uint8_t tmp_buffer[LENGTH(data_8bit) + sizeof(uint16_t)]; int i; uint16_t checksum; crc_io_checksum_byte_start(CRC_16BIT); for(i = 0;i < LENGTH(data_8bit); ++i) crc_io_checksum_byte_add(data_8bit[i]); checksum = crc_io_checksum_byte_stop(); test_assert_true(test, checksum == CRC_CHECKSUM_16BIT, "Checksum mismatch on IO CRC-16 test"); memcpy(tmp_buffer, data_8bit, LENGTH(data_8bit)); crc16_append_value(checksum, &tmp_buffer[LENGTH(tmp_buffer) - sizeof(uint16_t)]); checksum = crc_io_checksum(tmp_buffer, LENGTH(tmp_buffer), CRC_16BIT); test_assert_true(test, checksum == 0, "Checksum fail check failed on IO CRC-16 test"); }
/** * \brief Example 1 main application routine */ int main(void) { board_init(); sysclk_init(); // Initialize the platform LED's. LED_Off(LED0_GPIO); LED_Off(LED1_GPIO); uint32_t checksum; uint8_t data[15]; // Randomly selected data data[0] = 0xAA; data[1] = 0xBB; data[2] = 0xCC; data[3] = 0xDD; data[4] = 0xEE; data[5] = 0xFF; // Calculate checksum for the data checksum = crc_io_checksum((void*)data, 6, CRC_32BIT); // Append complemented CHECKSUM registers value to the data, little endian crc32_append_value(checksum, data+6); // Calculate the new checksum checksum = crc_io_checksum((void*)data, 10, CRC_32BIT); // Check that the data has not been corrupted, and checksum is zero if (checksum == 0) { // Turn on LED0 LED_On(LED0_GPIO); } // Calculate CRC 16 checksum for the data checksum = crc_io_checksum((void*)data, 6, CRC_16BIT); // Append the checksum to the data, big endian crc16_append_value(checksum, data+6); // Calculate the new checksum checksum = crc_io_checksum((void*)data, 8, CRC_16BIT); // Check that the data has not been corrupted, and checksum is zero if (checksum == 0) { // Turn on LED1 LED_On(LED1_GPIO); } // End of application, loop forever while (true) { // Intentionally left empty } }
/** * \brief 16-bit checksum of DMA transfer data * * This test sets up DMA to do a data block transfer, and sets up * the CRC module to do a 16 bit checksum on the data. The checksum * will then be added to another buffer, the same procedure is setup * with this new buffer which should result in a checksum = 0. * * \param test Current test case */ static void run_16bit_dma_test(const struct test_case *test) { uint16_t checksum; bool success; uint8_t data_buf_8bit[LENGTH(data_8bit) + sizeof(uint16_t)]; uint8_t data_8bit_cpy[LENGTH(data_8bit) + sizeof(uint16_t)]; setup_dma_channel(LENGTH(data_8bit), (uint8_t*)data_8bit, data_buf_8bit); crc_dma_checksum_start(CONF_TEST_DMACH, CRC_16BIT); dma_channel_trigger_block_transfer(CONF_TEST_DMACH); success = wait_for_dma_transfer(test); dma_channel_disable(CONF_TEST_DMACH); dma_disable(); checksum = crc_dma_checksum_stop(); if (!success) { return; } test_assert_true(test, checksum == CRC_CHECKSUM_16BIT, "Checksum mismatch on DMA CRC-16 test"); memcpy(data_8bit_cpy, data_8bit, LENGTH(data_8bit)); crc16_append_value(checksum, &data_8bit_cpy[LENGTH(data_8bit_cpy) - sizeof(uint16_t)]); setup_dma_channel(LENGTH(data_8bit_cpy), (uint8_t *)data_8bit_cpy, data_buf_8bit); crc_dma_checksum_start(CONF_TEST_DMACH, CRC_16BIT); dma_channel_trigger_block_transfer(CONF_TEST_DMACH); success = wait_for_dma_transfer(test); dma_channel_disable(CONF_TEST_DMACH); dma_disable(); checksum = crc_dma_checksum_stop(); if (!success) { return; } test_assert_true(test, checksum == 0, "Checksum fail check failed on DMA CRC-16 test"); }
/** * \brief main function */ int main(void) { struct dma_channel_config config; uint32_t checksum; pmic_init(); board_init(); sysclk_init(); sleepmgr_init(); // Randomly selected data source[0] = 0xAA; source[1] = 0xBB; source[2] = 0xCC; source[3] = 0xDD; source[4] = 0xEE; source[5] = 0xFF; // Calculate checksum for the data checksum = crc_io_checksum((void*)source, 6, CRC_16BIT); // Append the checksum to the data, big endian crc16_append_value(checksum, source+6); //Enable the CRC module for DMA crc_dma_checksum_start(DMA_CHANNEL, CRC_16BIT); // Enable DMA dma_enable(); // Set callback function for DMA completion dma_set_callback(DMA_CHANNEL, example_crc_dma_transfer_done); // Make sure config is all zeroed out so we don't get any stray bits memset(&config, 0, sizeof(config)); /** * This example will configure a DMA channel with the following * settings: * - Low interrupt priority * - 1 byte burst length * - DMA_BUFFER_SIZE bytes for each transfer * - Reload source and destination address at end of each transfer * - Increment source and destination address during transfer * - Source address is set to \ref source * - Destination address is set to \ref destination */ dma_channel_set_interrupt_level(&config, PMIC_LVL_LOW); dma_channel_set_burst_length(&config, DMA_CH_BURSTLEN_1BYTE_gc); dma_channel_set_transfer_count(&config, DMA_BUFFER_SIZE); dma_channel_set_src_reload_mode(&config, DMA_CH_SRCRELOAD_TRANSACTION_gc); dma_channel_set_dest_reload_mode(&config, DMA_CH_DESTRELOAD_TRANSACTION_gc); 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_set_source_address(&config, (uint16_t)(uintptr_t)source); dma_channel_set_destination_address(&config, (uint16_t)(uintptr_t)destination); dma_channel_write_config(DMA_CHANNEL, &config); // Use the configuration above by enabling the DMA channel in use. dma_channel_enable(DMA_CHANNEL); // Enable interrupts cpu_irq_enable(); // Trigger the DMA transfer dma_channel_trigger_block_transfer(DMA_CHANNEL); // Light the first LED to indicate that the DMA has started. gpio_set_pin_low(LED0_GPIO); while (true) { /* * Force a NOP instruction for an eventual placement of a debug * session breakpoint. */ asm("nop\n"); } }