NXP i.MX7D
контроллер SD/MMC
На эволюхе
PICO-PI-GL порт SD используется в двух местах:
доступ к eMMC флеш-памяти и ВайФай модему.
Приоритет для публикации кода на сайте, отдан микросхемке eMMC.
@ Отдать ножки флешке
MOV32 R0, IOMUXC_BASE
MOV R1, 0 @ Режим ALT0 для uSDHC3
STR R1, [R0, SW_MUX_CTL_PAD_SD3_CLK] @ SD3 CLK
STR R1, [R0, SW_MUX_CTL_PAD_SD3_CMD] @ SD3 CMD
STR R1, [R0, SW_MUX_CTL_PAD_SD3_DATA0] @ SD3 DATA0
STR R1, [R0, SW_MUX_CTL_PAD_SD3_DATA1] @ SD3 DATA1
STR R1, [R0, SW_MUX_CTL_PAD_SD3_DATA2] @ SD3 DATA2
STR R1, [R0, SW_MUX_CTL_PAD_SD3_DATA3] @ SD3 DATA3
STR R1, [R0, SW_MUX_CTL_PAD_SD3_DATA4] @ SD3 DATA4
STR R1, [R0, SW_MUX_CTL_PAD_SD3_DATA5] @ SD3 DATA5
STR R1, [R0, SW_MUX_CTL_PAD_SD3_DATA6] @ SD3 DATA6
STR R1, [R0, SW_MUX_CTL_PAD_SD3_DATA7] @ SD3 DATA7
MOV R1, 1 @ Режим ALT1 для SD3_CD_B
STR R1, [R0, SW_MUX_CTL_PAD_GPIO1_IO14] @ SD3 CD_B
@ Настроить параметры ножек
@ Pull Disabled, Hysteresis Enabled, Slow Slew Rate, Drive Strength ~40 ом
MOV R1, 0 << 5 + 0 << 4 + 1 << 3 + 1 << 2 + 3 << 0
STR R1, [R0, SW_PAD_CTL_PAD_SD3_CLK] @ SD3 CLK
STR R1, [R0, SW_PAD_CTL_PAD_SD3_CMD] @ SD3 CMD
STR R1, [R0, SW_PAD_CTL_PAD_SD3_DATA0] @ SD3 DATA0
STR R1, [R0, SW_PAD_CTL_PAD_SD3_DATA1] @ SD3 DATA1
STR R1, [R0, SW_PAD_CTL_PAD_SD3_DATA2] @ SD3 DATA2
STR R1, [R0, SW_PAD_CTL_PAD_SD3_DATA3] @ SD3 DATA3
STR R1, [R0, SW_PAD_CTL_PAD_SD3_DATA4] @ SD3 DATA4
STR R1, [R0, SW_PAD_CTL_PAD_SD3_DATA5] @ SD3 DATA5
STR R1, [R0, SW_PAD_CTL_PAD_SD3_DATA6] @ SD3 DATA6
STR R1, [R0, SW_PAD_CTL_PAD_SD3_DATA7] @ SD3 DATA7
STR R1, [R0, SW_PAD_CTL_PAD_GPIO1_IO14] @ SD3 CD_B
@ Определить источник тактовых импульсов и настроить делитель
MOV32 R0, CCM_BASE + TARGET_ROOT88 @ uSDHC3_CLK_ROOT
MOV32 R1, 1 << ROOT_ENABLE + 1 << MUX + (1-1) << PRE_PODF + (1-1) << POST_PODF
STR R1, [R0] @ Источник: SYS_PLL_PFD0, оверклокерская частота 392МГц
@ Частота 392МГц в 2 раза выше допустимой
@ Это пригодится нам при тестовом разгоне
@ Хотя частоты модулей лучше не превышать. Сгорит!
@ И в этом месте верните делитель на 2: (2-1) << PRE_PODF
@ Что бы получить штатные 196 МГц
@ Затактировать модуль
MOV32 R0, CCM_BASE + CCGR110 @ uSDHC3 clock gate
MOV R1, 0x00003333
STR R1, [R0]
@ Базовый адрес модуля
MOV32 R0, uSDHC3_BASE
@ Так как загрузчик до вас уже поковырялся в модуле
@ Выискивая прошивку на флешке
@ То модуль лучше полностью сбросить и настроить заново
MOV R1, 1 << SD_RSTA
STR R1, [R0, SYS_CTRL]
@ Дождаться завершения сброса
1:
LDR R1, [R0, SYS_CTRL]
TST R1, 1 << SD_RSTA @ Должен стать = 0
BNE 1b
@ Установить начальную частоту SDIO
@ Если входная @196 МГц / 64 / 8 = 382 килогерца
MOV32 R1, 1 << IPP_RST_N + 14 << DTOCV + 0x20 << SDCLKFS + (8-1) << DVS + 0x0F
STR R1, [R0, SYS_CTRL]
@ Дождаться стабилизации частоты
1:
LDR R1, [R0, PRES_STATE]
TST R1, 1 << SDSTB
BEQ 1b
@ Настроить DMA
LDR R1, [R0, MIX_CTRL]
BIS R1, 1 << DMAEN @ Использовать DMA вместо внутреннего буфера
BIS R1, 1 << BCEN @ Включить счётчик блоков
BIS R1, 1 << AC12EN @ CMD12 в конце потока
BIS R1, 1 << MSBSEL @ Передача более 1 блока
STR R1, [R0, MIX_CTRL]
@ Настройки буфера
LDR R1, [R0, WTMK_LVL]
MOV32 R1, 8 << 24 + 128 << 16 + 8 << 8 + 128
STR R1, [R0, WTMK_LVL]
@ Включить статусы
@ И сбросить флаги прерываний
SER R1
STR R1, [R0, INT_STATUS_EN]
STR R1, [R0, uSDHC_INT_STATUS]
@ Отправить 80 клоков в карту
LDR R1, [R0, SYS_CTRL]
BIS R1, 1 << INITA
STR R1, [R0, SYS_CTRL]
@ Дождаться завершения
1:
LDR R1, [R0, SYS_CTRL]
TST R1, 1 << INITA @ Должен стать = 0
BNE 1b
Вот и всё. И даже не больно.
Далее: с карточкой необходимо произвести определённую работу.
Назначить ей адрес и перевести в режим 8bit DDR.
Что бы всё так быстренько читалось и писалось.
После этого, можно прочитать файл из карточки и посчитать его сумму SHA1.
Это такая простая задача, когда уже всё сделано до вас!
Бери и копируй!
Ищите примеры и коды в
файлах чистого проекта.
Там же, вы найдёте код подъёма ВайФай модема.
Который пока что болтается без дела на порту uSDHC2.