adc 0 2 июня, 2009 Опубликовано 2 июня, 2009 · Жалоба ... Пока разбирался с инициализации написал подсчет CRC7 на ASM (могу поделиться) ... Было бы интересно взглянуть. :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 2 июня, 2009 Опубликовано 2 июня, 2009 · Жалоба Ncr может быть от 0 до 8 байт. Ncr - до 8, Nrc - 1. Что характерно, действительно после любой команды нужно подавать 1 байт холостого чтения, иначе карта не будет нормально воспринимать следующую команду... Вот это и есть Nrc. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
svchost 0 3 июня, 2009 Опубликовано 3 июня, 2009 (изменено) · Жалоба Было бы интересно взглянуть. :rolleyes: Пожалуйста... CLR CRC ... LDI A,$40 CALL CRC7 ... crc7.rar Изменено 3 июня, 2009 пользователем svchost Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adc 0 4 июня, 2009 Опубликовано 4 июня, 2009 · Жалоба Пожалуйста... .. Спасибо! Несколько сыровато. Код непроверенный? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 4 июня, 2009 Опубликовано 4 июня, 2009 · Жалоба Несколько сыровато. Код непроверенный? Да уж, надо было так запутать :( Вот что получается, если написать просто "в лоб": ; X - указатель на данные, ; b - длина crc7: clr crc ldi d, 0x12 crc7_0: ld a, X+ eor crc, a ldi c, 8 crc7_1: lsl crc brcc PC+0x02 eor crc, d dec c brne crc7_1 dec b brne crc7_0 ori crc, 1 ret Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 4 июня, 2009 Опубликовано 4 июня, 2009 · Жалоба А я в сети нашёл такой код: u8 CRC7(u8* chr, int cnt) { int i,a; u8 crc = 0, data; for (a=0; a < cnt; a++) { data=chr[a]; for (i=0; i < 8; i++) { crc <<= 1; if ((data ^ crc) & 0x80) crc ^= 0x09; data <<= 1; } } return crc; } Интересно, нельзя никак избежать побитного цикла (i), чтобы ускорить рассчёт? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 4 июня, 2009 Опубликовано 4 июня, 2009 · Жалоба Интересно, нельзя никак избежать побитного цикла (i), чтобы ускорить рассчёт? Можно, конечно. Хотя ускорять рассчет 5 байт большого смысла нет. Вот для данных - это другое дело. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 4 июня, 2009 Опубликовано 4 июня, 2009 · Жалоба Можно, конечно. Хотя ускорять рассчет 5 байт большого смысла нет. Это понятно, но всё равно интересно - как? В сети нигде не нашёл работающего примера без битового цикла... Для данных это да. Но для SPI сумма не нужна (странно, конечно, но неужели надёжность SPI близка к 100%, чтобы в контрольной сумме отпала надобность?), а SDIO контроллеры будут считать её аппаратно... ЗЫ: вот ваша процедура на Си, она пооптимальнее, чем приведённая мной: u8 CRC7(u8* chr, int cnt) { int i,a; u8 crc = 0; for (a=0; a < cnt; a++) { crc ^= chr[a]; for (i=0; i < 8; i++) { if (crc & 0x80) { crc <<= 1; crc ^= 0x12; } else crc <<= 1; } } crc |= 1; return crc; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 4 июня, 2009 Опубликовано 4 июня, 2009 · Жалоба Это понятно, но всё равно интересно - как? Табличкой, например. Для данных это да. Но для SPI сумма не нужна (странно, конечно, но неужели надёжность SPI близка к 100%, чтобы в контрольной сумме отпала надобность?), а SDIO контроллеры будут считать её аппаратно... Для SPI ее можно не включать, но это не значит, что она не нужна. Я, например, включаю и использую. ЗЫ: вот ваша процедура на Си, она пооптимальнее, чем приведённая мной: Спасибо, конечно, а я-то специально на асм переводил :) Если интересно, то вот вариант для данных: const u_short sd_crc16_table_a[0x10] = { 0x0000, 0x1231, 0x2462, 0x3653, 0x48c4, 0x5af5, 0x6ca6, 0x7e97, 0x9188, 0x83b9, 0xb5ea, 0xa7db, 0xd94c, 0xcb7d, 0xfd2e, 0xef1f }; const u_short sd_crc16_table_b[0x10] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef }; u_int sd_crc16(u_char *buff, u_int len) { u_char data; u_short crc = 0; while(len--) { data = *buff++ ^ (crc >> 0x08); crc = (sd_crc16_table_a[(data & 0xf0) >> 4] ^ sd_crc16_table_b[data & 0x0f]) ^ (crc << 8); } return crc; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 4 июня, 2009 Опубликовано 4 июня, 2009 · Жалоба Табличкой, например. Да, это вариант. Но самое прикольное - это хитрые варианты, когда без таблиц и без цилов, быстрое вычисление всего лишь несколькими командами. Наверное, такое возможно не всегда... Если интересно, то вот вариант для данных: Спасибо, красивая реализация, небольшие таблички и минимум вычислений :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
svchost 0 4 июня, 2009 Опубликовано 4 июня, 2009 (изменено) · Жалоба Да уж, надо было так запутать :( Вот что получается, если написать просто "в лоб": ; X - указатель на данные, ; b - длина crc7: clr crc ldi d, 0x12 crc7_0: ld a, X+ eor crc, a ldi c, 8 crc7_1: lsl crc brcc PC+0x02 eor crc, d dec c brne crc7_1 dec b brne crc7_0 ori crc, 1 ret Подпрограмма CRC7 полностью работоспособна. У каждого свое решение. Считаю, что мой вариант полностью отражает алгоритм подсчета CRC7 и вполне понятен. Спасибо. Изменено 4 июня, 2009 пользователем svchost Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 4 июня, 2009 Опубликовано 4 июня, 2009 · Жалоба Подпрограмма CRC7 полностью работоспособна. У каждого свое решение. Считаю, что мой вариант полностью отражает алгоритм подсчета CRC7 и вполне понятен. Я лишь предложил более короткий и быстрый вариант. Не обижайтесь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ivstech 0 4 июня, 2009 Опубликовано 4 июня, 2009 · Жалоба <br />Да, это вариант. Но самое прикольное - это хитрые варианты, когда без таблиц и без цилов Когда флэша нехватает, я использую такой код ; in/out YH аккумулятор ; in R18 следующий байт CRC7Update: eor YH, R18 ; Левый полубайт mov R19, YH andi R19, 0xF0 swap R19 eor YH, R19 swap R19 add R19, R19 brcc CRC7Skip ldi YL, 0x01 eor YH, YL CRC7Skip: mov YL, R19 ; Правый полубайт mov R19, YH andi R19, 0x0F swap R19 eor YL, R19 swap R19 add R19, R19 eor YL, R19 mov YH, YL ret и ; IN: R4, R5 - аккумулятор CRC ; R18 - значение ; OUT: R4, R5 ; По модулю 0x11021 CRC16Update: push R18 push R19 eor R4, R18 ; Левый полубайт mov R19, R4 andi R19, 0xF0 mov R18, R19 swap R19 eor R4, R19 add R19, R19 eor R5, R19 ; Правый полубайт mov R19, R4 andi R19, 0x0F eor R18, R19 swap R19 eor R5, R19 add R19, R19 brcc CRC16Skip clr R4 inc R4 eor R5, R4 CRC16Skip: eor R18, R19 mov R4, R5 mov R5, R18 pop R19 pop R18 ret Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adc 0 5 июня, 2009 Опубликовано 5 июня, 2009 · Жалоба to ivstech and aaarrr: странно но результат вычисления CRC7 ваших алгоритмов разный.?! это нормально? :rolleyes: разница в этой строчке у Вас aaarrr: ori crc, 1 Зачем она? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 5 июня, 2009 Опубликовано 5 июня, 2009 · Жалоба Зачем она? Считаем мы CRC7, а это end bit - см. Command Format в спецификации SD. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться