реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> STM32F4Discovery + SDIO DMA, Не читает как надо
__inline__
сообщение Mar 16 2018, 11:06
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 257
Регистрация: 5-09-17
Пользователь №: 99 126



Здравствуйте!

Использую Дискавери на 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 начал работать?

Прикрепленное изображение

Прикрепленное изображение
Go to the top of the page
 
+Quote Post
Aaron
сообщение Mar 16 2018, 11:38
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 243
Регистрация: 5-10-06
Из: Зеленоград
Пользователь №: 21 007



посчитал. 112 байт не хватает в начале.
а они точно нулевые? м.б. там нечитаемые символы, отличные от 0x00 и 0xFF?
Go to the top of the page
 
+Quote Post
__inline__
сообщение Mar 16 2018, 13:14
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 257
Регистрация: 5-09-17
Пользователь №: 99 126



Чтение секторов через 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.gif
Go to the top of the page
 
+Quote Post
Obam
сообщение Mar 16 2018, 14:54
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Цитата
...указатели, которые не выровнены на границу двойного слова(4 байта)...

Двойное слово в Cortex-M4 это 8 байт. Не?


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
__inline__
сообщение Mar 16 2018, 15:30
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 257
Регистрация: 5-09-17
Пользователь №: 99 126



Цитата(Obam @ Mar 16 2018, 15:54) *
Двойное слово в Cortex-M4 это 8 байт. Не?


В традициях Старого Доброго ДОС-а считаю до сих пор словом - 2 байта (WORD)
4 байта - это уже двойное слово (DWORD) biggrin.gif

Впрочем мне известно, что в кортексиках слово - 4 байта rolleyes.gif


Пробовал отформатировать карту в винде на другой размер сектора - не даёт, только стандартный 512 байт.
Чем отформатировать можно карту с скеторами 2048 байт или больше?
Уменьшится ли время чтения?

В High speed mode есть смысл переводить чтоб быстрее читать с карты?

Сообщение отредактировал __inline__ - Mar 16 2018, 15:32
Go to the top of the page
 
+Quote Post
Obam
сообщение Mar 16 2018, 20:54
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Вот со времён "Старого Доброго ДОС-а" (; похоже, и не отличаете сектор (в SD 512 байт и никаких сусликов) от кластера (; (хоть 2кБ а хоть 32кБ)

Сообщение отредактировал Obam - Mar 16 2018, 20:54


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
__inline__
сообщение Mar 21 2018, 00:47
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 257
Регистрация: 5-09-17
Пользователь №: 99 126



Цитата(Obam @ Mar 16 2018, 21:54) *
Вот со времён "Старого Доброго ДОС-а" (; похоже, и не отличаете сектор (в SD 512 байт и никаких сусликов) от кластера (; (хоть 2кБ а хоть 32кБ)

Старый добрый ДОС мне много счастья подарил sm.gif
С сектором да, разобрался - 512 байт и не меняется.
Скачал SDFormatter, форматнул карточку им, произошло чудо - медленные карты теперь идут без заиканий.

Теперь вопрос: какой смысл использовать DMA для карт памяти через SDIO при использовании FatFs ?

Допустим надо считать порцию с файла. Вызывается чтение секторов, но ведь пока DMA не передаст все данные - прийдётся ждать! И сделать ничего не могу дальше, пока файл не считан. Оперативы - сколько в штатном STM32F407, так что спроецировать файловую систему в память не смогу (хотя в другом проекте такое успешно делал, но там памяти 64 МБ было).

Есть ли шанс реорганизовать работу Fatfs без ожидания завершения чтения секторов? Мне кажется, что нет.
Остаётся толко низкоуровневое чтение секторов одного за другим (причем блочное).

Пробовал переводить карту в High Speed Mode, тактовая частота 36 - 52 МГц ( менял делитель PLL_Q для USB, так как согласно эррате на STM32F407 Bypass там не работает) - выигрыша с медленными картами не дало.

Медленная карта - без обозначения класса скорости вообще на 2 ГБ.
С классом скорости 4 - работает отлично.

Я так понял, что разгон тактовой для карты памяти не имеет смысл, когда читаешь 1-секторный блок, так как задержки перед чтением у карты могут быть более длинными по времени.

Так ли это, как я тут изложил свои думалки?

Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 17th June 2024 - 21:41
Рейтинг@Mail.ru


Страница сгенерированна за 0.01418 секунд с 7
ELECTRONIX ©2004-2016