46 #if defined(CLASSB_CRC_USE_HW) || defined(__DOXYGEN__)
52 uint32_t crc_initial_value = 0;
69 static inline void nvm_issue_command(NVM_CMD_t nvm_command)
74 NVM.CMD = nvm_command;
77 NVM.CTRLA = NVM_CMDEX_bm;
93 static inline bool crc_is_busy(
void)
95 return ((CRC_STATUS & CRC_BUSY_bm) == CRC_BUSY_bm);
112 void crc_io_checksum_byte_add(uint8_t data)
127 static inline void crc_reset(
void)
130 CRC_CTRL |= CRC_RESET_RESET0_gc;
133 CRC.CHECKSUM0 = crc_initial_value & 0xFF;
134 CRC.CHECKSUM1 = (crc_initial_value >> 8) & 0xFF;
135 CRC.CHECKSUM2 = (crc_initial_value >> 16) & 0xFF;
136 CRC.CHECKSUM3 = (crc_initial_value >> 24) & 0xFF;
138 crc_initial_value = 0;
151 static inline uint16_t crc16_checksum_read(
void)
155 checksum = ((uint16_t)CRC_CHECKSUM0 & 0x00FF);
156 checksum |= (((uint16_t)CRC_CHECKSUM1 << 8) & 0xFF00);
173 static inline uint32_t crc32_checksum_read(
void)
177 checksum = ((uint32_t)CRC_CHECKSUM0 & 0x000000FF);
178 checksum |= (((uint32_t)CRC_CHECKSUM1 << 8) & 0x0000FF00);
179 checksum |= (((uint32_t)CRC_CHECKSUM2 << 16) & 0x00FF0000);
180 checksum |= (((uint32_t)CRC_CHECKSUM3 << 24) & 0xFF000000);
199 static inline uint32_t crc_checksum_read(
void)
202 while (crc_is_busy()) {
207 if ((CRC_CTRL & CRC_CRC32_bm) == CRC_CRC32_bm) {
208 return crc32_checksum_read();
210 return crc16_checksum_read();
227 static inline void crc_set_source(CRC_SOURCE_t source)
229 CRC_CTRL &= ~CRC_SOURCE_gm;
241 static inline void crc_disable(
void)
243 crc_set_source(CRC_SOURCE_DISABLE_gc);
253 static inline uint32_t crc_checksum_complete(
void)
258 checksum = crc_checksum_read();
277 void crc_set_initial_value(uint32_t value)
279 crc_initial_value = value;
298 uint32_t crc_io_checksum(
void *data, uint16_t len,
enum crc_16_32_t crc_16_32)
301 crc_io_checksum_byte_start(crc_16_32);
305 crc_io_checksum_byte_add(*(uint8_t*)data);
306 data = (uint8_t*)data + 1;
310 return crc_io_checksum_byte_stop();
325 static inline void crc_32_enable(
void)
327 CRC_CTRL |= CRC_CRC32_bm;
343 void crc_io_checksum_byte_start(
enum crc_16_32_t crc_16_32)
348 if (crc_16_32 == CRC_32BIT) {
352 crc_set_source(CRC_SOURCE_IO_gc);
366 uint32_t crc_io_checksum_byte_stop(
void)
369 CRC_STATUS |= CRC_BUSY_bm;
372 return crc_checksum_complete();
376 #endif // defined(CLASSB_CRC_USE_HW)
381 #if (defined(CLASSB_CRC_USE_HW) && defined(CLASSB_CRC_16_BIT)) || defined(__DOXYGEN__)
398 crc_set_initial_value(CRC16_INITIAL_REMAINDER);
402 dataptr += MAPPED_EEPROM_START;
404 uint32_t checksum = crc_io_checksum((
void*)dataptr, numBytes, CRC_16BIT);
407 #if defined(__ICCAVR__)
411 if ( checksum != *pchecksum)
413 #elif defined(__GNUC__)
424 return (checksum & 0x0000FFFF);
444 crc_set_initial_value(CRC16_INITIAL_REMAINDER);
446 crc_io_checksum_byte_start(CRC_16BIT);
449 for (; numBytes != 0; numBytes--) {
450 #if (PROGMEM_SIZE >= 0x10000UL)
451 dataTemp = PROGMEM_READ_BYTE_FAR(dataptr++);
453 dataTemp = PROGMEM_READ_BYTE(dataptr++);
456 crc_io_checksum_byte_add(dataTemp);
459 uint32_t checksum = crc_io_checksum_byte_stop();
461 #if defined(__ICCAVR__)
463 if ( checksum != *pchecksum)
465 #elif defined(__GCC__)
475 return (checksum & 0x0000FFFF);
494 void crc16_append_value(uint16_t value,
void *ptr)
496 *(uint8_t*)ptr = (value >> 8);
497 *((uint8_t*)ptr+1) = value;
500 #endif // defined(CLASSB_CRC_USE_HW) && defined(CLASSB_CRC_16_BIT)
505 #if (defined(CLASSB_CRC_USE_HW) && defined(CLASSB_CRC_32_BIT)) || defined(__DOXYGEN__)
521 crc_set_initial_value(CRC32_INITIAL_REMAINDER);
525 dataptr += MAPPED_EEPROM_START;
527 uint32_t checksum = crc_io_checksum((
void*)dataptr, numBytes, CRC_32BIT);
529 #if defined(__ICCAVR__)
533 if ( checksum != *pchecksum)
535 #elif defined(__GCC__)
563 crc_set_initial_value(CRC32_INITIAL_REMAINDER);
566 uint32_t checksum = crc_flash_checksum(crc_type, (
flash_addr_t)dataptr, numBytes);
568 #if defined(__ICCAVR__)
570 if ( checksum != *pchecksum)
572 #elif defined(__GNUC__)
602 void crc32_append_value(uint32_t value,
void *ptr)
604 *(uint8_t*)ptr = value & 0xFF;
605 *((uint8_t*)ptr+1) = (value >> 8) & 0xFF;
606 *((uint8_t*)ptr+2) = (value >> 16) & 0xFF;
607 *((uint8_t*)ptr+3) = (value >> 24) & 0xFF;
636 uint32_t crc_flash_checksum(NVM_CMD_t crc_type,
flash_addr_t flash_addr, uint32_t length)
649 crc_set_source(CRC_SOURCE_FLASH_gc);
652 nvm_issue_flash_range_crc(flash_addr, flash_addr + length - 1);
654 nvm_issue_command(crc_type);
658 return crc_checksum_complete();
687 NVM.CMD = NVM_CMD_FLASH_RANGE_CRC_gc;
690 NVM.ADDR0 = start_addr & 0xFF;
691 NVM.ADDR1 = (start_addr >> 8) & 0xFF;
692 #if (PROGMEM_SIZE >= 0x10000UL)
693 NVM.ADDR2 = (start_addr >> 16) & 0xFF;
697 NVM.DATA0 = end_addr & 0xFF;
698 NVM.DATA1 = (end_addr >> 8) & 0xFF;
699 #if (PROGMEM_SIZE >= 0x10000UL)
700 NVM.DATA2 = (end_addr >> 16) & 0xFF;
705 NVM.CTRLA = NVM_CMDEX_bm;
711 #endif //defined(CLASSB_CRC_USE_HW) && defined(CLASSB_CRC_32_BIT)