|
|
  |
SD card on SPI, как организовать общение c SD картой по SPI ? |
|
|
|
Sep 11 2009, 13:04
|
Частый гость
 
Группа: Свой
Сообщений: 101
Регистрация: 22-08-07
Пользователь №: 29 977

|
Отвечу сам себе... причину нашел  , и она кроется где то в недрах DMA режима. Дело в том что в исходнике от Analog Device почему то используется SPI в DMA chain mode with interrupts, т.е. модулю DMA нужно сообщить адрес первого байта команды, кол-во байт, назначить процедуру прерывания, куда попадаем после приема очередного байта. Такой код предназначен для работы в фоновом режиме и использует всю мощь проца,но с другой создает много проблем - например DMA работает только с внутренней памятью, и имеет свои заморочки которые часто заканчиваются зависанием проца (например когда несколько модулей его используют одновременно). На экране осциллографа все выглядит так как должно быть, но карта постоянно выдает ошибки. В общем отключил я все эти навороты, написал блокирующую процедуру вывода в SPI и все заработало вплоть до 20 Мгц CLK
Сообщение отредактировал Ndf - Sep 11 2009, 13:05
|
|
|
|
|
Jan 19 2013, 12:09
|

Гуру
     
Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702

|
Цитата(Ndf @ Sep 10 2009, 16:36)  Прочитал еще раз spec... да, действительно, после ответа R1 на CMD9, клоки снимать не надо так как MMC/SD карта следом отправляет данные CSD регистра. Скажите , в каком документе написано как читать CSD в режиме SPI ? Уже третий день мучаюсь : Принимаю всё что карта ответила на CMD9 , 21 байт он начала и до того как пошли FF. Пытаюсь увидеть последовательность байтов как в CSD Version 1.0 (карта 1Гб) : 1 байт 0, 2,3 байт хх 4 байт 32 или 5А Но не вижу что бы 0 шёл на три байта раньше 0x32
--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
|
|
|
|
|
Jan 20 2013, 11:58
|
Частый гость
 
Группа: Участник
Сообщений: 147
Регистрация: 18-05-12
Пользователь №: 71 915

|
может поможет - вот рабочий код: Код enum sd_type {SD_NONE, SD_V1, SD_V2, MMC_V3}; enum {CSD_V1=0, CSD_V2=1}; enum { CMD0=0,CMD1=1,CMD2=2,CMD8=8,CMD9=9,CMD10=10,CMD13=13,CMD16=16,CMD17=17, CMD55=55,CMD58=58,CMD59=59,ACMD41=41 }; enum { R1_READY=0x00, R1_IDLE=0x01, R1_ERASE_RESET=0x02, R1_CMD_ILLEGAL=0x04, R1_CMD_CRC=0x08, R1_ERASE_SEQ=0x10, R1_ADDR=0x20, R1_PARAM=0x40 }; U8 sd_get_CSD(void) { sd_cs(0); sd_cmd_NoCRC(CMD9, 0x00000000, 0x57); sd.r1 = (sd_get_R1() == R1_READY); if (sd.r1) { sd.r1 = sd_get_buf(&sd.csd[0], 16, 0xFE); sd_update_csd(); } return sd.r1; } void sd_cmd_NoCRC(U8 cmd, U32 data, U8 crc) { spi_tx_U8_MSB(0xFF); spi_tx_U8_MSB(0x40 | cmd); spi_tx_U8_MSB(data >> 24); spi_tx_U8_MSB(data >> 16); spi_tx_U8_MSB(data >> 8); spi_tx_U8_MSB(data); spi_tx_U8_MSB((crc << 1) | 1); } U8 sd_get_R1(void) { U8 r1 = 0; U16 to = SD_CMD_TIMEOUT; do { r1 = spi_tx_U8_MSB(0xFF); } while (--to && (r1 == 0xFF)); sd.r1 = r1; return r1; } U8 sd_get_buf(U8 *buf, U16 len, U8 token) { U8 r1 = 0; U16 to = SD_CMD_TIMEOUT; do { r1 = (spi_tx_U8_MSB(0xFF) == token); } while (--to && !r1); if (r1) { spi_rx_buf_MSB(buf, len);
//skip CRC spi_tx_U8_MSB(0xFF); spi_tx_U8_MSB(0xFF); } return r1; } void sd_update_csd(void) { sd.sectors = 0; if (sd_ok()) { sd.ver = sd.csd[0] >> 6; if (sd.ver == CSD_V1) { U32 size = 1UL << (sd.csd[5] & 0xF); size *= 1UL << (((sd.csd[9] & 0x3) << 1) + (sd.csd[10] >> 7) + 2); size *= (U32)((((U16)(sd.csd[6] & 3)) << 10) + ((U16)sd.csd[7] << 2) + ((U16)(sd.csd[8] & 0xC0) >> 6) + 1); sd.sectors = size >> 9; } else if (sd.ver == CSD_V2) { sd.sectors = ((((U32)(sd.csd[7] & 0x3F)) << 16) + (((U32)sd.csd[8]) << 8) + (U32)sd.csd[9]) << 10; } } }
Сообщение отредактировал polyname - Jan 20 2013, 12:00
|
|
|
|
|
Jul 23 2014, 19:46
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(ohmjke @ Jul 23 2014, 15:19)  Пишу на SDHC блок и после этого читаю его. После записи сначала жду токена Data response со значением Data accepted - все ОК, получаю его сразу после второго байта CRC16. Затем, как я понял, карта шлёт busy байты в виде нулей, типа происходит запись из буфера в саму flash. Но эти busy заканчиваются только через 6-10 мс! Неужели, так и должно быть? Если так ждать после записи каждого байта, то получится максимальная скорость не более 100кБ/сек - бред.
Сейчас ещё раз глянул анализатором сразу после подачи питания - так busy длится вообще 20мс... Ага. И при чтении может быть весело: Цитата SP uSD 16GB <0.5ms – 4562197; <1.0ms - 52698; <2.0ms - 4683; <5.0ms - 2; <10 ms - 1; <20 ms - 18; <50 ms - 1971; >50 ms - 4; max - 59.9 ms Карта непрерывно читается. Измеряется время ожидания начала данных. После тире указано число случаев для данного диапазона. Для этой карты было 4 случая, когда данные были не готовы дольше 50 мс. Максимальное время ожидания почти 60 мс. Самая беда в том, что чтение начинает тормозить в среднем по 46 мс но на протяжении секунды: Цитата <51254590:43.9ms-12075> <+40:44.3ms-12147> <+50:44.1ms-12123> <+40:44.2ms-12139> <+50:44.1ms-12113> <+50:44.1ms-12091> <+40:44.1ms-12111> <+50:43.9ms-12057> <+50:47.4ms-13023> <+50:43.8ms-12001> <+40:45.8ms-12577> <+50:45.8ms-12573> <+70:45.5ms-12501> <+50:45.7ms-12541> <+40:45.7ms-12551> <+50:45.4ms-12467> <+70:46.0ms-12649> <+40:45.8ms-12573> <+50:46.3ms-12711> <+30:26.5ms-7271> <+40:27.5ms-7541> Тут формат такое <реальное время или смещение в мс от последнего события : время ожидания данных - число байт переданных в карту до момента ответа>
|
|
|
|
|
Jul 25 2014, 06:41
|
Частый гость
 
Группа: Свой
Сообщений: 101
Регистрация: 22-08-07
Пользователь №: 29 977

|
Цитата(ohmjke @ Jul 23 2014, 15:19)  Пишу на SDHC блок и после этого читаю его. После записи сначала жду токена Data response со значением Data accepted - все ОК, получаю его сразу после второго байта CRC16. Затем, как я понял, карта шлёт busy байты в виде нулей, типа происходит запись из буфера в саму flash. Но эти busy заканчиваются только через 6-10 мс! Неужели, так и должно быть? Если так ждать после записи каждого байта, то получится максимальная скорость не более 100кБ/сек - бред. Сейчас ещё раз глянул анализатором сразу после подачи питания - так busy длится вообще 20мс... Так и должно быть (у меня размер сектора 512 байт). Причем я не заметил чтобы SPI mode работал медленнее SD mode в режиме записи.
|
|
|
|
|
Feb 19 2016, 10:24
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Ruslan-maniak @ Feb 19 2016, 12:21)  Помогите, товарищи. Третий день не могу запустить нормально SD карту. Работаю по SPI. Инициализация проходит нормально. Также OCR считывается вполне адекватным {0x80, 0xFF, 0x80, 0x00}. Но абсолютно на все остальные команды карта отвечает 0x05: и чтение CSD, и CID, и просто блоков памяти. Ничего не получается. Карта в картридере работает адекаватно. Если не ошибаюсь, то для некоторых команд ответ идёт не сразу, а надо вычитать несколько пустых (0xFF) байт. Может в этом проблема?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|