sst78rus 0 24 октября, 2019 Опубликовано 24 октября, 2019 · Жалоба Добрый день. Пытаюсь подключить SD карту. Раньше делал уже это на F4, теперь переделываю под новый SDMMC в h7. Контроллер STM32H743, карта подключена по SDIO 4-bit, не получаю ответ на команды инициализации. Карта подключена "классическим" способом, D0-D4, CMD, CLK. В схемах на EVAL платы подключение другое, для поддержки карт с питанием 1.8в (и большей частотой). Использую SDMMC1. Тактирование от PLL1, на выходе DIVQ1 48Mhz. На время инициализации ставлю делитель 60. 48Mhz/(60*2) = 400kHz Включение SDMMC1: RCC->AHB3ENR |= RCC_AHB3ENR_SDMMC1EN; RCC->AHB3RSTR |= RCC_AHB3RSTR_SDMMC1RST; for(uint8_t i=0; i<0x10; i++) asm volatile("nop"); RCC->AHB3RSTR &= ~RCC_AHB3RSTR_SDMMC1RST; SDIO->CLKCR = SDIO_CLK_DIV_INIT; //#define SDIO_CLK_DIV_INIT ((uint32_t)0x03C) SDIO->POWER |= SDMMC_POWER_PWRCTRL; //Ожидание, 74 цикла for(uint32_t i=0; i<0x1000; i++) asm volatile("nop"); После включения питания, в реф. мане указано подождать 74 цикла. Циклы видимо по линии SD_CLK, поэтому тут пока задержка просто "на глаз" (оптимизация на данный момент выключена). В любом случае, я в отладчике шагаю, так что оно точно успевает 74 "тикнуть". После этого, если я правильно читаю, карта готова к инициализации. Для отправки команд использую такую конструкцию: uint8_t SD_Cmd(uint8_t cmd, uint32_t arg, uint16_t response_type, uint32_t *response){ SDIO->ICR = SDMMC_ICR_CCRCFAILC | SDMMC_ICR_CTIMEOUTC | SDMMC_ICR_CMDRENDC | SDMMC_ICR_CMDSENTC; SDIO->ARG = arg; SDIO->CMD = (uint32_t)(response_type | cmd | SDMMC_CMD_CPSMEN); while((SDIO->STA & (SDMMC_STA_CMDSENT|SDMMC_STA_CMDREND)) == 0){asm("nop");}; if (response_type != SDIO_RESP_NONE) { response[0] = SDIO->RESP1; response[1] = SDIO->RESP2; response[2] = SDIO->RESP3; response[3] = SDIO->RESP4; } if (SDIO->STA & SDMMC_STA_CTIMEOUT) return 2; if (SDIO->STA & SDMMC_STA_CCRCFAIL) return 3; return 0; } И пробую инициализировать карту: Отправляю команду CMD_0 без ожидания ответа. Команда проходит, в STA поднимается флаг CMDSENT, ошибок нет. Отправляю команду CMD_8. Аргумент - CHECK PATTERN 0x01A, ответ R7(короткий). В STA поднимается флаг CMDREND (флагов ошибок нет) , но в RESP регистрах нули, а должен был придти CHECK PATTERN. Переменная response на которую передаю указатель расположена в RAM_D1. Но я в отладчике на содержимое регистров смотрю, что ответа нет. На время отладки MPU отключен, кеш отключен. На второй такой же плате установлен F429 (корпус LQFP176, они pin-to-pin заменяемы), там этаже SD карта работает без проблем. Т.е. с разводкой все должно быть нормально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sst78rus 0 24 октября, 2019 Опубликовано 24 октября, 2019 · Жалоба Вопрос снимается :) Стал проверять "невозможное", оказалось в ините GPIO для ноги CMD не очищал предварительно регистр MODER, соответственно при операции "OR" он оставался в значении по умолчанию 11-Аналог, а не альт. функция. Но поскольку создал тему, поинтересуюсь про новые возможности SDMMC. Обычные SD карты памяти, те что можно в магазине купить, поддерживают режимы работы с увеличенной частотой и питанием 1.8в? Насколько больше скорость чтения и записи? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 24 октября, 2019 Опубликовано 24 октября, 2019 · Жалоба 2 minutes ago, sst78rus said: Обычные SD карты памяти, те что можно в магазине купить, поддерживают режимы работы с увеличенной частотой и питанием 1.8в? Насколько больше скорость чтения и записи? В магазине можно купить UHS-I. Чтение до 100МБайт/с, запись - как повезет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sst78rus 0 24 октября, 2019 Опубликовано 24 октября, 2019 · Жалоба Удалось запустить чтение, содержимое каталога через FATFs прочитал. А как правильно работать с IDMA? Максимальный размер буфера который можно указать - 0xFF * 32 = 8160 байт. А если нужно больше? "В ручную" разбивать буфер на куски? Или можно как-то связать с MDMA, и отправлять сразу буфер большего размера? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Шаманъ 0 28 октября, 2019 Опубликовано 28 октября, 2019 · Жалоба On 10/24/2019 at 5:08 PM, sst78rus said: Максимальный размер буфера который можно указать - 0xFF * 32 = 8160 байт. Речь про регистр IDMABSIZE я так понимаю? Вы описание его внимательно прочитайте - этот регистр используется только в режиме с двумя буферами. В обычном режиме через IDMA можно пропустить столько сколько нужно данных (размер задается через DLEN). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sst78rus 0 29 октября, 2019 Опубликовано 29 октября, 2019 · Жалоба Спасибо, действительно, в описании регистра это указано, просмотрел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jeka 0 6 ноября, 2019 Опубликовано 6 ноября, 2019 · Жалоба Тоже сейчас ковыряюсь с h743 и sd, запускаю без конвертора напряжений на 3.3v Через hal пока нормально работает только поллинг. Как только включаю irq/idma, чтение тупит и по тайм-ауту вываливается. irq какие-то прилетают, отдаю в hal. но в дебаггере ловлю флаг overrun (вероятно из-за остановки дебагером). Но поллинг не устраивает, ибо нужна скорость. Задач много, своё писать и hal глубоко расковыривать не очень хочется. Если есть рабочая реализация под rtos (желательно без hal) может поделитесь наработками? Бюджет обговариается :) upd: вроде разобрался. оказывается DMA пишет только в регион памяти AXISRAM. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sst78rus 0 7 ноября, 2019 Опубликовано 7 ноября, 2019 · Жалоба 14 часов назад, jeka сказал: Тоже сейчас ковыряюсь с h743 и sd, запускаю без конвертора напряжений на 3.3v Через hal пока нормально работает только поллинг. Как только включаю irq/idma, чтение тупит и по тайм-ауту вываливается. irq какие-то прилетают, отдаю в hal. но в дебаггере ловлю флаг overrun (вероятно из-за остановки дебагером). Но поллинг не устраивает, ибо нужна скорость. Задач много, своё писать и hal глубоко расковыривать не очень хочется. Если есть рабочая реализация под rtos (желательно без hal) может поделитесь наработками? Бюджет обговариается :) upd: вроде разобрался. оказывается DMA пишет только в регион памяти AXISRAM. Вот пример работы https://github.com/Sergey1560/h7_sdmmc Это не готовая библиотека, а просто пример, чтобы проверить работает ли вообще :) В данном примере выключен режим работы карты HighSpeed. Код переключения в этот режим скопипастил (источники в sdio.h есть), на F4 работало вроде бы быстрее. Под h7 его надо переписать. В sdio.c объявлен здоровый массив buf_copy. Я код взял из готового проекта и там иногда от FATFs приходил запрос на запись не выровненного буфера, от чего DMA падал в hardfault. Я просто копировал в выровненный буфер и уже его читал/писал в карту. Сейчас правда у меня есть подозрения, что FATFs передавал не выровненный блок потому, что я его не выровненным передавал FATFs :) Вообщем обратите на это внимание. Я добавил вывод сообщений, если в функцию чтения/записи на SD передается не выровненный блок, в тестовой записи-чтении срабатываний не было. Тот пример, что в коде, пишется со скоростью около 1.2Мб/с, читается около 8. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 7 ноября, 2019 Опубликовано 7 ноября, 2019 · Жалоба а всего-то надо в FatFS обеспечить выравнивание внутренних данных в структуре и самой её. Я в своем проекте обеспечил так: typedef FATFSALIGN_BEGIN struct { BYTE fs_type; /* Filesystem type (0:N/A) */ BYTE pdrv; /* Physical drive number */ BYTE n_fats; /* Number of FATs (1 or 2) */ BYTE wflag; /* win[] flag (b0:dirty) */ BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */ WORD id; /* Volume mount ID */ WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ WORD csize; /* Cluster size [sectors] */ #if FF_MAX_SS != FF_MIN_SS WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */ #endif #if FF_USE_LFN WCHAR* lfnbuf; /* LFN working buffer */ #endif #if FF_FS_EXFAT BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */ #endif #if FF_FS_REENTRANT FF_SYNC_t sobj; /* Identifier of sync object */ #endif #if !FF_FS_READONLY DWORD last_clst; /* Last allocated cluster */ DWORD free_clst; /* Number of free clusters */ #endif #if FF_FS_RPATH DWORD cdir; /* Current directory start cluster (0:root) */ #if FF_FS_EXFAT DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */ DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */ DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */ #endif #endif DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */ DWORD fsize; /* Size of an FAT [sectors] */ DWORD volbase; /* Volume base sector */ DWORD fatbase; /* FAT base sector */ DWORD dirbase; /* Root directory base sector/cluster */ DWORD database; /* Data base sector */ DWORD winsect; /* Current sector appearing in the win[] */ FATFSALIGN_BEGIN BYTE win[FF_MAX_SS] FATFSALIGN_END; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ } FATFSALIGN_END FATFS; /* File object structure (FIL) */ typedef FATFSALIGN_BEGIN struct { FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */ BYTE flag; /* File status flags */ BYTE err; /* Abort flag (error code) */ FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */ DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */ DWORD sect; /* Sector number appearing in buf[] (0:invalid) */ #if !FF_FS_READONLY DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */ BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */ #endif #if FF_USE_FASTSEEK DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */ #endif #if !FF_FS_TINY FATFSALIGN_BEGIN BYTE buf[FF_MAX_SS] FATFSALIGN_END; /* File private data read/write window */ #endif } FATFSALIGN_END FIL; У меня с GCC так: #define FATFSALIGN_BEGIN __attribute__ ((aligned (32))) #define FATFSALIGN_END /* nothing */ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jeka 0 8 ноября, 2019 Опубликовано 8 ноября, 2019 · Жалоба Мне кажется смысла мало заморачиваться с выравниванием. Проще dma переключить на байтовый режим и всё. ибо 25мб/s не та скорость чтоб память ощутимо тормозить начала. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 8 ноября, 2019 Опубликовано 8 ноября, 2019 · Жалоба 8 hours ago, jeka said: Проще dma IDMA? У нас тут H7 фигурирует. Интересно, как Вы это сделаете. А с выравниванием еще из соображений DataCache лучше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться