Добрый день!
- QNX6.5.
- Вывод утилит pidin ar дать не могу, у меня из терминалов пока доступен только последовательный порт (драйвер ethernet еще не поднял), а консоль ставноится недоступна, как только стартует драйвер etfs.
- Команда запуска драйвера
fs-etfs-imx-micron -e.
Пытаюсь поднять файловую систему ETFS для микросхемы
MT29F8G08 на нашем устройстве на базе i.MX6S. В качестве BSP у нас портированная версия BSP для
Freescale i.MX6Q Sabre Lite Board. Но поскольку в составе этой BSP не было ни одного драйвера для параллельных NAND, драйвер взяли из BSP для
NXP MCIMX7 Sabre Board, там он как раз для этой микросхемы. По составу регистров полное совпадение, единственное, что нужно было сделать, насколько я понял, это задать правильное начальное смещение регистров для модулей GPMI, BCH и APBH и назначить нужные номера аппаратных прерываний. Это можно было сделать передав параметр драйверу или просто поправив в исходниках, как я и поступил. Драйвер собрался без ошибок, запуск этого драйвера я прописал в секции .script в build-файле:
[+script] .script = {
...
display_msg Starting fs-etfs-imx-micron -e
fs-etfs-imx-micron -e
...
}
После запуска драйвера, процесс останавливается в бесконечном ожидании прерывания от модуля gpmi IMX_APBH_IRQ (45 - Logical OR of APBH DMA channels 0-3 completion and error interrupts). Система при этом не зависает "насмерть" (watchdog не срабатывает), но загрузка так и останавливается на ожидании, когда поднимется драйвер.
Клоки вроде как поданы - я их все включил в DCD секции еще в IPL:
…
DCD_ENTRY(1, 0x020c4068, 0xffffffff)
DCD_ENTRY(2, 0x020c406c, 0xffffffff)
DCD_ENTRY(3, 0x020c4070, 0xffffffff)
DCD_ENTRY(4, 0x020c4074, 0xffffffff)
DCD_ENTRY(5, 0x020c4078, 0xffffffff)
DCD_ENTRY(6, 0x020c407c, 0xffffffff)
DCD_ENTRY(7, 0x020c4080, 0xffffffff)
…
Мультиплексирование пинов я сделал в startup:
out32(MX6X_CCM_BASE + MX6X_CCM_CCGR4, 0xFFFFF300 );
pinmux_set_swmux(SWMUX_NANDF_CLE, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_CLE, PAD_CFG_0);
pinmux_set_swmux(SWMUX_NANDF_ALE, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_ALE, PAD_CFG_0);
pinmux_set_swmux(SWMUX_NANDF_WP_B, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_WP_B, PAD_CFG_0);
pinmux_set_swmux(SWMUX_NANDF_RB0, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_RB0, PAD_CFG_1);
pinmux_set_swmux(SWMUX_NANDF_CS0, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_CS0, PAD_CFG_0);
pinmux_set_swmux(SWMUX_NANDF_CS1, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_CS1, PAD_CFG_0);
pinmux_set_swmux(SWMUX_NANDF_CS2, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_CS2, PAD_CFG_0);
pinmux_set_swmux(SWMUX_NANDF_CS3, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_CS3, PAD_CFG_0);
pinmux_set_swmux(SWMUX_SD4_CMD, MUX_CTL_MUX_MODE_ALT1);
pinmux_set_padcfg(SWPAD_SD4_CMD, PAD_CFG_0);
pinmux_set_swmux(SWMUX_SD4_CLK, MUX_CTL_MUX_MODE_ALT1);
pinmux_set_padcfg(SWPAD_SD4_CLK, PAD_CFG_0);
pinmux_set_swmux(SWMUX_NANDF_D0, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_D0, PAD_CFG_0);
pinmux_set_swmux(SWMUX_NANDF_D1, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_D1, PAD_CFG_0);
pinmux_set_swmux(SWMUX_NANDF_D2, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_D2, PAD_CFG_0);
pinmux_set_swmux(SWMUX_NANDF_D3, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_D3, PAD_CFG_0);
pinmux_set_swmux(SWMUX_NANDF_D4, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_D4, PAD_CFG_0);
pinmux_set_swmux(SWMUX_NANDF_D5, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_D5, PAD_CFG_0);
pinmux_set_swmux(SWMUX_NANDF_D6, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_D6, PAD_CFG_0);
pinmux_set_swmux(SWMUX_NANDF_D7, MUX_CTL_MUX_MODE_ALT0);
pinmux_set_padcfg(SWPAD_NANDF_D7, PAD_CFG_0);
pinmux_set_swmux(SWMUX_SD4_DAT0, MUX_CTL_MUX_MODE_ALT2);
pinmux_set_padcfg(SWPAD_SD4_DAT0, PAD_CFG_2);
Вот фрагмент кода, в котором все стопорится:
// APBH, BCH and GPMI init
if (nand_init(cio) != 0) {
dev->log(_SLOG_CRITICAL, "nand_init failed : %s", strerror(errno));
// We will not return
}
cio->apbhirq = IMX_APBH_IRQ;
cio->bchirq = IMX_BCH_IRQ;
// Start-up a thread that is dedicated to interrupt processing
cio->apbhirq_expected = 0;
pthread_mutex_init(&cio->apbhmutex, NULL);
pthread_cond_init(&cio->apbhcond, NULL);
pthread_create(NULL, NULL, apbhint_thread, cio);
// Start-up a thread that is dedicated to interrupt processing
cio->bchirq_expected = 0;
pthread_mutex_init(&cio->bchmutex, NULL);
pthread_cond_init(&cio->bchcond, NULL);
pthread_create(NULL, NULL, bchint_thread, cio);
...
if (nand_wait_busy(cio, MAX_RESET_USEC, 0) != 0) {
dev->log(_SLOG_CRITICAL, "Timeout on RESET");
}
// Create reset device and reset the part - for some devices it must be first command
create_reset_descriptor(reset_ptr);
status = run_dma((apbh_dma_t*)reset_ptr, cio, NAND_DMA_GPMI_TRANS, (uint32_t)virtual_to_physical_addr(reset_ptr));
if (status != NAND_EOK) {
dev->log(_SLOG_CRITICAL, "DMA operation fail");
}
if (nand_wait_busy(cio, MAX_RESET_USEC, 0) != 0) {
dev->log(_SLOG_CRITICAL, "Timeout on RESET");
}
delay(2);
// Create read status chain and read status register from device
create_readStatus2_descriptor(read_status_ptr, mem_stat_ptr, 1);
status = run_dma((apbh_dma_t*)read_status_ptr, cio, NAND_DMA_GPMI_TRANS, (uint32_t)virtual_to_physical_addr(read_status_ptr)); //<<<<<<<<<<<<<<<<< Оставливается на ожидании прерывания здесь <<<<<<<<<<<<<<<<<<<
...
Если у кого-нибудь есть идеи, подскажите в чем может быть дело?