Перейти к содержанию
    

Джентельмены, нет ли у кого работающего примера работы SD+FatFs через DMA на L4? Буду очень признателен.

 

Пробовали пример от STM32L476G_EVAL, но там только в поллинге.

Попробовали пределать под DMA, но пока не работает, читает только первый килобайт а потом ошибка, с записью вообще пока не работает.

В поллинге нет проблем, но он работает только при выключенных прерываниях (оно есть в коде на еваборду).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть для не "L" а для "F"

 

https://188.134.5.254/browser/trunk

 

Файл sdcard.c и dskio.c

 

ПРограммирование адреса периферии не тут, надюсь поможет. Это как пониямете из работающего проекта..

 

	/* DMA2	Stream6	Channel 4 */ 
const uint_fast8_t ch = 4;

DMA2_Stream6->M0AR = addr;
DMA2_Stream6->NDTR = (DMA2_Stream6->NDTR & ~ DMA_SxNDT) |
	(1 * DMA_SxNDT_0);		// Особый случай - регистр игнорируется. В примерах от ST пишется 1

if (direction == 0)
{
	// Read from SD CARD
	//DMA2_Stream6->NDTR = (DMA2_Stream6->NDTR & ~ DMA_SxNDT) |
	//	(length0 * count / 4 * DMA_SxNDT_0);		// Особый случай - регистр игнорируется. В примерах от ST пишется 1

	DMA2_Stream6->FCR =
		1 * DMA_SxFCR_DMDIS |	// use FIFO mode
		3 * DMA_SxFCR_FTH_0 |	// 11: full FIFO
		0;

	DMA2_Stream6->CR =
		0 * DMA_SxCR_DIR_0 |	// 00: Peripheral-to-memory
		ch * DMA_SxCR_CHSEL_0 | // канал
		1 * DMA_SxCR_PFCTRL |	// 1: The peripheral is the flow controller (required for SDIO/SDMMC connected DMA)
		1 * DMA_SxCR_MBURST_0 |	// 01: INCR4 (incremental burst of 4 beats)
		1 * DMA_SxCR_PBURST_0 |	// 01: INCR4 (incremental burst of 4 beats)
		//0 * DMA_SxCR_DIR_0 |	// 00: Peripheral-to-memory
		1 * DMA_SxCR_MINC |		//инкремент памяти
		2 * DMA_SxCR_MSIZE_0 | //длина в памяти - 32 bit
		2 * DMA_SxCR_PSIZE_0 | //длина в DR - 32 bit
		//1 * DMA_SxCR_CIRC | //циклический режим не требуется при DBM
		2 * DMA_SxCR_PL_0 |		// Priority level - High
		0 * DMA_SxCR_CT |	// M0AR selected
		//0 * DMA_SxCR_DBM |	 // double buffer mode seelcted
		0;
}
else
{
	// Write to SD CARD

	//DMA2_Stream6->NDTR = (DMA2_Stream6->NDTR & ~ DMA_SxNDT) |
	//	(length0 * count * DMA_SxNDT_0);		// Особый случай - регистр игнорируется. В примерах от ST пишется 1

	DMA2_Stream6->FCR =
		1 * DMA_SxFCR_DMDIS |	// use FIFO mode
		1 * DMA_SxFCR_FTH_0 |	// 01: 1/2 full FIFO (changed from read !)
		0;

	DMA2_Stream6->CR =
		1 * DMA_SxCR_DIR_0 |	// 01: Memory-to-peripherial
		ch * DMA_SxCR_CHSEL_0 | // канал
		1 * DMA_SxCR_PFCTRL |	// 1: The peripheral is the flow controller (required for SDIO/SDMMC connected DMA)
		0 * DMA_SxCR_MBURST_0 |	// 00: single transfer (changed from read !)
		1 * DMA_SxCR_PBURST_0 |	// 01: INCR4 (incremental burst of 4 beats)
		//0 * DMA_SxCR_DIR_0 |	// 00: Peripheral-to-memory
		1 * DMA_SxCR_MINC |		//инкремент памяти
		0 * DMA_SxCR_MSIZE_0 | //длина в памяти - 8 bit (changed from read !)
		2 * DMA_SxCR_PSIZE_0 | //длина в DR - 32 bit
		//1 * DMA_SxCR_CIRC | //циклический режим не требуется при DBM
		2 * DMA_SxCR_PL_0 |		// Priority level - High
		0 * DMA_SxCR_CT |	// M0AR selected
		//0 * DMA_SxCR_DBM |	 // double buffer mode seelcted
		0;
}

DMA2->HIFCR = (DMA_HIFCR_CTCIF6 /*| DMA_HIFCR_CTEIF6 */);	// Clear TC interrupt flag соответствующий stream
//DMA2_Stream6->CR |= (DMA_SxCR_TCIE /* | DMA_SxCR_TEIE */);	// разрешить прерывания от DMA по TC и TE

DMA2_Stream6->CR |= DMA_SxCR_EN;

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Трудно там разобраться, тем более что L4 и F4 немного отличаются (напрмиер каналы DMA).

Может есть у кого именно для L4?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, у L проще... так попробовали бы по аналогии... Главные вещи - едигичка в регистре длины, размеры данных у источника-получателя.

Изменено пользователем Genadi Zawidowski

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Genadi Zawidowski, а зачем разные размеры источника и приемника при записи? Вот тут:

 

0 * DMA_SxCR_MSIZE_0 | //длина в памяти - 8 bit (changed from read !)

2 * DMA_SxCR_PSIZE_0 | //длина в DR - 32 bit

 

У меня везде стоит по 32бита. Кстати в регистр длины в принципе можно писать что угодно, после начала работы DMA он сбросится в 0xFFFF об этом прямо указано в доках.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Там было много непонятного... много казалось бы разумного отсеялось.. осталось то что совпало с примером от ST. Когда оно заработало, я не трогал... Вохможно тут и 32 бита можно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Там было много непонятного...

По этой причине я написал по докам с нуля. Хотя поковыряться пришлось тоже - забыл вначале Hardware Flow Control включить :).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если посмотришь, у меня только инициализация DMA стянута. Остальное тоже только по докам. Сперва вообще запускал на Ренесансе по усеченной документации... Потом уже на STM32F.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Genadi Zawidowski, а зачем разные размеры источника и приемника при записи? Вот тут:

 

0 * DMA_SxCR_MSIZE_0 | //длина в памяти - 8 bit (changed from read !)

2 * DMA_SxCR_PSIZE_0 | //длина в DR - 32 bit

 

У меня везде стоит по 32бита. Кстати в регистр длины в принципе можно писать что угодно, после начала работы DMA он сбросится в 0xFFFF об этом прямо указано в доках.

А, тут не всё так просто. Вот, почитайте эту тему, я там походил по граблям...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дело не только и не столько в burst, сколько в пословном доступе к невыровненным данным. Этого, думаю, и L4 не любит.

(FatFs при определённых условиях вызывает функцию записи блока с адресом буфера, не кратным 4).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А, тут не всё так просто. Вот, почитайте эту тему, я там походил по граблям...

У меня такого не может произойти - доступ всегда по выровненным адресам.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Используя у себя FatFs R0.12b, дорабатывал напильником выравнивание члена buf структуры FIL и win в структуре FATFS - перестали идти невыровненные обращения. Мне это требовалось еще и для нормальной работы DATA CACHE процессоров, вернее чтобы FatFs работал при наличии DCache. Все это есть в проекте.

Изменено пользователем Genadi Zawidowski

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Выравнивание buf структуры FIL не помогает, всё равно FatFs при определённых условиях передаёт в функцию записи блока невыровненный указатель. Почитайте по моей ссылке. Но у вас доступ DMA к памяти побайтный (0 * DMA_SxCR_MSIZE_0), поэтому не страшно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...