|
|
  |
CMD25 на LPC17xx кто нибудь сделал?, Последовательная поблочная запись не работает :( |
|
|
|
Jul 11 2012, 14:25
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 21-01-05
Пользователь №: 2 113

|
Делали, но не доделали, как-то проект заглох. MCI контроллер в LPC1788 взят родной ARM-овский (ARM PrimeCell MultiMedia Card Interface PL181), на него можно найти TRM на сайте ARM-а, хотя пользы от неё мало  До мультиблочной записи не дошли, но вроде проблем с DMA небыло. Хочу заметить, что при настройке DMA число транзакций указывается в словах (т.е. по 4 байта) и в итоге на сектор будет 128 записей, а в регистре LPC_MCI->DATALEN указывается полная длина блока данных. И ещё, если у вас SDHC и выше, то можно не через CMD12 делать останов, а задать заранее через CMD23 число блоков данных.
|
|
|
|
|
Jul 11 2012, 15:13
|
Участник

Группа: Участник
Сообщений: 59
Регистрация: 3-01-07
Из: Germany
Пользователь №: 24 071

|
Делал, запись работает а вот читать поблочно не получается. На LPCWare.com есть пример который я в начале взял за основу. Но у меня примерно после 7 секунд почему то не вызывалось прерывание MCI и программка зависала не получив флаг окончания переноса данных.
|
|
|
|
|
Jul 11 2012, 15:24
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(kostyan @ Jul 11 2012, 16:00)  Документация у филипков восхитительная - просто названия флагов написаны!!! Документация как у всех - нормальная. Наверное не там смотрите (кстати, где?). По LPC17xx надо смотреть "UM10360 LPC17xx User manual" Цитата(kostyan @ Jul 11 2012, 16:00)  Такое чувство что когда встаешь отладчиком, то какието флаги успевают отработать как положено... Очень может быть... Не используйте отладчик в течении обмена.
|
|
|
|
|
Jul 12 2012, 08:58
|
Участник

Группа: Участник
Сообщений: 59
Регистрация: 3-01-07
Из: Germany
Пользователь №: 24 071

|
В MCI_Cmd_WriteBlock() numOfBlock и не нужна. Я тоже не знаю зачем они её туда передают... В этой функции другая ошибка: cmdIf.Argument = blockNum * BLOCK_LENGTH; А должно что то типа if(SDHC) cmdIf.Argument = blockNum; else cmdIf.Argument = blockNum * BLOCK_LENGTH; А вот в MCI_WriteBlock(), которая в свою очередь вызывает MCI_Cmd_WriteBlock() стоит LPC_MCI->DATALEN = BLOCK_LENGTH*numOfBlock; Кстати сегодня вышел новый релиз в котором исправлены некоторые ошибки в lpc177x_8x_mci.c Посмотрите на http://sw.lpcware.com/index.php
|
|
|
|
|
Jul 12 2012, 14:04
|
Участник

Группа: Участник
Сообщений: 59
Регистрация: 3-01-07
Из: Germany
Пользователь №: 24 071

|
Всё просто: сначала (CMD13+CMD25) а потом в цикле равном количеству секторов CODE for (j = 0; j < cnt; buf += 512, j++) { /* Set MCI Transfer registers. */ LPC_MCI->DATATMR = DATA_WR_TOUT_VALUE; LPC_MCI->DATALEN = 512;
/* Start DMA Memory to Peripheral transfer. */ DmaStart (DMA_WRITE, buf); LPC_MCI->DATACTRL = 0x99; for (i = DMA_TOUT; i; i--) { if (LPC_GPDMA->RawIntTCStat & 0x01) { /* Data transfer finished. */ break; } }
if (i == 0) { /* DMA Data Transfer timeout. */ return (__FALSE); }
if (cnt == 1) { break; }
/* Wait until Data Block sent to Card. */ while (LPC_MCI->STATUS != (MCI_DATA_END | MCI_DATA_BLK_END)) { if (LPC_MCI->STATUS & (MCI_DATA_CRC_FAIL | MCI_DATA_TIMEOUT)) { /* Error while Data Block sending occured. */ return (__FALSE); } } /* Wait 2 SD clocks */ for (i = WAIT_2SD_CLK(__CPUCLK); i; i--); }
И в конце CMD12
Сообщение отредактировал IgorKossak - Jul 12 2012, 14:41
Причина редактирования: [code] или [codebox] для кода
|
|
|
|
|
Jul 13 2012, 12:17
|
Участник

Группа: Участник
Сообщений: 59
Регистрация: 3-01-07
Из: Germany
Пользователь №: 24 071

|
Сожалею но не могу секунду ждать. У меня логгер 25600Hz 32 канала записывает. Только я не совсем понимаю зачем тогда поблочная запись если секунду ждать можно? Пробовал заменить на for(volatile unsigned int i = 100; i;--i); работает.
|
|
|
|
|
Jul 19 2012, 08:36
|
Участник

Группа: Участник
Сообщений: 59
Регистрация: 3-01-07
Из: Germany
Пользователь №: 24 071

|
#define DMA_TOUT 10000000 Ещё ни разу не выалился по таймауту. Сама запись через DMA относительно постоянна по времени. SanDisk Extreme Pro 20Mhz CLK: 2мс ждёт в цикле для 16ти секторов (8kbyte) for (i = DMA_TOUT; i; i--) { if (LPC_GPDMA->RawIntTCStat & (1<<(GPDMA_MCI_WRITE_CHANNEL))) { /* Data transfer finished. */ break; } }
В начале использовал прерыания чтобы не ждать. Но для поблочного переноса нужно дать для того чтоб в конце переноса CMD12 (Stop Read or Write transm.) послать. При использовании ОСи не проблема подождать в низко приоритетной задаче. Я использую TNKernel которую могу только порекомендовать. Без ОСи ждать действтительно не лучший вариант.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|