neorv32/sw/example/demo_crc/main.c
2025-03-02 09:54:55 +01:00

169 lines
5.9 KiB
C

// ================================================================================ //
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
// Copyright (c) NEORV32 contributors. //
// Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. //
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
// SPDX-License-Identifier: BSD-3-Clause //
// ================================================================================ //
/**********************************************************************//**
* @file demo_crc/main.c
* @brief CRC demo program.
**************************************************************************/
#include <neorv32.h>
/**********************************************************************//**
* @name User configuration
**************************************************************************/
/**@{*/
/** UART BAUD rate */
#define BAUD_RATE 19200
/**@}*/
// CRC test array
const uint8_t test_string[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00};
/**********************************************************************//**
* Simple demo program to showcase the NEORV32 CRC unit.
*
* @note This program requires UART0 and the CRC unit to be synthesized.
* The DMA controller is optional.
*
* @return Irrelevant.
**************************************************************************/
int main() {
// setup NEORV32 runtime environment
neorv32_rte_setup();
// setup UART at default baud rate, no interrupts
neorv32_uart0_setup(BAUD_RATE, 0);
// intro
neorv32_uart0_printf("\n<<< CRC Unit Demo Program >>>\n\n");
// check if CRC unit is implemented at all
if (neorv32_crc_available() == 0) {
neorv32_uart0_printf("ERROR! CRC unit not implemented!\n");
return 1;
}
uint32_t result, polynomial, reference, seed;
neorv32_uart0_printf("Test string: '%s'\n", test_string);
// CRC8 example
polynomial = 0x07;
reference = 0x5b; // generated by http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
seed = 0x00;
neorv32_crc_setup(CRC_MODE8, polynomial, seed);
result = neorv32_crc_block((uint8_t*)test_string, sizeof(test_string)) & 0xff;
neorv32_uart0_printf("\n[CRC8]\n");
neorv32_uart0_printf("Polynomial = 0x%x\n", polynomial);
neorv32_uart0_printf("Seed = 0x%x\n", seed);
neorv32_uart0_printf("Result = 0x%x ", result);
if (result == reference) {
neorv32_uart0_printf("[OK]\n");
}
else {
neorv32_uart0_printf("[FAILED]\n");
}
// CRC16 example
polynomial = 0x1021;
reference = 0x96B9; // generated by http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
seed = 0x0000;
neorv32_crc_setup(CRC_MODE16, polynomial, seed);
result = neorv32_crc_block((uint8_t*)test_string, sizeof(test_string)) & 0xffff;
neorv32_uart0_printf("\n[CRC16]\n");
neorv32_uart0_printf("Polynomial = 0x%x\n", polynomial);
neorv32_uart0_printf("Seed = 0x%x\n", seed);
neorv32_uart0_printf("Result = 0x%x ", result);
if (result == reference) {
neorv32_uart0_printf("[OK]\n");
}
else {
neorv32_uart0_printf("[FAILED]\n");
}
// CRC32 example
polynomial = 0x04C11DB7;
reference = 0xF58D7B78; // generated by http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
seed = 0xFFFFFFFF;
neorv32_crc_setup(CRC_MODE32, polynomial, seed);
result = neorv32_crc_block((uint8_t*)test_string, sizeof(test_string)) & 0xffffffff;
neorv32_uart0_printf("\n[CRC32]\n");
neorv32_uart0_printf("Polynomial = 0x%x\n", polynomial);
neorv32_uart0_printf("Seed = 0x%x\n", seed);
neorv32_uart0_printf("Result = 0x%x ", result);
if (result == reference) {
neorv32_uart0_printf("[OK]\n");
}
else {
neorv32_uart0_printf("[FAILED]\n");
}
// CRC8 example using the DMA
if (neorv32_dma_available() != 0) {
polynomial = 0x07;
reference = 0x5b; // generated by http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
seed = 0x00;
neorv32_crc_setup(CRC_MODE8, polynomial, seed);
neorv32_uart0_printf("\n[CRC8] using DMA\n");
neorv32_uart0_printf("Polynomial = 0x%x\n", polynomial);
neorv32_uart0_printf("Seed = 0x%x\n", seed);
neorv32_dma_enable();
// configure DMA descriptor
neorv32_dma_desc_t dma_desc;
dma_desc.src = (uint32_t)(&test_string[0]); // source array base address (data = 0xff)
dma_desc.dst = (uint32_t)(&NEORV32_CRC->DATA); // destination address = CRC data register (32-bit!)
dma_desc.num = sizeof(test_string); // number of elements to transfer
dma_desc.cmd = DMA_CMD_B2UW | // read source in byte quantities, write destination in WORD quantities
DMA_CMD_SRC_INC | // auto-increment source address
DMA_CMD_DST_CONST; // constant destination address
// trigger DMA transfer
neorv32_dma_transfer(&dma_desc);
// wait for transfer to complete using polling
neorv32_uart0_printf("Waiting for DMA... ");
int rc;
while (1) {
rc = neorv32_dma_status();
if (rc == DMA_STATUS_DONE) {
neorv32_uart0_printf("Transfer done.\n");
break;
}
else if ((rc == DMA_STATUS_ERR_RD) || (rc == DMA_STATUS_ERR_WR)) {
neorv32_uart0_printf("Transfer failed!\n");
break;
}
}
// check DMA status
rc = neorv32_dma_status();
if ((rc == DMA_STATUS_ERR_RD) || (rc == DMA_STATUS_ERR_WR)) {
neorv32_uart0_printf("Transfer failed!\n");
}
result = neorv32_crc_get() & 0xff;
neorv32_uart0_printf("Result = 0x%x ", result);
if (result == reference) {
neorv32_uart0_printf("[OK]\n");
}
else {
neorv32_uart0_printf("[FAILED]\n");
}
}
neorv32_uart0_printf("\nProgram completed.\n");
return 0;
}