1 /*
2  * Copyright (c) 2025 Renesas Electronics Corporation
3  * Copyright 2025 NXP
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/logging/log.h>
9 LOG_MODULE_REGISTER(crc_example, CONFIG_LOG_DEFAULT_LEVEL);
10 
11 #include <zephyr/device.h>
12 #include <zephyr/drivers/crc.h>
13 
14 /* The devicetree node identifier for the "crc" */
15 #define CRC_NODE DT_CHOSEN(zephyr_crc)
16 
17 /* Pre-select CRC variant and constants via Kconfig */
18 #if defined(CONFIG_SAMPLE_CRC_VARIANT_CRC8)
19 #if !IS_ENABLED(CONFIG_CRC_DRIVER_HAS_CRC8)
20 #error "Selected CRC8 but driver/platform does not support it"
21 #endif
22 #define CRC_SAMPLE_TYPE     CRC8
23 #define CRC_SAMPLE_POLY     CRC8_POLY
24 #define CRC_SAMPLE_SEED     CRC8_INIT_VAL
25 #define CRC_SAMPLE_REVERSED (CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT)
26 #define CRC_SAMPLE_NAME     "CRC8"
27 #define CRC_SAMPLE_EXPECTED 0xB2
28 #elif defined(CONFIG_SAMPLE_CRC_VARIANT_CRC16_CCITT)
29 #if !IS_ENABLED(CONFIG_CRC_DRIVER_HAS_CRC16_CCITT) && !IS_ENABLED(CONFIG_CRC_DRIVER_HAS_CRC16)
30 #error "Selected CRC16-CCITT but platform does not support it"
31 #endif
32 #define CRC_SAMPLE_TYPE     CRC16_CCITT
33 #define CRC_SAMPLE_POLY     CRC16_CCITT_POLY
34 #define CRC_SAMPLE_SEED     CRC16_CCITT_INIT_VAL
35 #define CRC_SAMPLE_REVERSED (CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT)
36 #define CRC_SAMPLE_NAME     "CRC16-CCITT"
37 #define CRC_SAMPLE_EXPECTED 0x445c
38 #elif defined(CONFIG_SAMPLE_CRC_VARIANT_CRC32_IEEE)
39 #if !IS_ENABLED(CONFIG_CRC_DRIVER_HAS_CRC32_IEEE)
40 #error "Selected CRC32-IEEE but platform does not support it"
41 #endif
42 #define CRC_SAMPLE_TYPE     CRC32_IEEE
43 #define CRC_SAMPLE_POLY     CRC32_IEEE_POLY
44 #define CRC_SAMPLE_SEED     CRC32_IEEE_INIT_VAL
45 #define CRC_SAMPLE_REVERSED (CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT)
46 #define CRC_SAMPLE_NAME     "CRC32-IEEE"
47 #define CRC_SAMPLE_EXPECTED 0xCEA4A6C2
48 #elif defined(CONFIG_SAMPLE_CRC_VARIANT_CRC32_C)
49 #if !IS_ENABLED(CONFIG_CRC_DRIVER_HAS_CRC32_C)
50 #error "Selected CRC32-C but platform does not support it"
51 #endif
52 #define CRC_SAMPLE_TYPE     CRC32_C
53 #define CRC_SAMPLE_POLY     CRC32_C_POLY
54 #define CRC_SAMPLE_SEED     CRC32_C_INIT_VAL
55 #define CRC_SAMPLE_REVERSED (CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT)
56 #define CRC_SAMPLE_NAME     "CRC32-C"
57 #define CRC_SAMPLE_EXPECTED 0xBB19ECB2
58 #else
59 #error "No CRC sample variant selected"
60 #endif
61 
62 /*
63  * A build error on this line means your board is unsupported.
64  * See the sample documentation for information on how to fix this.
65  */
66 
main(void)67 int main(void)
68 {
69 	static const struct device *const dev = DEVICE_DT_GET(CRC_NODE);
70 	uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4};
71 	int ret;
72 
73 	if (!device_is_ready(dev)) {
74 		LOG_ERR("Device is not ready");
75 		return -ENODEV;
76 	}
77 
78 	struct crc_ctx ctx = {
79 		.type = CRC_SAMPLE_TYPE,
80 		.polynomial = CRC_SAMPLE_POLY,
81 		.seed = CRC_SAMPLE_SEED,
82 		.reversed = CRC_SAMPLE_REVERSED,
83 	};
84 
85 	ret = crc_begin(dev, &ctx);
86 	if (ret != 0) {
87 		LOG_ERR("Failed to begin %s: %d", CRC_SAMPLE_NAME, ret);
88 		return ret;
89 	}
90 
91 	ret = crc_update(dev, &ctx, data, sizeof(data));
92 	if (ret != 0) {
93 		LOG_ERR("Failed to update %s: %d", CRC_SAMPLE_NAME, ret);
94 		return ret;
95 	}
96 
97 	ret = crc_finish(dev, &ctx);
98 	if (ret != 0) {
99 		LOG_ERR("Failed to finish %s: %d", CRC_SAMPLE_NAME, ret);
100 		return ret;
101 	}
102 
103 	LOG_INF("%s result: 0x%08x", CRC_SAMPLE_NAME, (unsigned int)ctx.result);
104 
105 #if defined(CRC_SAMPLE_EXPECTED) && (CRC_SAMPLE_EXPECTED != 0)
106 	ret = crc_verify(&ctx, CRC_SAMPLE_EXPECTED);
107 	if (ret != 0) {
108 		LOG_ERR("%s verification failed (expected 0x%08x): %d", CRC_SAMPLE_NAME,
109 			CRC_SAMPLE_EXPECTED, ret);
110 		return ret;
111 	}
112 	LOG_INF("%s verification succeeded (expected 0x%08x)", CRC_SAMPLE_NAME,
113 		CRC_SAMPLE_EXPECTED);
114 #endif
115 
116 	return 0;
117 }
118