По умолчанию SDK в SDIO с FATFS В процессе, Нанахара SDK Существует несколько вопросыов:
(1) Не могу определить размер 2G Вот карта
(2) fatfs Не могу нормально повесить 2G Вот карта
(3) Измени основные частоты 240M посл, Проблемы с чтением и письмом карт
Поэтому я был прав насчет оригинала SDK в SDIO Привод и Fatfs Трансплантация была изменена, И решил несколько проблем.
(1) Описание проблемы, в SDK в wm_main. c Существуют следующие функции, Для настройки CPU На магистральной частоте, Высший балл 240M. Чтобы улучшить производительность, Я настроил его на это 240M А потом появилась она SD Проблемы с чтением и письмом на картах.
tls_sys_clk_set (CPU_CLK_240M) ;
(2) Причина вопросыа: SDIO в mmc В режиме, И используется SD Слова, настроенные на скорость по умолчанию, Максимальная выходная частота может быть только 20M. W801 в SDIO Да CPU Время идет, Получено через разделительную частоту, оказыва SDK По умолчанию количество разделительных частот составляет 1/6, После модификации основной частоты, SDIO И на магистральной частоте тоже 40M, Выше потолка невозможно читать и писать.
(3) Решение проблемы: Есть два варианта решения, Во-первых, изменить значение регистра деления частоты, Одна модификация SD Скорость карты, Я выбираю первое. SDIO Таблица значений для разбивки частоты показана ниже на диаграмме;
И когда cpu Основные частоты установлены 240M когд, Нужно изменить разделительную частоту 1/12 Не более 20M Верхний предел, Измененное положение изменяется в этой инициализированной конфигурационной функции ниже:
int wm_sdh_config (void)
{
tls_sys_clk sysclk;
tls_sys_clk_get (&sysclk) ;
SDIO_HOST- MMC_CARDSEL = 0xC0 | (sysclk. cpuclk / 2 - 1) ; //0xd3; //enable module, enable mmcclk
SDIO_HOST- MMC_CTL = 0xEB; //оказыва SDK в D3, Здесь мы должны достичь отметки в диапазоне 1/12, Нужно изменить EB, Когда меняется основная частота, Здесь также требуется соответствующая гарантия изменений 20M
SDIO_HOST- MMC_INT_MASK = 0x100; //unmask sdio data interrupt.
SDIO_HOST- MMC_CRCCTL = 0xC0; //
SDIO_HOST- MMC_TIMEOUTCNT = 0xff;
return 0;
}
(Измени результаты испытаний)
(1) SD Классификация карт:
SD Карточк на mmc Карта развивается, В соответствии с протоколом, Вместимость может быть разделена на несколько видов, Пот что W801 Максимальная поддержка sd2. 0 соглашен, Так что мы имеем дело со следующим 4 Карты класса:
1. mmc карточк
2. SD карточк: Протокол SD1. 0, Объёмный размер 0-2G
3. SDSC карточк: Протокол SD2. 0, Объёмный размер 0-2G
4. SDHC карточк: Протокол SD2. 0, Объёмный размер 2-32G
(2) различн SD Карта отличается от чтения и записи
2G Внутри SD Карта адресуется байтами, а 2G Карта выше указана только по блоку. Например, Когда адрес 0x01 когд, 2G Внутренняя карта определена как байт-адрес 0x01 Начать читать и писать, а 2G Карта, находящаяся за пределами этой страны, определена как начало чтения и записи с первого блока.
(3) SD Инициализация и идентификация карт
согласн SD2. 0 соглашен, Процесс идентификации указанных выше четырех категорий карт показан на диаграмме ниже, Я также написал китайскую версию карты наведения.
Как говорится, процесс инициализации, Главным образом cmd8 и acmd41 Назад OCR Значение регистра определяет четыре категории карт. Давайте посмотрим SDK Оригинальный код может быть найден, первоначальн SDK Да CMD8 Независимо от того, отвечает команда или нет, Если не прочтёшь response В то же время он был признан непосредственно провалом инициализации. И в то же время не верно OCR регистр CCS Судить по положению, В результате этого невозможно судить о Том, что является 2G объемный SDSC Карточка 2-32G в SDHC карточк, Для идентификации его в едином виде SDHC карточк, Как и верхняя сторона SD Это видно в разнице между чтением и письмом карт 2G Внутренняя карта, Это адресация по байтам 2G Внешняя карта, Для адресации, Потому что SDK Не делая различий в результате 2G Внутренняя карта успешно инициализирована, Но будут проблемы с чтением и письмом. Также могут возникнуть проблемы с двигателем fatfs Что-то не так.
int wm_sd_card_initialize (uint32_t *rca)
{
int ret = -1;
uint32_t respCmd[4];
int recnt = 5;
wm_sdh_config () ;
//======================================================
// set up
// Test: Init sequence, With response check
// CMD 0 Reset Card
// CMD 8 Get voltage (Only 2. 0 Card response to this)
// CMD55 Indicate Next Command are Application specific
// ACMD41 Get Voltage windows
// CMD 2 CID reg
// CMD 3 Get RCA.
//======================================================
begin:
wm_sdh_send_cmd (0, 0, 0x04) ; //Send CMD0
sm_sdh_wait_interrupt (0, -1) ;
delay_cnt (1000) ;
wm_sdh_send_cmd (8, 0x1AA, 0x44) ; //Send CMD8
sm_sdh_wait_interrupt (0, -1) ;
wm_sdh_get_response (respCmd, 2) ;
sh_dumpBuffer ("CMD8 respCmd", (char *) respCmd, 5) ;
if (respCmd[0] ! = 0x1AA || (respCmd[1] & 0xFF) ! = 8)
{
TEST_DEBUG ("CMD8 Error\n") ;
printf ("CMD8 Error\n") ;
if (recnt--)
goto begin;
goto end; //Здесь 5 Вторичное считывание cmd8 посл response Когда не получилось, Перепрыгнет прямо к провалу инициализации, Не делая различий
}
while (1)
{
wm_sdh_send_cmd (55, 0, 0x44) ; //Send CMD55
sm_sdh_wait_interrupt (0, -1) ;
wm_sdh_get_response (respCmd, 2) ;
sh_dumpBuffer ("CMD55 respCmd", (char *) respCmd, 5) ;
if ( (respCmd[1] & 0xFF) ! = 55)
{
printf ("respCmd Error\n") ;
goto end;
}
wm_sdh_send_cmd (41, 0xC0100000, 0x44) ; //Send ACMD41
sm_sdh_wait_interrupt (0, -1) ;
sm_sdh_wait_interrupt (3, 1000) ; //поскольк sd Правила, Acmd41 Назад crc Навсегда 11111, А именно, игнорировать crc; Здесь crc Ошибки следует игнорировать.
wm_sdh_get_response (respCmd, 2) ;
sh_dumpBuffer ("ACMD41 respCmd", (char *) respCmd, 5) ;
if ( (respCmd[1] & 0xFF) ! = 0x3F) //sd Спецификация определяется как фиксированная 0x3F, Так что crc ошибк
{
printf ("respCmd Error - 2\n") ;
goto end;
}
if (respCmd[0] 31 & 0x1)
{
TEST_DEBUG ("card is ready\n") ; //Нет CCS Судить по положению, Их не различить SDSC с SDHC
printf ("card is ready\n") ;
break;
}
}
wm_sdh_send_cmd (2, 0, 0x54) ; //Send CMD2
sm_sdh_wait_interrupt (0, -1) ;
sm_sdh_wait_interrupt (3, 1000) ;
wm_sdh_get_response (respCmd, 4) ;
sh_dumpBuffer ("CMD2 respCmd", (char *) respCmd, 16) ;
if ( (respCmd[3] 24 & 0xFF) ! = 0x3F) //sd Спецификация определяется как фиксированная 0x3F, Так что crc ошибк
{
printf ("respCmd Error - 3\n") ;
goto end;
}
wm_sdh_send_cmd (3, 0, 0x44) ; //Send CMD3
sm_sdh_wait_interrupt (0, -1) ;
wm_sdh_get_response (respCmd, 2) ;
sh_dumpBuffer ("CMD3 respCmd", (char *) respCmd, 5) ;
if ( (respCmd[1] & 0xFF) ! = 3)
{
printf ("respCmd Error - 4\n") ;
goto end;
}
*rca = respCmd[0] 16;
TEST_DEBUG ("RCA = %x\n", *rca) ;
ret = 0;
end:
return ret;
}
(1) модификац wm_sdio_host. h, В начале файла SD_CardInfo_t Один из них был определен внутри структурного тела CardType Переменные используются для определения типа карт, Осталось только добавить 3 Макросы определяют тип карты. Пот что mmc Карты не часто используются, Поэтому я не добавлял mmc Распознавание карт.
#define CardType_SD 0x01
#define CardType_SDSC 0x02
#define CardType_SDHC 0x03
//Структура уже определена в главном файле, Я вижу начало SDK Одно уже определено CardType Переменные используются для определения типа карт
typedef struct
{
long long CardCapacity;
u32 CardBlockSize;
u16 RCA;
u8 CardType;
} SD_CardInfo_t;
(2) модификац wm_sdio_host. c из wm_sd_card_initialize функц, Поправка:
int wm_sd_card_initialize (uint32_t *rca)
{
int ret = -1;
uint32_t respCmd[4];
int recnt = 5;
u8 temp_type = 0x00;
wm_sdh_config () ;
//======================================================
// set up
// Test: Init sequence, With response check
// CMD 0 Reset Card
// CMD 8 Get voltage (Only 2. 0 Card response to this)
// CMD55 Indicate Next Command are Application specific
// ACMD41 Get Voltage windows
// CMD 2 CID reg
// CMD 3 Get RCA.
//======================================================
begin:
wm_sdh_send_cmd (0, 0, 0x04) ; //Send CMD0
sm_sdh_wait_interrupt (0, -1) ;
delay_cnt (1000) ;
wm_sdh_send_cmd (8, 0x1AA, 0x44) ; //Send CMD8
sm_sdh_wait_interrupt (0, -1) ;
wm_sdh_get_response (respCmd, 2) ;
sh_dumpBuffer ("CMD8 respCmd", (char *) respCmd, 5) ;
if (respCmd[0] ! = 0x1AA || (respCmd[1] & 0xFF) ! = 8)
{
TEST_DEBUG ("CMD8 Error\n") ;
if (recnt--)
goto begin;
temp_type =0x01; // Неполученный ответ говорит о Том, что SD1. 0 карточк
}
while (1)
{
wm_sdh_send_cmd (55, 0, 0x44) ; //Send CMD55
sm_sdh_wait_interrupt (0, -1) ;
wm_sdh_get_response (respCmd, 2) ;
sh_dumpBuffer ("CMD55 respCmd", (char *) respCmd, 5) ;
if ( (respCmd[1] & 0xFF) ! = 55)
goto end;
wm_sdh_send_cmd (41, 0xC0100000, 0x44) ; //Send ACMD41
sm_sdh_wait_interrupt (0, -1) ;
sm_sdh_wait_interrupt (3, 1000) ; //поскольк sd Правила, Acmd41 Назад crc Навсегда 11111, А именно, игнорировать crc; Здесь crc Ошибки следует игнорировать.
wm_sdh_get_response (respCmd, 2) ;
sh_dumpBuffer ("ACMD41 respCmd", (char *) respCmd, 5) ;
if ( (respCmd[1] & 0xFF) ! = 0x3F) //sd Спецификация определяется как фиксированная 0x3F, Так что crc ошибк
goto end;
if (respCmd[0] 31 & 0x1)
{
TEST_DEBUG ("card is ready\n") ;
// согласн CCS Бит определяет тип карты
if ( (respCmd[0] 30 == 0x3) && (temp_type == 0x0) )
{
SDCardInfo. CardType = CardType_SDHC;
printf ("\nCardtype[%d]: SDHC\n", SDCardInfo. CardType) ;
}
else if ( (respCmd[0] 30 == 0x2) && (temp_type == 0x0) )
{
SDCardInfo. CardType = CardType_SDSC;
printf ("\nCardtype[%d]: SDSC\n", SDCardInfo. CardType) ;
}
else if (temp_type == 0x1)
{
SDCardInfo. CardType = CardType_SD;
printf ("\nCardtype[%d]: SD\n", SDCardInfo. CardType) ;
}
break;
}
}
wm_sdh_send_cmd (2, 0, 0x54) ; //Send CMD2
sm_sdh_wait_interrupt (0, -1) ;
sm_sdh_wait_interrupt (3, 1000) ;
wm_sdh_get_response (respCmd, 4) ;
sh_dumpBuffer ("CMD2 respCmd", (char *) respCmd, 16) ;
if ( (respCmd[3] 24 & 0xFF) ! = 0x3F) //sd Спецификация определяется как фиксированная 0x3F, Так что crc ошибк
goto end;
wm_sdh_send_cmd (3, 0, 0x44) ; //Send CMD3
sm_sdh_wait_interrupt (0, -1) ;
wm_sdh_get_response (respCmd, 2) ;
sh_dumpBuffer ("CMD3 respCmd", (char *) respCmd, 5) ;
if ( (respCmd[1] & 0xFF) ! = 3)
goto end;
*rca = respCmd[0] 16;
TEST_DEBUG ("RCA = %x\n", *rca) ;
ret = 0;
end:
return ret;
}
(3) для wm_sdio_host_demo. c Модификация, эт demo Разные карты не используются для разных операций, Здесь мы уточняем тип карты, Позволяет всем картам читать и писать с помощью блоков. Обе функции чтения и записи должны быть изменены, Покажи sdh_card_wr_sb Модификация функции, Еще одна функциональная аналогия.
static int sdh_card_wr_sb (uint32_t rca, uint8_t bus_width, const uint32_t tsize)
{
int ret = -1;
int i = 0;
char* buf = NULL;
char* bufR = NULL;
buf = tls_mem_alloc (512) ;
if (buf == NULL)
goto end;
bufR = tls_mem_alloc (512) ;
if (bufR == NULL)
goto end;
random_get_bytes (buf, 512) ;
TEST_DEBUG ("bus width %s\n", bus_width == 0 ? "1bit" : "4bits") ;
ret = wm_sd_card_set_bus_width (rca, bus_width) ;
if (ret)
goto end;
ret = wm_sd_card_set_blocklen (0x200) ; //512
if (ret)
goto end;
for (i=0; i (tsize/512) ; i++)
{
//Узнать, правда ли это SDHC карточк, А если нет, то это адресация, В противном случае это байт адресации, Нужно умножить 512
if (SDCardInfo. CardType == CardType_SDHC)
{
ret = wm_sd_card_block_write (rca, i, buf) ;
}
else if ( (SDCardInfo. CardType == CardType_SDSC) || (SDCardInfo. CardType == CardType_SD) )
{
ret = wm_sd_card_block_write (rca, i * 512, buf) ;
}
if (ret)
goto end;
}
ret = wm_sd_card_query_status (rca, NULL) ;
if (ret)
goto end;
for (i=0; i (tsize/512) ; i++)
{
if (SDCardInfo. CardType == CardType_SDHC)
{
ret = wm_sd_card_block_read (rca, i, bufR) ;
}
else if ( (SDCardInfo. CardType == CardType_SDSC) || (SDCardInfo. CardType == CardType_SD) )
{
ret = wm_sd_card_block_read (rca, i * 512, bufR) ;
}
if (ret)
goto end;
if (memcmp (buf, bufR, 512) )
{
ret = -2;
goto end;
}
}
ret = 0;
end:
if (buf)
{
tls_mem_free (buf) ;
}
if (bufR)
{
tls_mem_free (bufR) ;
}
TEST_DEBUG ("ret %d\n", ret) ;
return ret;
}
(4) fatfs в diskio. c Модификация, оригинальный fatfs Функция считывания и записи файловой системы также не делает различий между блочным чтением и байтовым письмом, Я не смогу его повесить 2G Нужна правильная карта disk_write и disk_write Функция состоит из следующих модификаций:
static int MMC_disk_write ( BYTE *buff, LBA_t sector, UINT count)
{
int ret, i;
int buflen = BLOCK_SIZE*count;
BYTE *wrbuff = buff;
if ( ( (u32) buff) &0x3)
{
wrbuff = tls_mem_alloc (buflen) ;
if (wrbuff == NULL) /*non aligned 4*/
{
return -1;
}
memcpy (wrbuff, buff, buflen) ;
}
for ( i = 0; i TRY_COUNT; i++ )
{
if (count == 1)
{
//Узнать, правда ли это SDHC карточк, А если нет, то это адресация, В противном случае это байт адресации, Нужно умножить 512
if (SDCardInfo. CardType == CardType_SDHC)
{
ret = wm_sd_card_block_write (fs_rca, sector, (char *) wrbuff) ;
}
else if ( (SDCardInfo. CardType == CardType_SDSC) || (SDCardInfo. CardType == CardType_SD) )
{
ret = wm_sd_card_block_write (fs_rca, sector * BLOCK_SIZE, (char *) wrbuff) ;
}
}
else if (count 1)
{
if (SDCardInfo. CardType == CardType_SDHC)
{
ret = wm_sd_card_blocks_write (fs_rca, sector, (char *) wrbuff, buflen) ;
}
else if ( (SDCardInfo. CardType == CardType_SDSC) || (SDCardInfo. CardType == CardType_SD) )
{
for (int j = 0; j count; j++)
{
ret = wm_sd_card_blocks_write (fs_rca, sector + j* BLOCK_SIZE, (char *) wrbuff, BLOCK_SIZE) ;
}
}
}
if ( ret == 0 )
{
break;
}
}
if (wrbuff ! = buff)
{
tls_mem_free (wrbuff) ;
}
return ret;
}
static int MMC_disk_read ( BYTE *buff, LBA_t sector, UINT count)
{
int ret, i;
int buflen = BLOCK_SIZE*count;
BYTE *rdbuff = buff;
if ( ( (u32) buff) &0x3) /*non aligned 4*/
{
rdbuff = tls_mem_alloc (buflen) ;
if (rdbuff == NULL)
{
return -1;
}
}
for ( i=0; i TRY_COUNT; i++ )
{
if (count == 1)
{
//Узнать, правда ли это SDHC карточк, А если нет, то это адресация, В противном случае это байт адресации, Нужно умножить 512
if (SDCardInfo. CardType == CardType_SDHC)
{
ret = wm_sd_card_block_read (fs_rca, sector, (char *) rdbuff) ;
}
else if ( (SDCardInfo. CardType == CardType_SDSC) || (SDCardInfo. CardType == CardType_SD) )
{
ret = wm_sd_card_block_read (fs_rca, sector * BLOCK_SIZE, (char *) rdbuff) ;
}
}
else if (count 1)
{
if (SDCardInfo. CardType == CardType_SDHC)
{
ret = wm_sd_card_blocks_read (fs_rca, sector, (char *) rdbuff, buflen) ;
}
else if ( (SDCardInfo. CardType == CardType_SDSC) || (SDCardInfo. CardType == CardType_SD) )
{
for (int j = 0; j count; j++)
{
ret = wm_sd_card_blocks_read (fs_rca, sector + j* BLOCK_SIZE, (char *) rdbuff, BLOCK_SIZE) ;
}
}
}
if ( ret == 0 )
break;
}
if (rdbuff ! = buff)
{
if (ret == 0)
{
memcpy (buff, rdbuff, buflen) ;
}
tls_mem_free (rdbuff) ;
}
return ret;
}
(1) Используется SD карточк: У меня сейчас только два SD карточк, Для чего 4G в SDHC карточк, Еще Один для 128MB в SD карточк, На рисунке ниже показано.
(2) Возвращайся к явным результатам: На рисунке ниже показано, Оба могут читать, писать и вешать Fatfs
У меня больше нет проблем с личным тестом, Если есть что-нибудь bug Слова могут общаться в комментариях
ссылк: https: //pan. baidu. com/s/1YFtnyO1YzOUhDGhLEiWuXw
Код извлечения: e4fx
Модифицированный код, Энергия 739265828 Документы? Не вижу никаких изменений.
@lutherluo Эта группа переполнена, я 5 групп, Дайте нам связь с облаком в 100 градусов
ссылк: https: //pan. baidu. com/s/1YFtnyO1YzOUhDGhLEiWuXw
Код извлечения: e4fx
Отличная статья! Вот на что нужно обратить внимание, CPU Основная частота делится на 2 Еще раз на частоте, То есть 240MHZ/2/6 = 20MHZ.
Если хочешь предельную скорость:
CPU Если настройка будет установлена 80MHz, MMC_CTL Устанавливаю 0xC3
CPU Если настройка будет установлена 240MHz, MMC_CTL Устанавливаю 0xD3
Я проверю SD Чтение и запись карт в норме.
@SK2024 OK, Got it.
хорош! Возьми!
Когда я читаю карты малой емкости, CMD16 Установить размер блока и провалиться, Интересно, почему