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()};
|
float data[4] = {xMin(), xMax(), yMin(), yMax()};
|
||||||
size_t dataLengthInBytes = 4*sizeof(float);
|
size_t dataLengthInBytes = 4*sizeof(float);
|
||||||
assert((dataLengthInBytes & 0x3) == 0); // Assert that dataLengthInBytes is a multiple of 4
|
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() {
|
float CurveViewRange::yGridUnit() {
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ uint32_t DoublePairStore::storeChecksum() const {
|
|||||||
for (int i = 0; i < k_numberOfSeries; i++) {
|
for (int i = 0; i < k_numberOfSeries; i++) {
|
||||||
checkSumPerSeries[i] = storeChecksumForSeries(i);
|
checkSumPerSeries[i] = storeChecksumForSeries(i);
|
||||||
}
|
}
|
||||||
return Ion::crc32(checkSumPerSeries, k_numberOfSeries);
|
return Ion::crc32Word(checkSumPerSeries, k_numberOfSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t DoublePairStore::storeChecksumForSeries(int series) const {
|
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
|
assert((dataLengthInBytesPerDataColumn & 0x3) == 0); // Assert that dataLengthInBytes is a multiple of 4
|
||||||
uint32_t checkSumPerColumn[k_numberOfColumnsPerSeries];
|
uint32_t checkSumPerColumn[k_numberOfColumnsPerSeries];
|
||||||
for (int i = 0; i < k_numberOfColumnsPerSeries; i++) {
|
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 {
|
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};
|
float data[5] = {m_xMin, m_xMax, m_yMin, m_yMax, m_yAuto ? 1.0f : 0.0f};
|
||||||
size_t dataLengthInBytes = 5*sizeof(float);
|
size_t dataLengthInBytes = 5*sizeof(float);
|
||||||
assert((dataLengthInBytes & 0x3) == 0); // Assert that dataLengthInBytes is a multiple of 4
|
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) {
|
void InteractiveCurveViewRange::setYAuto(bool yAuto) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ uint32_t Store::barChecksum() const {
|
|||||||
double data[2] = {m_barWidth, m_firstDrawnBarAbscissa};
|
double data[2] = {m_barWidth, m_firstDrawnBarAbscissa};
|
||||||
size_t dataLengthInBytes = 2*sizeof(double);
|
size_t dataLengthInBytes = 2*sizeof(double);
|
||||||
assert((dataLengthInBytes & 0x3) == 0); // Assert that dataLengthInBytes is a multiple of 4
|
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 */
|
/* Histogram bars */
|
||||||
|
|||||||
@@ -33,11 +33,8 @@ const char * patchLevel();
|
|||||||
const char * fccId();
|
const char * fccId();
|
||||||
|
|
||||||
// CRC32 : non xor-ed, non reversed, direct, polynomial 4C11DB7
|
// CRC32 : non xor-ed, non reversed, direct, polynomial 4C11DB7
|
||||||
// Only accepts whole 32bit values
|
uint32_t crc32Word(const uint32_t * data, size_t length); // Only accepts whole 32bit values
|
||||||
uint32_t crc32(const uint32_t * data, size_t length);
|
uint32_t crc32Byte(const uint8_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);
|
|
||||||
|
|
||||||
|
|
||||||
// Provides a true random number
|
// Provides a true random number
|
||||||
uint32_t random();
|
uint32_t random();
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ void CRC(const char * input) {
|
|||||||
// Disable the cache to make many cache accesses
|
// Disable the cache to make many cache accesses
|
||||||
Ion::Device::Cache::disable();
|
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();
|
Ion::Device::Cache::enable();
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,31 @@ namespace Ion {
|
|||||||
|
|
||||||
using namespace Device::Regs;
|
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();
|
bool initialCRCEngineState = RCC.AHB1ENR()->getCRCEN();
|
||||||
RCC.AHB1ENR()->setCRCEN(true);
|
RCC.AHB1ENR()->setCRCEN(true);
|
||||||
CRC.CR()->setRESET(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) {
|
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);
|
RCC.AHB1ENR()->setCRCEN(initialCRCEngineState);
|
||||||
return result;
|
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 {
|
class CRC {
|
||||||
public:
|
public:
|
||||||
class DR : public Register32 {
|
class DR_ByteAccess : public Register8 {
|
||||||
|
};
|
||||||
|
class DR_WordAccess : public Register32 {
|
||||||
};
|
};
|
||||||
|
|
||||||
class CR : Register32 {
|
class CR : Register32 {
|
||||||
@@ -18,7 +20,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
constexpr CRC() {};
|
constexpr CRC() {};
|
||||||
REGS_REGISTER_AT(DR, 0x00);
|
REGS_REGISTER_AT(DR_ByteAccess, 0x00);
|
||||||
|
REGS_REGISTER_AT(DR_WordAccess, 0x00);
|
||||||
REGS_REGISTER_AT(CR, 0x08);
|
REGS_REGISTER_AT(CR, 0x08);
|
||||||
private:
|
private:
|
||||||
constexpr uint32_t Base() const {
|
constexpr uint32_t Base() const {
|
||||||
|
|||||||
@@ -10,16 +10,29 @@ static uint32_t crc32(uint32_t crc, uint8_t data) {
|
|||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Ion::crc32(const uint32_t * data, size_t length) {
|
uint32_t crc32Helper(const uint8_t * data, size_t length, bool wordAccess) {
|
||||||
const uint8_t * dataByte = (const uint8_t *)data;
|
|
||||||
size_t uint32ByteLength = sizeof(uint32_t)/sizeof(uint8_t);
|
size_t uint32ByteLength = sizeof(uint32_t)/sizeof(uint8_t);
|
||||||
uint32_t crc = 0xFFFFFFFF;
|
uint32_t crc = 0xFFFFFFFF;
|
||||||
for (int i = 0; i < (int)length; i++) {
|
size_t byteLength = (wordAccess ? length * uint32ByteLength : length);
|
||||||
// FIXME: Assumes little-endian byte order!
|
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--) {
|
for (int j = uint32ByteLength-1; j >= 0; j--) {
|
||||||
// scan byte by byte to avoid alignment issue when building for emscripten platform
|
// 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;
|
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];
|
uint32_t crc32Results[2];
|
||||||
crc32Results[0] = m_fullNameCRC32;
|
crc32Results[0] = m_fullNameCRC32;
|
||||||
Data data = value();
|
Data data = value();
|
||||||
crc32Results[1] = Ion::crc32PaddedString((const char *)data.buffer, data.size);
|
crc32Results[1] = Ion::crc32Byte((const uint8_t *)data.buffer, data.size);
|
||||||
return Ion::crc32(crc32Results, 2);
|
return Ion::crc32Word(crc32Results, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Storage::Record::Record(const char * basename, int basenameLength, const char * extension, int extensionLength) {
|
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
|
// We compute the CRC32 of the CRC32s of the basename and the extension
|
||||||
uint32_t crc32Results[2];
|
uint32_t crc32Results[2];
|
||||||
crc32Results[0] = Ion::crc32PaddedString(basename, basenameLength);
|
crc32Results[0] = Ion::crc32Byte((const uint8_t *)basename, basenameLength);
|
||||||
crc32Results[1] = Ion::crc32PaddedString(extension, extensionLength);
|
crc32Results[1] = Ion::crc32Byte((const uint8_t *)extension, extensionLength);
|
||||||
m_fullNameCRC32 = Ion::crc32(crc32Results, 2);
|
m_fullNameCRC32 = Ion::crc32Word(crc32Results, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STORAGE
|
// STORAGE
|
||||||
@@ -113,7 +113,7 @@ size_t Storage::availableSize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Storage::checksum() {
|
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 {
|
void Storage::notifyChangeToDelegate(const Record record) const {
|
||||||
|
|||||||
@@ -3,8 +3,13 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
QUIZ_CASE(ion_crc32) {
|
QUIZ_CASE(ion_crc32) {
|
||||||
uint32_t input[] = { 0x48656C6C, 0x6F2C2077 };
|
uint32_t inputWord[] = { 0x48656C6C, 0x6F2C2077 };
|
||||||
quiz_assert(Ion::crc32(input, 1) == 0x93591FFD);
|
quiz_assert(Ion::crc32Word(inputWord, 1) == 0x93591FFD);
|
||||||
quiz_assert(Ion::crc32(input, 2) == 0x72EAD3FB);
|
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