[ion] Add Ion::crc32

Takes only 32bit values. Uses non-reversed data/input

Change-Id: I8a776064af69047f7a8fa1399cf8a484f42b9b18
This commit is contained in:
Romain Goyet
2017-01-06 17:22:29 +01:00
parent c1db79b5f9
commit 025405d01d
8 changed files with 89 additions and 0 deletions

View File

@@ -1,2 +1,6 @@
SFLAGS += -Iion/include -DKD_CONFIG_H=1
include ion/src/$(PLATFORM)/Makefile
tests += $(addprefix ion/test/,\
crc32.cpp\
)

View File

@@ -8,6 +8,8 @@
#include <ion/keyboard.h>
#include <ion/led.h>
#include <ion/power.h>
#include <stdint.h>
#include <string.h>
/* ION is not your regular library. It is a library you link against, but it
@@ -26,6 +28,10 @@ void usleep(long us);
/* CAUTION: This is a complete reset! */
void reset();
// CRC32 : non xor-ed, non reversed, direct, polynomial 4C11DB7
// Only accepts whole 32bit values
uint32_t crc32(const uint32_t * data, size_t length);
}
#endif

View File

@@ -26,6 +26,21 @@ void Ion::usleep(long us) {
}
}
uint32_t Ion::crc32(const uint32_t * data, size_t length) {
bool initialCRCEngineState = RCC.AHB1ENR()->getCRCEN();
RCC.AHB1ENR()->setCRCEN(true);
CRC.CR()->setRESET(true);
const uint32_t * end = data + length;
while (data < end) {
CRC.DR()->set(*data++);
}
uint32_t result = CRC.DR()->get();
RCC.AHB1ENR()->setCRCEN(initialCRCEngineState);
return result;
}
void Ion::reset() {
CM4.AIRCR()->requestReset();
}

27
ion/src/device/regs/crc.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef REGS_CRC_H
#define REGS_CRC_H
#include "register.h"
class CRC {
public:
class DR : public Register32 {
};
class CR : Register32 {
public:
REGS_BOOL_FIELD(RESET, 0);
};
constexpr CRC() {};
REGS_REGISTER_AT(DR, 0x00);
REGS_REGISTER_AT(CR, 0x08);
private:
constexpr uint32_t Base() const {
return 0x40023000;
};
};
constexpr CRC CRC;
#endif

View File

@@ -2,6 +2,7 @@
#define REGS_REGS_H
#include "adc.h"
#include "crc.h"
#include "exti.h"
#include "cm4.h"
#include "fsmc.h"

23
ion/src/shared/crc32.cpp Normal file
View File

@@ -0,0 +1,23 @@
#include <ion.h>
constexpr uint32_t polynomial = 0x04C11DB7;
static uint32_t crc32(uint32_t crc, uint8_t data) {
crc ^= data << 24;
for (int i=8; i--;) {
crc = crc & 0x80000000 ? ((crc<<1)^polynomial) : (crc << 1);
}
return crc;
}
uint32_t Ion::crc32(const uint32_t * data, size_t length) {
uint32_t crc = 0xFFFFFFFF;
for (int i=0; i<length; i++) {
// FIXME: Assumes little-endian byte order!
crc = ::crc32(crc, (uint8_t)((data[i] >> 24) & 0xFF));
crc = ::crc32(crc, (uint8_t)((data[i] >> 16) & 0xFF));
crc = ::crc32(crc, (uint8_t)((data[i] >> 8) & 0xFF));
crc = ::crc32(crc, (uint8_t)(data[i] & 0xFF));
}
return crc;
}

View File

@@ -4,6 +4,9 @@ objs += $(addprefix ion/src/simulator/, \
battery.o\
init.o\
)
objs += $(addprefix ion/src/shared/, \
crc32.o\
)
objs += $(addprefix ion/src/simulator/boot/, main.o)
objs += $(addprefix ion/src/simulator/display/, fltklcd.o)
objs += $(addprefix ion/src/simulator/keyboard/, fltkkbd.o)

10
ion/test/crc32.cpp Normal file
View File

@@ -0,0 +1,10 @@
#include <quiz.h>
#include <ion.h>
#include <assert.h>
QUIZ_CASE(ion_crc32) {
uint32_t input[] = { 0x48656C6C, 0x6F2C2077 };
assert(Ion::crc32(input, 1) == 0x93591FFD);
assert(Ion::crc32(input, 2) == 0x72EAD3FB);
}