ffs2001 0 3 декабря, 2014 Опубликовано 3 декабря, 2014 · Жалоба Господа, помогите советом: хочу считать CRC-32 на указанном МК. Аппаратный модуль имеется. Код использовал родной атмелевский отсюда и упрощённый вариант: CRC_CTRL |= CRC_CRC32_bm; CRC.CTRL |= CRC_SOURCE_IO_gc; for (n = 0; n < 32; n++){ CRC.DATAIN = test[n]; // send data } CRC.STATUS |= CRC_BUSY_bm; // finish while (CRC_STATUS & CRC_BUSY_bm == CRC_BUSY_bm); itoa(CRC.CHECKSUM3,str); puts_usf0(str); //и так далее Сам модуль работает, но выдаёт неверные данные. Проверял вот этим калькулятором. Полиномы совпадают, в даташите есть описание. В эррате ничего. Тестовый массив: uint8_t[32] = {0xFF} ЧЯДНТ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 35 3 декабря, 2014 Опубликовано 3 декабря, 2014 · Жалоба CRC_CTRL |= CRC_CRC32_bm; CRC.CTRL |= CRC_SOURCE_IO_gc; Сам модуль работает, но выдаёт неверные данные. Возможно, вы забыли сделать обнуление перед накоплением. CRC_CTRL = CRC_CRC32_bm | CRC_SOURCE_IO_gc; CRC_CTRL |= CRC_RESET_RESET0_gc; // Reset CRC with CHECKSUM to all zeros P.S. И вот еще: надо вызывать функцию ltoa(CRC.CHECKSUM3,str); вместо itoa(CRC.CHECKSUM3,str); Т.к. int у XMega 16-битный. CRC32 тогда long, а не int. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ffs2001 0 4 декабря, 2014 Опубликовано 4 декабря, 2014 · Жалоба Возможно, вы забыли сделать обнуление перед накоплением. CRC_CTRL = CRC_CRC32_bm | CRC_SOURCE_IO_gc; CRC_CTRL |= CRC_RESET_RESET0_gc; // Reset CRC with CHECKSUM to all zeros Да, в атмелевском драйвере это есть. С него начал. Там ещё есть аж две малопонятных для меня инверсии; но и с ними, и без них результат даже примерно не похож на нужный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 4 декабря, 2014 Опубликовано 4 декабря, 2014 · Жалоба Да, в атмелевском драйвере это есть. Драйвер неправильный (или может его исправили?). Попробуйте такой код, он вроде работал: uint32_t Crc32(uint8_t * data, uint16_t data_size, bool init_zero, uint32_t xor_value) { CRC.CTRL=0 | init_zero ? (CRC_RESET_RESET0_gc) : (CRC_RESET_RESET1_gc) | 1<<CRC_CRC32_bp | CRC_SOURCE_IO_gc ; CRC.CTRL=0 | CRC_RESET_NO_gc | 1<<CRC_CRC32_bp | CRC_SOURCE_IO_gc ; CRC.STATUS=1<<CRC_BUSY_bp; uint8_t byte_counter=0; for (uint8_t i=0; i<data_size; i++) CRC.DATAIN=*data++; uint32_t crc=*(volatile uint32_t *)&CRC.CHECKSUM0; crc^=xor_value; return crc; } typedef dma_channel<'0'> Dma0; uint32_t CrcDma(uint8_t * data, bool init_zeros, uint16_t length) { CRC.CTRL=0 | init_zeros ? CRC_RESET_RESET1_gc : CRC_RESET_RESET0_gc | 1<<CRC_CRC32_bp | CRC_SOURCE_DMAC0_gc ; CRC.CTRL=0 | CRC_RESET_NO_gc | 1<<CRC_CRC32_bp | CRC_SOURCE_DMAC0_gc ; Dma0::ResetChannel(); Dma0::SetSrcAddress((uint16_t)data); Dma0::SetDestAddress((uint16_t)data); Dma0::SetAddressControl(DMA_CH_SRCRELOAD_NONE_gc, DMA_CH_SRCDIR_INC_gc, DMA_CH_DESTRELOAD_NONE_gc, DMA_CH_DESTDIR_INC_gc); Dma0::SetTransferSize(length); Dma0::SetTriggerSource(DMA_CH_TRIGSRC_OFF_gc); Dma0::StartRamToRamTransfer(DMA_CH_BURSTLEN_8BYTE_gc); while (Dma0::TransferComplete()==false); uint32_t crc = *(uint32_t *)&CRC.CHECKSUM0; return crc; } В драйвере не было вроде такой строки (функция Crc32): CRC.STATUS=1<<CRC_BUSY_bp; С ДМА как ни странно работало без проблем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ffs2001 0 4 декабря, 2014 Опубликовано 4 декабря, 2014 · Жалоба Так, проблема, похоже, не в контроллере. В этом калькуляторе получается то же значение, что выдаёт мой контроллер. Проблема в том, что в него я скопировал полином из этого калькулятора, где получается другое значение (с этим полиномом). Это, как говорится, какое-то фуфло; но бедная иксмега не при чём. Когда разберусь с полиномами, отпишу, в чём соль. Драйвер неправильный (или может его исправили?). Мда, печально. Расскажите подробнее, если не затруднит. В драйвере не было вроде такой строки (функция Crc32): CRC.STATUS=1<<CRC_BUSY_bp; С ДМА как ни странно работало без проблем. Да, уже обрабатывал этот момент; это единственная ошибка в драйвере? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 4 декабря, 2014 Опубликовано 4 декабря, 2014 · Жалоба Мда, печально. Расскажите подробнее, если не затруднит. Рассказывать-то и нечего: есть стандартная функция расчёта CRC /* Name : CRC-32 Poly : 0x04C11DB7 x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 Init : 0xFFFFFFFF Revert: true XorOut: 0xFFFFFFFF Check : 0xCBF43926 ("123456789") MaxLen: 268 435 455 байт (2 147 483 647 бит) - обнаружение одинарных, двойных, пакетных и всех нечетных ошибок */ uint_least32_t Crc32Soft(uint8_t *buf, size_t len, uint32_t init_value) { uint_least32_t crc_table[256]; uint_least32_t crc; int i, j; for (i = 0; i < 256; i++) { crc = i; for (j = 0; j < 8; j++) crc = crc & 1 ? (crc >> 1) ^ 0xEDB88320UL : crc >> 1; crc_table[i] = crc; }; crc = init_value; while (len--) crc = crc_table[(crc ^ *buf++) & 0xFF] ^ (crc >> 8); return crc ^ 0xFFFFFFFFUL; } Результат CRC32 который выдаёт модуль xmega не совпадает с ним для CRC32. это единственная ошибка в драйвере? Я драйвер подробно не рассматривал, смотрел пример который шёл вместе со AtmelStudio. И в примере результат неправильный получается. драйвере? Да в общем-то тут и драйвер-то не нужен - там весь модуль 3 регистра. Самому проще написать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ffs2001 0 4 декабря, 2014 Опубликовано 4 декабря, 2014 · Жалоба Рассказывать-то и нечего: есть стандартная функция расчёта CRC Благодарю! В общем, CRC-модуль, похоже, рабочий. Теперь (немного в сторону от темы) ситуация получилась такая: модуль xmega и вот этот калькулятор выдают одинаковое значение; библиотека CRC-32 для VS (PC) и вот этот калькулятор тоже выдают одинаковое значение, но другое! Полином везде один и тот же. Видимо, под конец они как-то хитро XOR-ятся или ещё что... Тестовое значение (hex) 940C. Буду очень рад, если кто-нибудь объяснит, как так происходит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 4 декабря, 2014 Опубликовано 4 декабря, 2014 · Жалоба Полином везде один и тот же. Возможно они инициализируют crc перед началом подсчёта нулями, а вы единицами. Или наоборот. Попробуйте посчитать CRC по функции из сообщения 6. uint8_t Test10[10]={1,2,3,4,5,6,7,8,9,10}; volatile uint32_t soft_crc[2]; soft_crc[0]=Crc32Soft(Test, sizeof(Test), 0xFFFFFFFFUL); soft_crc[1]=Crc32Soft(Test, sizeof(Test), 0); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ffs2001 0 4 декабря, 2014 Опубликовано 4 декабря, 2014 · Жалоба Результаты работы приведённого кода идентичны результатам библиотеки для PC (собственно, и код идентичен). Крайне смущает совпадение результатов из xmega'вского генератора с другим калькулятором. Хочу использовать hardware генератор, т.к. нужно считать CRC app-table из бутлодера. Буду копать дальше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 4 декабря, 2014 Опубликовано 4 декабря, 2014 · Жалоба Хочу использовать hardware генератор, т.к. нужно считать CRC app-table из бутлодера. Тогда лучше использовать подсчёт CRC через команду NVM-контроллера Flash range CRC - оно само подсчитает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ffs2001 0 4 декабря, 2014 Опубликовано 4 декабря, 2014 · Жалоба Тогда лучше использовать подсчёт CRC через команду NVM-контроллера Flash range CRC - оно само подсчитает. Так будет использоваться тот же самый хардварный генератор. А он выдаёт не то. Совпадение калькулятора и генератора, похоже, было случайным. Совпадают только значения, генерируемые из массива [32] = {0xFF} Делаю вывод, что хардварный генератор нерабочий. Странно, что этого нет в эррате. При возможности проверю на другом контроллере, отпишусь. Ещё интересный нюанс относительно приведённого в сообщении 6 кода: crc = crc & 1 ? (crc >> 1) ^ 0xEDB88320UL : crc >> 1; Visual studio ругнулась тут на невозможность привести int к bool, и я ничтоже сумняшеся привёл код к виду for (j = 0; j < 8; j++) { if ((crc & 1) == 1) { crc = (crc >> 1) ^ 0xedb88320u; } else { crc = (crc >> }; crc_table[i] = crc; тем более что так это реализовано в библиотеке, которую я использовал для PC. Компилятор для Атмеги (работаю в CVAVR) на эту строку не ругнулся. Но если не привести код к тому же виду, результат получается РАЗНЫЙ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 4 декабря, 2014 Опубликовано 4 декабря, 2014 · Жалоба Так будет использоваться тот же самый хардварный генератор. А он выдаёт не то. То он выдаёт. Совпадение калькулятора и генератора, похоже, было случайным. Совпадают только значения, генерируемые из массива [32] = {0xFF} Ну да,случайность... У меня при входных данных из комментария к функции /* Name : CRC-32 Poly : 0x04C11DB7 x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 Init : 0xFFFFFFFF Revert: true XorOut: 0xFFFFFFFF Check : 0xCBF43926 ("123456789") MaxLen: 268 435 455 байт (2 147 483 647 бит) - обнаружение одинарных, двойных, пакетных и всех нечетных ошибок */ результат получался всеми тремя способами одинаковый - 0xCBF43926. Случайно... Проверял в симуляторе - плату лень искать. На PC не проверял - не нашёл реализацию. Делаю вывод, что хардварный генератор нерабочий. Странно, что этого нет в эррате. Описан он в мануале как-то криво. Но работает. При возможности проверю на другом контроллере, отпишусь. У меня проверялось в atxmega256A3U Компилятор для Атмеги (работаю в CVAVR) на эту строку не ругнулся. Но если не привести код к тому же виду, результат получается РАЗНЫЙ. Вот проект для GCC: crc32_02.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ffs2001 0 5 декабря, 2014 Опубликовано 5 декабря, 2014 (изменено) · Жалоба Проверил на двух 64ых, результаты разные для hard и soft в обоих случаях. Правильное значение выдаёт soft. Очень странно. Изменено 5 декабря, 2014 пользователем ffs2001 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 5 декабря, 2014 Опубликовано 5 декабря, 2014 · Жалоба результаты разные для hard и soft в обоих случаях. Очень странно. Проверил на xmega256A3U - hard, soft и dma дают одинаковый результат. Проверил на двух 64ых На двух? Тенденция , однако...Выложите проект, а вдруг и правда в 64х ошибка. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ffs2001 0 8 декабря, 2014 Опубликовано 8 декабря, 2014 · Жалоба Проект для CVAVR 3.1 . Скомпилированные ROM и HEX в Debug. CRC_test.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться