ICARUS OS (Intelligent Cooperative Architecture for Real-time Unified Systems) 0.1.0
Preemptive Real-Time Operating System for ARM Cortex-M7
Loading...
Searching...
No Matches
crc.c
Go to the documentation of this file.
1
32#include "icarus/crc.h"
33#include "icarus/config.h"
34#include <stddef.h>
35
36#ifndef HOST_TEST
37
38#include "icarus/kernel.h" /* enter_critical / exit_critical */
39#include "stm32h7xx.h"
40
41/* CRC->CR field encodings (from RM0433):
42 * bit 0 RESET — write 1 to reload INIT into the data register
43 * bits 4:3 POLYSIZE — 00=32, 01=16, 10=8, 11=7
44 * bits 6:5 REV_IN — 00 = no input bit/byte reversal
45 * bit 7 REV_OUT — 0 = no output bit reversal
46 */
47#define CRC_CR_POLYSIZE_16 (0x1u << CRC_CR_POLYSIZE_Pos)
48
49static volatile uint8_t crc_initialised;
50
51ITCM_FUNC static void crc_hw_init(void) {
52 /* Enable the CRC peripheral clock on AHB4. The dummy read settles
53 * the bus per the H7 reference manual recommendation. */
54 RCC->AHB4ENR |= RCC_AHB4ENR_CRCEN;
55 (void)RCC->AHB4ENR;
56
57 /* Configure poly = 0x1021, init = 0xFFFF, 16-bit polysize,
58 * no reversal. */
59 CRC->POL = 0x1021u;
60 CRC->INIT = 0xFFFFu;
61 CRC->CR = CRC_CR_POLYSIZE_16;
62
63 crc_initialised = 1u;
64}
65
66ITCM_FUNC uint16_t crc16_ccitt(const uint8_t *data, uint16_t len) {
67 if (data == NULL || len == 0) {
68 return 0xFFFFu;
69 }
70
72
73 if (!crc_initialised) {
75 }
76
77 /* Reset the running value back to INIT (0xFFFF) before this run. */
78 CRC->CR |= CRC_CR_RESET;
79
80 /* Feed bytes one at a time. The peripheral allows 8/16/32-bit
81 * accesses to DR; an 8-bit write consumes one byte regardless of
82 * word alignment. */
83 volatile uint8_t *const dr8 = (volatile uint8_t *)&CRC->DR;
84 for (uint16_t i = 0; i < len; i++) {
85 *dr8 = data[i];
86 }
87
88 uint16_t crc = (uint16_t)(CRC->DR & 0xFFFFu);
89
91 return crc;
92}
93
94#else /* HOST_TEST — portable bytewise loop */
95
96uint16_t crc16_ccitt(const uint8_t *data, uint16_t len) {
97 if ((data == NULL) || (len == 0u)) {
98 return 0xFFFFu;
99 }
100 uint16_t crc = 0xFFFFu;
101 for (uint16_t i = 0u; i < len; i++) {
102 crc ^= (uint16_t)((uint16_t)data[i] << 8u);
103 for (uint8_t bit = 0u; bit < 8u; bit++) {
104 if ((crc & 0x8000u) != 0u) {
105 crc = (uint16_t)((crc << 1) ^ 0x1021u);
106 } else {
107 crc = (uint16_t)(crc << 1);
108 }
109 }
110 }
111 return crc;
112}
113
114#endif /* HOST_TEST */
#define CRC_CR_POLYSIZE_16
Definition crc.c:47
static volatile uint8_t crc_initialised
Definition crc.c:49
static void crc_hw_init(void)
Definition crc.c:51
uint16_t crc16_ccitt(const uint8_t *data, uint16_t len)
Compute CRC16-CCITT (poly 0x1021, init 0xFFFF) over a byte buffer.
Definition crc.c:66
CRC16-CCITT helper for the ICARUS OS kernel.
ICARUS OS Configuration Header.
#define ITCM_FUNC
Definition config.h:155
ICARUS Kernel Core - State and Initialization.
void __exit_critical(void)
Privileged implementation of exit_critical.
Definition kernel.c:124
void __enter_critical(void)
Privileged implementation of enter_critical.
Definition kernel.c:114