repstosw 18 16 марта, 2018 Опубликовано 16 марта, 2018 · Жалоба Здравствуйте! Использую Дискавери на STM32F407 + карту SD Micro 4 GB на чтение. Чтение через поллинг (Polling) идет отлично, даже файлы верно читаются с помощью FatFs. Но через DMA не удаётся нормально работать. Помотрел как читается нулевой(первый сектор) карты в 2 случаях: Polling и DMA. Фрагменты кода (прерывания включил, карту проинитил, данные выровнял на 16 байт) : u8 buff[512] __attribute__((aligned (16))); void SDIO_IRQHandler(void) { SD_ProcessIRQSrc(); } void SD_SDIO_DMA_IRQHANDLER(void) { SD_ProcessDMAIRQ(); } void SD_NVIC_Configuration(void) { // SDIO Interrupt ENABLE NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // DMA2 STREAMx Interrupt ENABLE NVIC_InitStructure.NVIC_IRQChannel = SD_SDIO_DMA_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_Init(&NVIC_InitStructure); } SD_Init(); SD_NVIC_Configuration(); __enable_irq(); SD_ReadBlock(buff,0<<9,512); OLED_ON(); #define COL 255 for(u32 i=0;i<512;i++)OLED_Char(i%20,i/20,buff[i],COL|(COL<<8)|(COL<<16)); while(1); Фотки прикладываю. Вывод содержимого нулевого сектора на дисплей. Первая картинка - перез Polling - там всё OK. Вторая через DMA - первые байты (от трети до половины всего экрана) - нулевые. Куда копать, чтобы DMA нормально на чтение с SDIO начал работать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aaron 1 16 марта, 2018 Опубликовано 16 марта, 2018 · Жалоба посчитал. 112 байт не хватает в начале. а они точно нулевые? м.б. там нечитаемые символы, отличные от 0x00 и 0xFF? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 16 марта, 2018 Опубликовано 16 марта, 2018 · Жалоба Чтение секторов через DMA заработало. После чтения надо ждать завершения ДМА: while(DMA2_Stream3->CR&DMA_SxCR_EN); DMA2->LIFCR=DMA_IT_TCIF3&0x0F7D0F7D; DMA2_Stream3->CR|=DMA_SxCR_EN; То что выше, работает и без разрешения прерываний. С разрешёнными прерываниям работает стандартный кусок: SDError = SD_WaitReadOperation(); while( SD_GetStatus() != SD_TRANSFER_OK ); Сектор читается корректно, но FatFs не работает! При открытии файла - ошибка 4 - FR_NO_FILE, /* (4) Could not find the file */ Без DMA работает. В чём подвох работы FatFs с DMA ? WORD_ACCESS стоит 0. Всё разобрался с FatFs! Проверил, что при чтении из файла библиотека суёт указатели, которые не выровнены на границу двойного слова(4 байта). Решил путём промежуточного буфера, выровненного на 16 байт для DMA: /*-----------------------------------------------------------------------*/ /* Read Sector(s) */ /*-----------------------------------------------------------------------*/ #define BLOCK_SIZE 512 unsigned char abuf[512] __attribute__((aligned (16))); //выровненный на 16 байт буфер extern void align_error(void); //для отладки DRESULT disk_read ( BYTE pdrv, /* Physical drive nmuber (0..) */ BYTE *buff, /* Data buffer to store read data */ DWORD sector, /* Sector address (LBA) */ BYTE count /* Number of sectors to read (1..128) */ ) { DRESULT dresult = RES_OK; SD_Error SDError; if( pdrv == SD_DISK_PDRV ) { if((((unsigned long int)buff)&0x00000003)!=0)align_error(); for(int i=0;i<count;i++) //карта поддерживает только одно-блочную команду чтения, мультиблоки не работают :( { SDError = SD_ReadBlock(abuf,(sector+i)*BLOCK_SIZE, BLOCK_SIZE); //читаем в выровненный буфер DMA #ifdef SD_DMA_MODE SDError = SD_WaitReadOperation(); #endif while( SD_GetStatus() != SD_TRANSFER_OK ); if(SDError != SD_OK)dresult = RES_ERROR; memcpy(buff+(i<<9),abuf,512); //копируем в выходной буфер со смещением } return dresult; } return RES_PARERR; } :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 16 марта, 2018 Опубликовано 16 марта, 2018 · Жалоба ...указатели, которые не выровнены на границу двойного слова(4 байта)... Двойное слово в Cortex-M4 это 8 байт. Не? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 16 марта, 2018 Опубликовано 16 марта, 2018 (изменено) · Жалоба Двойное слово в Cortex-M4 это 8 байт. Не? В традициях Старого Доброго ДОС-а считаю до сих пор словом - 2 байта (WORD) 4 байта - это уже двойное слово (DWORD) Впрочем мне известно, что в кортексиках слово - 4 байта :rolleyes: Пробовал отформатировать карту в винде на другой размер сектора - не даёт, только стандартный 512 байт. Чем отформатировать можно карту с скеторами 2048 байт или больше? Уменьшится ли время чтения? В High speed mode есть смысл переводить чтоб быстрее читать с карты? Изменено 16 марта, 2018 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 16 марта, 2018 Опубликовано 16 марта, 2018 (изменено) · Жалоба Вот со времён "Старого Доброго ДОС-а" (; похоже, и не отличаете сектор (в SD 512 байт и никаких сусликов) от кластера (; (хоть 2кБ а хоть 32кБ) Изменено 16 марта, 2018 пользователем Obam Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 21 марта, 2018 Опубликовано 21 марта, 2018 · Жалоба Вот со времён "Старого Доброго ДОС-а" (; похоже, и не отличаете сектор (в SD 512 байт и никаких сусликов) от кластера (; (хоть 2кБ а хоть 32кБ) Старый добрый ДОС мне много счастья подарил :) С сектором да, разобрался - 512 байт и не меняется. Скачал SDFormatter, форматнул карточку им, произошло чудо - медленные карты теперь идут без заиканий. Теперь вопрос: какой смысл использовать DMA для карт памяти через SDIO при использовании FatFs ? Допустим надо считать порцию с файла. Вызывается чтение секторов, но ведь пока DMA не передаст все данные - прийдётся ждать! И сделать ничего не могу дальше, пока файл не считан. Оперативы - сколько в штатном STM32F407, так что спроецировать файловую систему в память не смогу (хотя в другом проекте такое успешно делал, но там памяти 64 МБ было). Есть ли шанс реорганизовать работу Fatfs без ожидания завершения чтения секторов? Мне кажется, что нет. Остаётся толко низкоуровневое чтение секторов одного за другим (причем блочное). Пробовал переводить карту в High Speed Mode, тактовая частота 36 - 52 МГц ( менял делитель PLL_Q для USB, так как согласно эррате на STM32F407 Bypass там не работает) - выигрыша с медленными картами не дало. Медленная карта - без обозначения класса скорости вообще на 2 ГБ. С классом скорости 4 - работает отлично. Я так понял, что разгон тактовой для карты памяти не имеет смысл, когда читаешь 1-секторный блок, так как задержки перед чтением у карты могут быть более длинными по времени. Так ли это, как я тут изложил свои думалки? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться