|
STM32F4 DMA+SDIO, на основе Cube HAL |
|
|
|
Apr 13 2015, 15:05
|
Профессионал
    
Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863

|
ДА. Не первый раз удивляюсь, почему этот и другие глюки не были найдены раньше, хотя народу кто якобы уже много лет пользуется СТМ32Ф4 целая москва. То ли все делают ёлочные гирлянды и не пишут СД через дма, то ли я лошара.
Речь о записи на СД, как я понимаю. ДМА останавливается потому что в СДИО по непонятной причине возникает ошибка TXUNDERR (регистр STA), проверьте. Почему-то возникает она всегда на последних 10-и словах. Само ДМА не при чём.
А лечение такое:: пишите в DLEN (SDIO) на 16+ слов больше, чем в ДМА. А окончание записи придётся контролировать именно по завершению ДМА, прерывание от СДИО вообще запретите. То есть, несколько функций придётся подредактировать, сейчас не скажу каких точно.
Сообщение отредактировал IgorKossak - Apr 13 2015, 16:10
|
|
|
|
|
Apr 13 2015, 18:59
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(Dr.Alex @ Apr 13 2015, 19:49)  Тоже не помню чтобы были проблемы с чтением (ДМА), но может быть просто забыл. Тут не совсем понятно в чем проблема. Проект, действительно, не маленький - разбираться очень долго. Я бы отметил две причины, которые следует устранить: - бывают плохие карты (фэйковые, бракованные, изношенные и т.п.); Советую попробовать разные карты. Но раз поллингом работает, значит не оно. - бывают медленные карты (чтение может прерываться); Таймаут действует для ожидания данных. От момента передачи команды на чтение до появления признака готовности данных. Чтобы порция не дочитывалась стабильно, это что-то другое. В DMA есть битик DMA_SCR_PFCTRL, который можно (и нужно) установить только при обмене с SDIO. Вообще, флаги ошибок о многом могут рассказать.
|
|
|
|
|
Apr 13 2015, 21:12
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(Dr.Alex @ Apr 13 2015, 22:59)  HAL нигде его не ставит, и я кажыцо догадываюс почему. Еррата запрещает ставить соответствующий битик в самом SDIO, поэтому я думаю что и в ДМА его либо нельзя ставить, либо он просто не возымеет действия без такого же битика в SDIO. Errata описывает только SDIO HW flow control, но я его и не использую. На DMA это не влияет. Еще один нужный битик DMA_SCR_PBURST. У меня такой код (обработку ошибок и нестандартного поведения не привожу): CODE Перед считыванием данных я проверяю статус (CMD13) - если карта в TRAN, то буду считывать:
else if(cs.current_state == CARD_STATE_TRAN) { SDIO->DCTRL = 0; SDIO->DLEN = sdio_p_buf_size; DMA2_Stream6->CR = 0 | (4 << DMA_SCR_CHSEL) | (1 << DMA_SCR_MINC) | (2 << DMA_SCR_MSIZE) | (2 << DMA_SCR_PSIZE) | (1 << DMA_SCR_PBURST) | (1 << DMA_SCR_PFCTRL) | (0 << DMA_SCR_EN); DMA2_Stream6->FCR = 0 | (1 << DMA_SFCR_DMDIS) | (1 << DMA_SFCR_FTH); DMA2->HIFCR = (0x3D << 16); DMA2_Stream6->PAR = (DWORD)&SDIO->FIFO; DMA2_Stream6->M0AR = (DWORD)sdio_p_buf; DMA2_Stream6->NDTR = sdio_p_buf_size / sizeof(DWORD); sdio_fsm = SDIO_FSM_READ; SDIO_Send(CMD18_READ_MULTIPLE_BLOCK, (sdio_sect << ((card_type == CARD_SDHC)? 0 : 9)), EXPECT_SHORT_RESP); }
когда CMD18 выполнится запускаю прием данных так:
DMA2_Stream6->CR = 0 | (4 << DMA_SCR_CHSEL) | (1 << DMA_SCR_MINC) | (2 << DMA_SCR_MSIZE) | (2 << DMA_SCR_PSIZE) | (1 << DMA_SCR_PBURST) | (1 << DMA_SCR_PFCTRL) | (1 << DMA_SCR_EN); SDIO->DCTRL = 0 | (9 << SDIO_DCTRL_DBLOCKSIZE) | (1 << SDIO_DCTRL_DTDIR) | (1 << SDIO_DCTRL_DMAEN) | (1 << SDIO_DCTRL_DTEN);
по приходу прерывания DATAEND отправляю "горшочек не вари" для CMD18:
if(status & (1 << SDIO_DATAEND)) { SDIO->ICR = (1 << SDIO_DATAEND); SDIO->DCTRL = 0; sdio_fsm = SDIO_FSM_READ_STOP; SDIO_Send(CMD12_STOP_TRANSMISSION, NO_ARGUMENTS, EXPECT_SHORT_RESP); }
|
|
|
|
|
Apr 14 2015, 05:52
|
Знающий
   
Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594

|
Убрал вариант влияния FATfs. Оставил только эти функции: Код BSP_SD_Init(); char buffer[512]; BSP_SD_ReadBlocks((uint32_t *)buffer, 0, 512, 1); PFCTRL дейтсивтельно ни влияет. Просто NDTR начинается с 0xFFFF. И в данном случае так же не дочитывает 4 слова. По битам - проверяю, все то же самое, см. картинку. test
Эскизы прикрепленных изображений
|
|
|
|
|
Apr 14 2015, 06:35
|
Знающий
   
Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594

|
CIRC не влияет, я отключал А 32 битный захват данных и так включен (PSIZE=2, MSIZE = 2). В NDTR перед началом транзакции было 0x00000080, после - 4, то есть отправилось 124 слова, кстати я в буфере вижу, что так и есть, данные из карты идут!
раньше напарывался та такой косяк, что данные были не выровнены на 4 байта, но тут все четко.
|
|
|
|
|
Apr 14 2015, 08:37
|
Знающий
   
Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594

|
Цитата(Dr.Alex @ Apr 14 2015, 11:03)  Вы так и не посмотрели статус СДИО, наверняка там ошибки.. Посмотрел - ошибок нет во флагах. Скрин приложу чуть позже. Данные 512 байт как будто пролетают все.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|