Перейти к содержанию
    

SD карта не просыпается

...

Пока разбирался с инициализации написал подсчет CRC7 на ASM (могу поделиться)

...

Было бы интересно взглянуть. :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ncr может быть от 0 до 8 байт.

Ncr - до 8, Nrc - 1.

 

Что характерно, действительно после любой команды нужно подавать 1 байт холостого чтения, иначе карта не будет нормально воспринимать следующую команду...

Вот это и есть Nrc.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Было бы интересно взглянуть. :rolleyes:

 

Пожалуйста...

 

CLR CRC

...

LDI A,$40

CALL CRC7

...

crc7.rar

Изменено пользователем svchost

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Несколько сыровато. Код непроверенный?

Да уж, надо было так запутать :(

 

Вот что получается, если написать просто "в лоб":

; 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А я в сети нашёл такой код:

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), чтобы ускорить рассчёт?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Интересно, нельзя никак избежать побитного цикла (i), чтобы ускорить рассчёт?

Можно, конечно. Хотя ускорять рассчет 5 байт большого смысла нет.

Вот для данных - это другое дело.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно, конечно. Хотя ускорять рассчет 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;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это понятно, но всё равно интересно - как?

Табличкой, например.

 

Для данных это да. Но для 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;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Табличкой, например.

Да, это вариант. Но самое прикольное - это хитрые варианты, когда без таблиц и без цилов, быстрое вычисление всего лишь несколькими командами.

Наверное, такое возможно не всегда...

 

Если интересно, то вот вариант для данных:

Спасибо, красивая реализация, небольшие таблички и минимум вычислений :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да уж, надо было так запутать :(

 

Вот что получается, если написать просто "в лоб":

; 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 и вполне понятен.

 

Спасибо.

Изменено пользователем svchost

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подпрограмма CRC7 полностью работоспособна.

У каждого свое решение. Считаю, что мой вариант полностью отражает

алгоритм подсчета CRC7 и вполне понятен.

Я лишь предложил более короткий и быстрый вариант. Не обижайтесь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

<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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

to ivstech and aaarrr: странно но результат вычисления CRC7 ваших алгоритмов разный.?! это нормально? :rolleyes:

разница в этой строчке у Вас aaarrr:

ori    crc, 1

Зачем она?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...