mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[ion/crc32] crc32Byte and crc32Word
This commit is contained in:
@@ -12,7 +12,7 @@ uint32_t CurveViewRange::rangeChecksum() {
|
||||
float data[4] = {xMin(), xMax(), yMin(), yMax()};
|
||||
size_t dataLengthInBytes = 4*sizeof(float);
|
||||
assert((dataLengthInBytes & 0x3) == 0); // Assert that dataLengthInBytes is a multiple of 4
|
||||
return Ion::crc32((uint32_t *)data, dataLengthInBytes/sizeof(uint32_t));
|
||||
return Ion::crc32Word((uint32_t *)data, dataLengthInBytes/sizeof(uint32_t));
|
||||
}
|
||||
|
||||
float CurveViewRange::yGridUnit() {
|
||||
|
||||
@@ -135,7 +135,7 @@ uint32_t DoublePairStore::storeChecksum() const {
|
||||
for (int i = 0; i < k_numberOfSeries; i++) {
|
||||
checkSumPerSeries[i] = storeChecksumForSeries(i);
|
||||
}
|
||||
return Ion::crc32(checkSumPerSeries, k_numberOfSeries);
|
||||
return Ion::crc32Word(checkSumPerSeries, k_numberOfSeries);
|
||||
}
|
||||
|
||||
uint32_t DoublePairStore::storeChecksumForSeries(int series) const {
|
||||
@@ -151,9 +151,9 @@ uint32_t DoublePairStore::storeChecksumForSeries(int series) const {
|
||||
assert((dataLengthInBytesPerDataColumn & 0x3) == 0); // Assert that dataLengthInBytes is a multiple of 4
|
||||
uint32_t checkSumPerColumn[k_numberOfColumnsPerSeries];
|
||||
for (int i = 0; i < k_numberOfColumnsPerSeries; i++) {
|
||||
checkSumPerColumn[i] = Ion::crc32((uint32_t *)m_data[series][i], dataLengthInBytesPerDataColumn/sizeof(uint32_t));
|
||||
checkSumPerColumn[i] = Ion::crc32Word((uint32_t *)m_data[series][i], dataLengthInBytesPerDataColumn/sizeof(uint32_t));
|
||||
}
|
||||
return Ion::crc32(checkSumPerColumn, k_numberOfColumnsPerSeries);
|
||||
return Ion::crc32Word(checkSumPerColumn, k_numberOfColumnsPerSeries);
|
||||
}
|
||||
|
||||
double DoublePairStore::defaultValue(int series, int i, int j) const {
|
||||
|
||||
@@ -17,7 +17,7 @@ uint32_t InteractiveCurveViewRange::rangeChecksum() {
|
||||
float data[5] = {m_xMin, m_xMax, m_yMin, m_yMax, m_yAuto ? 1.0f : 0.0f};
|
||||
size_t dataLengthInBytes = 5*sizeof(float);
|
||||
assert((dataLengthInBytes & 0x3) == 0); // Assert that dataLengthInBytes is a multiple of 4
|
||||
return Ion::crc32((uint32_t *)data, dataLengthInBytes/sizeof(uint32_t));
|
||||
return Ion::crc32Word((uint32_t *)data, dataLengthInBytes/sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void InteractiveCurveViewRange::setYAuto(bool yAuto) {
|
||||
|
||||
@@ -25,7 +25,7 @@ uint32_t Store::barChecksum() const {
|
||||
double data[2] = {m_barWidth, m_firstDrawnBarAbscissa};
|
||||
size_t dataLengthInBytes = 2*sizeof(double);
|
||||
assert((dataLengthInBytes & 0x3) == 0); // Assert that dataLengthInBytes is a multiple of 4
|
||||
return Ion::crc32((uint32_t *)data, dataLengthInBytes/sizeof(uint32_t));
|
||||
return Ion::crc32Word((uint32_t *)data, dataLengthInBytes/sizeof(uint32_t));
|
||||
}
|
||||
|
||||
/* Histogram bars */
|
||||
|
||||
@@ -33,11 +33,8 @@ const char * patchLevel();
|
||||
const char * fccId();
|
||||
|
||||
// CRC32 : non xor-ed, non reversed, direct, polynomial 4C11DB7
|
||||
// Only accepts whole 32bit values
|
||||
uint32_t crc32(const uint32_t * data, size_t length);
|
||||
// crc32 of a string padded with 0 to get a 32bit value
|
||||
uint32_t crc32PaddedString(const char * s, int length);
|
||||
|
||||
uint32_t crc32Word(const uint32_t * data, size_t length); // Only accepts whole 32bit values
|
||||
uint32_t crc32Byte(const uint8_t * data, size_t length);
|
||||
|
||||
// Provides a true random number
|
||||
uint32_t random();
|
||||
|
||||
@@ -46,7 +46,7 @@ void CRC(const char * input) {
|
||||
// Disable the cache to make many cache accesses
|
||||
Ion::Device::Cache::disable();
|
||||
|
||||
uint32_t crc = Ion::crc32PaddedString(reinterpret_cast<const char *>(internal ? 0x08000000 : 0x90000000), length);
|
||||
uint32_t crc = Ion::crc32Byte(reinterpret_cast<const uint8_t *>(internal ? 0x08000000 : 0x90000000), length);
|
||||
|
||||
Ion::Device::Cache::enable();
|
||||
|
||||
|
||||
@@ -5,19 +5,31 @@ namespace Ion {
|
||||
|
||||
using namespace Device::Regs;
|
||||
|
||||
uint32_t crc32(const uint32_t * data, size_t length) {
|
||||
uint32_t crc32Byte(const uint8_t * data, size_t length) {
|
||||
bool initialCRCEngineState = RCC.AHB1ENR()->getCRCEN();
|
||||
RCC.AHB1ENR()->setCRCEN(true);
|
||||
CRC.CR()->setRESET(true);
|
||||
|
||||
const uint32_t * end = data + length;
|
||||
const uint8_t * end = data + length;
|
||||
int wordSize = (length * sizeof(uint8_t)) / sizeof(uint32_t);
|
||||
|
||||
// Make as many word accesses as possible
|
||||
for (int i = 0; i < wordSize; i++) {
|
||||
CRC.DR_WordAccess()->set(*((uint32_t *)data));
|
||||
data += 4;
|
||||
}
|
||||
// Scanning the remaining data with byte accesses
|
||||
while (data < end) {
|
||||
CRC.DR()->set(*data++);
|
||||
CRC.DR_ByteAccess()->set(*data++);
|
||||
}
|
||||
|
||||
uint32_t result = CRC.DR()->get();
|
||||
uint32_t result = CRC.DR_WordAccess()->get();
|
||||
RCC.AHB1ENR()->setCRCEN(initialCRCEngineState);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t crc32Word(const uint32_t * data, size_t length) {
|
||||
return crc32Byte((const uint8_t *)data, length * (sizeof(uint32_t)/sizeof(uint8_t)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ namespace Regs {
|
||||
|
||||
class CRC {
|
||||
public:
|
||||
class DR : public Register32 {
|
||||
class DR_ByteAccess : public Register8 {
|
||||
};
|
||||
class DR_WordAccess : public Register32 {
|
||||
};
|
||||
|
||||
class CR : Register32 {
|
||||
@@ -18,7 +20,8 @@ public:
|
||||
};
|
||||
|
||||
constexpr CRC() {};
|
||||
REGS_REGISTER_AT(DR, 0x00);
|
||||
REGS_REGISTER_AT(DR_ByteAccess, 0x00);
|
||||
REGS_REGISTER_AT(DR_WordAccess, 0x00);
|
||||
REGS_REGISTER_AT(CR, 0x08);
|
||||
private:
|
||||
constexpr uint32_t Base() const {
|
||||
|
||||
@@ -10,16 +10,29 @@ static uint32_t crc32(uint32_t crc, uint8_t data) {
|
||||
return crc;
|
||||
}
|
||||
|
||||
uint32_t Ion::crc32(const uint32_t * data, size_t length) {
|
||||
const uint8_t * dataByte = (const uint8_t *)data;
|
||||
uint32_t crc32Helper(const uint8_t * data, size_t length, bool wordAccess) {
|
||||
size_t uint32ByteLength = sizeof(uint32_t)/sizeof(uint8_t);
|
||||
uint32_t crc = 0xFFFFFFFF;
|
||||
for (int i = 0; i < (int)length; i++) {
|
||||
// FIXME: Assumes little-endian byte order!
|
||||
size_t byteLength = (wordAccess ? length * uint32ByteLength : length);
|
||||
size_t wordLength = byteLength / uint32ByteLength;
|
||||
|
||||
for (int i = 0; i < (int)wordLength; i++) {
|
||||
// FIXME: Assumes little-endian byte order!
|
||||
for (int j = uint32ByteLength-1; j >= 0; j--) {
|
||||
// scan byte by byte to avoid alignment issue when building for emscripten platform
|
||||
crc = ::crc32(crc, dataByte[i*uint32ByteLength+j]);
|
||||
crc = crc32(crc, data[i*uint32ByteLength+j]);
|
||||
}
|
||||
}
|
||||
for (int i = (int) wordLength * uint32ByteLength; i < byteLength; i++) {
|
||||
crc = crc32(crc, data[i]);
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
uint32_t Ion::crc32Word(const uint32_t * data, size_t length) {
|
||||
return crc32Helper((const uint8_t *) data, length, true);
|
||||
}
|
||||
|
||||
uint32_t Ion::crc32Byte(const uint8_t * data, size_t length) {
|
||||
return crc32Helper(data, length, false);
|
||||
}
|
||||
|
||||
@@ -70,8 +70,8 @@ uint32_t Storage::Record::checksum() {
|
||||
uint32_t crc32Results[2];
|
||||
crc32Results[0] = m_fullNameCRC32;
|
||||
Data data = value();
|
||||
crc32Results[1] = Ion::crc32PaddedString((const char *)data.buffer, data.size);
|
||||
return Ion::crc32(crc32Results, 2);
|
||||
crc32Results[1] = Ion::crc32Byte((const uint8_t *)data.buffer, data.size);
|
||||
return Ion::crc32Word(crc32Results, 2);
|
||||
}
|
||||
|
||||
Storage::Record::Record(const char * basename, int basenameLength, const char * extension, int extensionLength) {
|
||||
@@ -80,9 +80,9 @@ Storage::Record::Record(const char * basename, int basenameLength, const char *
|
||||
|
||||
// We compute the CRC32 of the CRC32s of the basename and the extension
|
||||
uint32_t crc32Results[2];
|
||||
crc32Results[0] = Ion::crc32PaddedString(basename, basenameLength);
|
||||
crc32Results[1] = Ion::crc32PaddedString(extension, extensionLength);
|
||||
m_fullNameCRC32 = Ion::crc32(crc32Results, 2);
|
||||
crc32Results[0] = Ion::crc32Byte((const uint8_t *)basename, basenameLength);
|
||||
crc32Results[1] = Ion::crc32Byte((const uint8_t *)extension, extensionLength);
|
||||
m_fullNameCRC32 = Ion::crc32Word(crc32Results, 2);
|
||||
}
|
||||
|
||||
// STORAGE
|
||||
@@ -113,7 +113,7 @@ size_t Storage::availableSize() {
|
||||
}
|
||||
|
||||
uint32_t Storage::checksum() {
|
||||
return Ion::crc32PaddedString(m_buffer, endBuffer()-m_buffer);
|
||||
return Ion::crc32Byte((const uint8_t *) m_buffer, endBuffer()-m_buffer);
|
||||
}
|
||||
|
||||
void Storage::notifyChangeToDelegate(const Record record) const {
|
||||
|
||||
@@ -3,8 +3,13 @@
|
||||
#include <assert.h>
|
||||
|
||||
QUIZ_CASE(ion_crc32) {
|
||||
uint32_t input[] = { 0x48656C6C, 0x6F2C2077 };
|
||||
quiz_assert(Ion::crc32(input, 1) == 0x93591FFD);
|
||||
quiz_assert(Ion::crc32(input, 2) == 0x72EAD3FB);
|
||||
}
|
||||
uint32_t inputWord[] = { 0x48656C6C, 0x6F2C2077 };
|
||||
quiz_assert(Ion::crc32Word(inputWord, 1) == 0x93591FFD);
|
||||
quiz_assert(Ion::crc32Word(inputWord, 2) == 0x72EAD3FB);
|
||||
|
||||
uint8_t inputBytes[] = {0x6C, 0x6C, 0x65, 0x48, 0x77, 0x20, 0x2C, 0x6F};
|
||||
quiz_assert(Ion::crc32Byte(inputBytes, 1) == 0xD7A1E247);
|
||||
quiz_assert(Ion::crc32Byte(inputBytes, 4) == 0x93591FFD);
|
||||
quiz_assert(Ion::crc32Byte(inputBytes, 6) == 0x7BCD4EB3);
|
||||
quiz_assert(Ion::crc32Byte(inputBytes, 8) == 0x72EAD3FB);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user