Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Atmel SAM3U4
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2, 3, 4
BurglarInt
Здравствуйте, у меня появилась проблема при работе с внешней NAND Flash.
При подаче команды Read ID к Flash, сигнал CE формируется неправильно (не становится в актиный уровень). Вследствии этого флэш не реагирует на команду, в чем может быть проблема ?
aaarrr
Цитата(sonycman @ Aug 21 2011, 22:34) *
Всё начинает нормально функционировать только после сброса по RSTB, то есть флеш не слетает, а происходит какое-то залочивание контроллера при включении...
Плата лежит дома, при комнатной температуре...

Непонятно это всё, это что-же, мне теперь каждую неделю батарейку передёргивать и переустанавливать часы?
Мог ли я что-то напортачить в коде стартапа? Но эта проблема возникает только после простоя платы без питания несколько дней...

Наблюдал точно такое же поведение "родного" кита от атмела. От батарейки в своем устройстве в результате был вынужден отказаться.
Кстати, на вашей плате стоит -ES, или более свежий кристалл?

Цитата(sonycman @ Aug 26 2011, 17:27) *
Только вот запропастился куда-то наш гуру, в отпуске, наверное rolleyes.gif

Вроде того.

Цитата(BurglarInt @ Aug 30 2011, 16:12) *
Здравствуйте, у меня появилась проблема при работе с внешней NAND Flash.
При подаче команды Read ID к Flash, сигнал CE формируется неправильно (не становится в актиный уровень). Вследствии этого флэш не реагирует на команду, в чем может быть проблема ?

В ревизии -ES один из CE не работает - не ваш ли случай?
sonycman
Цитата(aaarrr @ Aug 31 2011, 16:13) *
Наблюдал точно такое же поведение "родного" кита от атмела. От батарейки в своем устройстве в результате был вынужден отказаться.
Кстати, на вашей плате стоит -ES, или более свежий кристалл?

У меня ревизия А.

Возможно, залочивание кристалла происходит по причине слишком медленного нарастания напряжения питания.
Проблема возникает при запитывании от лабораторного источника с ограничением макс. тока на уровне 250 ма (пробовал и 750 - всё одно).
Последние 10 дней запитываю от USB порта компьютера - пока ни разу не повис.

Потом попробую установить ограничение тока лабораторника на несколько ампер, для эксперимента.

ЗЫ: вот уже несколько лет пользуюсь лабораторником - проблем с нарастанием напряжения и зависанием не было никогда.
SAM3U первый проблемный кристалл. И проблема возникает только при питании батарейного блока от батареи.

Наверное, тоже придётся отказаться от встроенного RTC sad.gif
aaarrr
Охладить попробуйте - кит у меня зависал после улицы зимой (хотя сам при этом сильно остыть не успевал).

Вообще же, ситуация дурацкая - причины неясны, в еррате молчок, а зависание наблюдается. И в качестве дополнительного бонуса очень медленный старт процессора после RSTB sad.gif
singlskv
Цитата(singlskv @ Aug 26 2011, 01:29) *
то буду делать это в этой теме...
Ну вот и вопросики нарисовались:
1. Ремап векторов в SRAM улучшает производительность(учитываем различные шины для доступа к FLASH и SRAM) ?
2. Размещение функции которая должна максимально быстро работать в SRAM дает преимущество как на ARM7 или нет ?
(ARM вроде как утверждает что из-за наличия многих шин код не нужно размещать в SRAM)
3. Какие ограничения имеет PDC по пропускной способности ?
aaarrr
1-2. Нет.
3. Каких-либо прямых ограничений не имеет. Да и подключен он теперь исключительно к медленной периферии.
singlskv
Цитата(aaarrr @ Sep 13 2011, 02:12) *
1-2. Нет.
А что делать с функциями записи в флеш ?
у меня что-то какая-то фигня
беру свою стандартную(от арм7) функцию которая работает в секции .fast и считает просто CRC16
вылетаю в hardfault
соответственно вопрос про запись в флеш
запускать из SRAM(а как ?)
или юзать IAP из SAM-BA ?

хотя конечно возможно у CrossWorks странный конфиг по умолчанию....

aaarrr
Цитата(singlskv @ Sep 13 2011, 02:27) *
А что делать с функциями записи в флеш ?

Как и раньше - писать из RAM или другого банка.

Цитата(singlskv @ Sep 13 2011, 02:27) *
хотя конечно возможно у CrossWorks странный конфиг по умолчанию....

Посмотрите map.
singlskv
Цитата(aaarrr @ Sep 13 2011, 02:32) *
Как и раньше - писать из RAM или другого банка
Посмотрите map.
то есть у Вас из рам все работает ? при записи в флеш
тогда буду копать скрипт линкера...
просто у меня какая-то фигня генерица компилятором похоже...

не вижу чего-нить непрвильного в map файле
Hardfault генерит вызов функции WORD ModbusCrcBuff(BYTE *buff, DWORD len);
вот их описание:
CODE

//---- CRC sections
#define FAST_SECTION __attribute__((section(".fast")))
#define FLASH_CONST_ARRAY static const
#define RAM_ARRAY

#define MODBUS_CRC_SECTION FAST_SECTION
#define CRC8_SECTION FAST_SECTION
#define MODBUS_CRC_TABLE RAM_ARRAY
#define CRC8_TABLE RAM_ARRAY
.........................

#if !defined(MODBUS_CRC_SECTION)
#define MODBUS_CRC_SECTION
#endif

#if !defined(CRC8_SECTION)
#define CRC8_SECTION
#endif

#if !defined(FLASH_CONST_ARRAY)
#define FLASH_CONST_ARRAY static const
#endif

#if !defined(MODBUS_CRC_TABLE)
#define MODBUS_CRC_TABLE FLASH_CONST_ARRAY
#endif

#if !defined(CRC8_TABLE)
#define CRC8_TABLE FLASH_CONST_ARRAY
#endif

#include "ModbusCrc.h"

MODBUS_CRC_TABLE BYTE ModbusCrcLo[256] =
{
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,

0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
};

MODBUS_CRC_TABLE BYTE ModbusCrcHi[256]=
{
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04,
0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8,
0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10,

0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C,
0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0,

0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C,
0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,

0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54,
0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98,
0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40
};

WORD ModbusCrc(WORD crc, BYTE data) MODBUS_CRC_SECTION;
WORD ModbusCrc(WORD crc, BYTE data)
{
BYTE crclo = crc;
BYTE crchi = crc >> 8;
BYTE index = crclo ^ data;
crclo = crchi ^ ModbusCrcLo[index];
crchi = ModbusCrcHi[index];
return (crchi << 8) | crclo;
}

WORD ModbusCrcBuff(BYTE *buff, DWORD len) MODBUS_CRC_SECTION;
WORD ModbusCrcBuff(BYTE *buff, DWORD len)
{
BYTE index;
BYTE crclo = MODBUS_CRC_LO_DEFAULT;
BYTE crchi = MODBUS_CRC_HI_DEFAULT;
while (len--)
{
index = crclo ^ *buff++;
crclo = crchi ^ ModbusCrcLo[index];
crchi = ModbusCrcHi[index];
}

return (crchi << 8) | crclo;
}

CRC8_TABLE BYTE DallasCrc[256] =
{ // Полином 0x8C
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53
};

BYTE Crc8Buff(BYTE *buff, DWORD len) CRC8_SECTION;
BYTE Crc8Buff(BYTE *buff, DWORD len)
{
BYTE index;
BYTE crc = CRC8_DEFAULT;
while (len--)
{
index = crc ^ *buff++;
crc = DallasCrc[index];
}

return crc;
}

aaarrr
Цитата(singlskv @ Sep 13 2011, 02:39) *
то есть у Вас из рам все работает ? при записи в флеш

Не пробовал, но нет оснований не доверять документации в данном вопросе.

Цитата(singlskv @ Sep 13 2011, 02:39) *
тогда буду копать скрипт линкера...
просто у меня какая-то фигня генерица компилятором похоже...

Вообще, я бы IAP-функцию использовал, наверное - меньше телодвижений и расхода RAM нет.
singlskv
Цитата(aaarrr @ Sep 13 2011, 02:51) *
ообще, я бы IAP-функцию использовал, наверное - меньше телодвижений и расхода RAM нет.
В конечном продукте наверное использую IAP
но понять что я делаю не так при размещении функций в SRAM хотелось-бы...



может я еще что-нить недопонял в настройке басматрикск ?
у меня пока вот такЖ
Код
  ldr r1, =MATRIX_BASE_ADDRESS
  ldr r0, =(2 << MATRIX_SCFG0_DEFMSTR_TYPE_BIT) | (1 << MATRIX_SCFG0_FIXED_DEFMSTR_BIT)
  str r0, [r1, #MATRIX_SCFG0_BASE_OFFSET]
  str r0, [r1, #MATRIX_SCFG1_BASE_OFFSET]
  ldr r0, =(2 << MATRIX_SCFG0_DEFMSTR_TYPE_BIT) | (0 << MATRIX_SCFG0_FIXED_DEFMSTR_BIT)
  str r0, [r1, #MATRIX_SCFG3_BASE_OFFSET]
  str r0, [r1, #MATRIX_SCFG4_BASE_OFFSET]

sonycman
Потихоньку пишу инициализацию карты памяти контроллером HSMCI.

Дошёл до команды ACMD41, после выдачи которой необходимо ждать, пока не снимется статус BUSY.
В мануале это делается опросом флага NOTBUSY регистра статуса, пока он не установится в 1.

Но проблема в том, что этот флаг находится в 1 сразу после завершения команды sad.gif

То есть как только устанавливается CMDRDY, опрашиваю NOTBUSY - он всегда в единичке.

Соответственно инициализация карты не завершается, в ответе команды ACMD41 (регистр OCR карты памяти) биты 31 и 30 сброшены...
Если подождать около секунды и повторно выдать ACMD41 - то в ответе уже всё ОК - бит 31 установлен (инициализация завершена) и 30 сообщает правильную информацию, является ли карта SDHC или нет.

Спрашивается - почему контроллер HSMCI не выполняет ожидание статуса BUSY?

Может быть, я что-то делаю не так?
aaarrr
Цитата(sonycman @ Sep 22 2011, 22:22) *
Спрашивается - почему контроллер HSMCI не выполняет ожидание статуса BUSY?

Может быть, я что-то делаю не так?

Это не тот busy, который умеет ждать хост. ACMD41 нужно подавать в цикле до тех пор пока не сбросится 31-й бит или не случится тайм-аут инициализации (софтовый, естественно).
sonycman
Цитата(aaarrr @ Sep 22 2011, 23:57) *
Это не тот busy, который умеет ждать хост. ACMD41 нужно подавать в цикле до тех пор пока не сбросится 31-й бит или не случится тайм-аут инициализации (софтовый, естественно).

Даже так sm.gif
Значит попробую подождать в цикле, пока 31 бит в ответе не установится, спасибо!
sonycman
Инициализация карты у меня получается такая:
PowerOn -> CMD0 -> CMD8 -> ACMD41 -> CMD2 -> CMD3 -> CMD9 -> CMD7 -> ACMD6.

Дошёл пока до CMD9 включительно, вроде всё ОК.

Хотел ещё спросить по поводу операций с блоками - в поле Transfer Type (TRTYP) регистра комманд HSMCI_CMDR какие нужно выбирать значения для single и multiple блоков?
Вроде как 0 для одно- и 1 для много- секторных чтения\записи, но вот смущает ещё значение 5 - SDIO Block... rolleyes.gif
aaarrr
Цитата(sonycman @ Sep 23 2011, 20:29) *
Инициализация карты у меня получается такая:
PowerOn -> CMD0 -> CMD8 -> ACMD41 -> CMD2 -> CMD3 -> CMD9 -> CMD7 -> ACMD6.

А у меня такая:
PowerOn -> CMD0 -> CMD8 -> ACMD41 -> CMD2 -> CMD3 -> CMD7 (select) -> ACMD51 -> ACMD6 (только если поддерживается 4 бита) -> Проверка и выбор high speed (CMD6), если версия спецификации >= 2 -> CMD7 (deselect) -> CMD9 -> Установка скорости интерфейса

Цитата(sonycman @ Sep 23 2011, 20:29) *
Хотел ещё спросить по поводу операций с блоками - в поле Transfer Type (TRTYP) регистра комманд HSMCI_CMDR какие нужно выбирать значения для single и multiple блоков?
Вроде как 0 для одно- и 1 для много- секторных чтения\записи, но вот смущает ещё значение 5 - SDIO Block... rolleyes.gif

SDIO и SD Memory - это совсем разные вещи.
sonycman
Спасибо!
Цитата(aaarrr @ Sep 23 2011, 20:52) *
если версия спецификации >= 2 -> CMD7 (deselect) -> CMD9 -> Установка скорости интерфейса

А вот тут можно разъяснить, для чего делать deselect? Ведь CMD9 можно выдать вообще до CMD7 (select)?
Или это имеет отношение к CMD6?

Цитата
SDIO и SD Memory - это совсем разные вещи.

Вот оно что, а у меня эти понятия перемешались вместе sm.gif

Цитата
только если поддерживается 4 бита
- неужели встречаются карточки без поддержки 4 бит?
aaarrr
Цитата(sonycman @ Sep 23 2011, 21:00) *
А вот тут можно разъяснить, для чего делать deselect? Ведь CMD9 можно выдать вообще до CMD7 (select)?
Или это имеет отношение к CMD6?

CMD9 можно выдать только карте в "stby", а ACMD51 - только в "tran", поэтому сначала карта выбирается через CMD7 (select), затем переводится в "stby" через CMD7 (deselect).
Можно сделать так:
PowerOn -> CMD0 -> CMD8 -> ACMD41 -> CMD2 -> CMD3 -> CMD9 -> CMD7 (select) -> ACMD51 -> ACMD6 (только если поддерживается 4 бита) -> Проверка и выбор high speed (CMD6), если версия спецификации >= 2 -> Установка скорости интерфейса

Наврал, нельзя.

Цитата(sonycman @ Sep 23 2011, 21:00) *
- неужели встречаются карточки без поддержки 4 бит?

Ну, как бы надо проверять, если уж все делать честно. Не встречал до сих пор sm.gif
sonycman
Цитата(aaarrr @ Sep 23 2011, 21:21) *
Можно сделать так:
PowerOn -> CMD0 -> CMD8 -> ACMD41 -> CMD2 -> CMD3 -> CMD9 -> CMD7 (select) -> ACMD51 -> ACMD6 (только если поддерживается 4 бита) -> Проверка и выбор high speed (CMD6), если версия спецификации >= 2 -> Установка скорости интерфейса

Да, да, я тоже такого мнения sm.gif

А вот последний пункт - Установка скорости интерфейса - это что означает? Это разве не одно и то же с high speed?
aaarrr
Цитата(sonycman @ Sep 23 2011, 21:25) *
А вот последний пункт - Установка скорости интерфейса - это что означает? Это разве не одно и то же с high speed?

Нет, это выбор режима. Причем после выбора high speed меняются поля в CSD, так что CMD9 нужно все же давать в конце. Скорость интерфейса устанавливается на основании данных из этих полей.
sonycman
Цитата(aaarrr @ Sep 23 2011, 21:30) *
Нет, это выбор режима. Причем после выбора high speed меняются поля в CSD, так что CMD9 нужно все же давать в конце. Скорость интерфейса устанавливается на основании данных из этих полей.

То есть это установка макс. частоты интерфейса?
Я почему то думал, раз карта поддерживает HS, то без проблем должна работать на 50 МГц.
Значит, это не так?
aaarrr
Цитата(sonycman @ Sep 23 2011, 21:44) *
То есть это установка макс. частоты интерфейса?
Я почему то думал, раз карта поддерживает HS, то без проблем должна работать на 50 МГц.
Значит, это не так?

Максимальная частота прописана в CSD, ориентироваться нужно исключительно на эти данные. Они в свою очередь зависят от наличия и выбора режима HS.
То есть если сравнить CSD до свистопляски с CMD6 и после, то он будет содержать разные значения.
sonycman
Хм, этот HSMCI вообще может корректно обрабатывать статус BUSY карты памяти?

Подаю команду CMD7 подряд два раза - просто для интереса, чтобы посмотреть, как меняется статус карточки.
Первый раз она обрабатывается нормально, но во второй получаю ошибку таймаута ответа (RTOE: Response Time-out Error)... sad.gif

Вероятно, карточка всё ещё находится в состоянии BUSY после первой команды CMD7, и этот статус опять не обрабатывается контроллером angry.gif

Но почему? Ведь тип ответа команды задаю правильно - R1b?
Разве это не означает, что контроллер должен автоматически ожидать, пока карта не снимет BUSY?
aaarrr
Цитата(sonycman @ Dec 15 2011, 14:28) *
Но почему? Ведь тип ответа команды задаю правильно - R1b?
Разве это не означает, что контроллер должен автоматически ожидать, пока карта не снимет BUSY?

Нет. Это означает, что программа должна дождаться флага NOTBUSY в SR.
sonycman
Цитата(aaarrr @ Dec 15 2011, 14:40) *
Нет. Это означает, что программа должна дождаться флага NOTBUSY в SR.

Поставил ожидание:
Код
do
        {
            status = AT_MCI0->MCI_SR;
        }
        while (!(status & AT_MCI_NOTBUSY));

но никакого эффекта... sad.gif
Что делать - то?

Похоже, повторяется ситуация, как с командой ACMD41 - флаг NOTBUSY устанавливается мгновенно с CMDRDY...

ЗЫ: если ждать нужно ручками - зачем тогда вообще ввели специальный тип команды с ответом R1b? Толку то нет.

ЗЗЫ: а, так тут наверное я сам напортачил - подавать CMD7(SELECT) два раза подряд, наверное, нельзя.
Вот карточка и входит в ступор...
Сейчас попробую сначала CMD7(SELECT), а потом сразу CMD7(DESELECT)...
aaarrr
Цитата(sonycman @ Dec 15 2011, 14:43) *
но никакого эффекта... sad.gif
Что делать - то?

Странно, проверка NOTBUSY у меня вполне себе работает.

Цитата(sonycman @ Dec 15 2011, 14:43) *
Похоже, повторяется ситуация, как с командой ACMD41 - флаг NOTBUSY устанавливается мгновенно с CMDRDY...

ACMD41 - это особый случай, и там совсем другой "busy". Кстати, взвода CMDRDY перед проверкой NOTBUSY дожидаетесь?

Цитата(sonycman @ Dec 15 2011, 14:43) *
ЗЫ: если ждать нужно ручками - зачем тогда вообще ввели специальный тип команды с ответом R1b? Толку то нет.

Потому что в противном случае контроллер возможно даже смотреть не будет busy status.
sonycman
Цитата(aaarrr @ Dec 15 2011, 14:55) *
Кстати, взвода CMDRDY перед проверкой NOTBUSY дожидаетесь?

Конечно, такая же проверка:
Код
    AT_MCI0->MCI_CMDR = comm_reg;
    do
    {
        status = AT_MCI0->MCI_SR;
    }
    while (!(status & AT_MCI_CMDRDY));


Попробовал и так: сначала CMD7(SELECT), а потом сразу CMD7(DESELECT).
Без разницы - получаю RTOE...
aaarrr
Ну, на CMD7(DESELECT) ответа и не должно быть.

Сдается мне, все правильно: повторная передача CMD7 переводит карту назад в stand-by, ответа и не должно быть.
sonycman
Цитата(aaarrr @ Dec 15 2011, 15:14) *
Ну, на CMD7(DESELECT) ответа и не должно быть.

Сдается мне, все правильно: повторная передача CMD7 переводит карту назад в stand-by, ответа и не должно быть.

Да, спасибо, сейчас попробую отправить вслед за CMD7 другую команду.
Действительно, с CMD7 всё не так просто - судя по спецификации на эту команду карта отвечает только при переходе с STBY на TRAN.

ЗЫ: отправил следом ACMD51 - всё в порядке, ошибок нет sm.gif
Впрочем, ошибок нет, даже если совсем убрать ожидание NOTBUSY. То ли это из-за низкой скорости интерфейса (работает пока на паре мегагерц, в отладочных соображениях), и карта успевает отпустить линию данных, то ли всё же контроллер отслеживает статус автоматически...
sonycman
Ну вот, вроде сделал чтение сектора, теперь надо бы DMA подключать.
В даташите на этот счёт всё довольно мутно - какие-то дескрипторы, выравнивание по WORD и прочие грустные штуки sm.gif

Мне бы организовать чтение\запись по произвольному адресу в памяти и с произвольным кол-вом секторов.

Может ли DMAC выполнять чтение\запись памяти по произвольному адресу, а не только по выровненному до слова?
Вроде бы есть поля в регистрах, этому сопутствующие.

С дескрипторами так и не пойму, допустим, надо мне прочесть с карты памяти 32 сектора последовательно в память, неужели для этого придётся создавать в памяти 32 дескриптора?
Можно ли обойтись одним так, чтобы чтение 32 секторов выполнялось за один раз, или придётся 32 раза перепрограммировать DMA (на каждый сектор)?

Судя по описанию в даташите, придётся возиться с каждым сектором sad.gif
aaarrr
Цитата(sonycman @ Dec 15 2011, 15:19) *
Впрочем, ошибок нет, даже если совсем убрать ожидание NOTBUSY. То ли это из-за низкой скорости интерфейса (работает пока на паре мегагерц, в отладочных соображениях), и карта успевает отпустить линию данных, то ли всё же контроллер отслеживает статус автоматически...

Ну, на CMD7 карте задумываться особо и не о чем.

Цитата(sonycman @ Dec 15 2011, 19:05) *
Может ли DMAC выполнять чтение\запись памяти по произвольному адресу, а не только по выровненному до слова?

Может, но тогда ширина передачи должна быть снижена до байта, что скажется на производительности - 3/4 возможности шины будут пущены на ветер.

Цитата(sonycman @ Dec 15 2011, 19:05) *
Можно ли обойтись одним так, чтобы чтение 32 секторов выполнялось за один раз, или придётся 32 раза перепрограммировать DMA (на каждый сектор)?

Теоретически можно обойтись одним. Контроллеру HSMCI в общем-то все равно, как запрограммирован контроллер DMA, лишь бы данные шли.
sonycman
Цитата(aaarrr @ Dec 15 2011, 20:15) *
Может, но тогда ширина передачи должна быть снижена до байта, что скажется на производительности - 3/4 возможности шины будут пущены на ветер.

Понятно. Но зато не надо париться с выравниванием.
Что-то я слабо представляю, как вообще возможно всегда получать выровненный адрес в памяти, с которой будет работать файловая система в реальном приложении.

Хотя, среди примеров есть способ программирования DMA несколькими дескрипторами для передачи блока данных длиной не кратной 4.
Если только делать что-то похожее...

Среди регистров DMAC есть поля Source Chunk Transfer Size и Destination Chunk Transfer size.
Могут принимать значения 1 или 4.
Это что-то типа пакетной передачи?

Последнее, как я понимаю, будет лучше?
Цитата(aaarrr @ Dec 15 2011, 20:15) *
Теоретически можно обойтись одним. Контроллеру HSMCI в общем-то все равно, как запрограммирован контроллер DMA, лишь бы данные шли.

В общем, буду пробовать sm.gif
aaarrr
Цитата(sonycman @ Dec 15 2011, 22:59) *
Что-то я слабо представляю, как вообще возможно всегда получать выровненный адрес в памяти, с которой будет работать файловая система в реальном приложении.

А в чем проблема? Файловой системе все равно придется работать с целыми секторами, так почему бы их не выровнять по границе слова?
Кроме того, не стоит забывать, что ядру тоже не всегда удобно работать с не выровненными адресами - всякие memset/memcpy это замедлит.

Цитата(sonycman @ Dec 15 2011, 22:59) *
Среди регистров DMAC есть поля Source Chunk Transfer Size и Destination Chunk Transfer size.
Могут принимать значения 1 или 4.
Это что-то типа пакетной передачи?

Последнее, как я понимаю, будет лучше?

Да, это значит, что HSMCI и DMA будут между собой обмениваться блоками по 4 слова, что, несомненно, лучше. Только не забудьте установить это поле и у HSMCI и у DMAC одинаково.
sonycman
Цитата(aaarrr @ Dec 15 2011, 20:15) *
Теоретически можно обойтись одним. Контроллеру HSMCI в общем-то все равно, как запрограммирован контроллер DMA, лишь бы данные шли.

Но в чём проблема - в примерах для READ_SINGLE_BLOCK в качестве источника данных всегда указывается не регистр HSMCI_RDR, а так называемая "апертура" FIFOx Memory Aperture, при этом указатель на неё задаётся как инкрементируемый.
Это FIFO имеет граничный размер (HSMCI_FIFOx[x=0..255]), и при чтении\записи больших блоков не приведёт ли это к выходу за пределы этой памяти?

Цитата(aaarrr @ Dec 15 2011, 23:10) *
А в чем проблема? Файловой системе все равно придется работать с целыми секторами, так почему бы их не выровнять по границе слова?
Кроме того, не стоит забывать, что ядру тоже не всегда удобно работать с не выровненными адресами - всякие memset/memcpy это замедлит.

Ну, к примеру, если я захочу записать пару килобайт данных, пусть даже выровненных в памяти, в файл с произвольным смещением от его начала (не нулевым), то это будет как работать?
Сначала в буфер файловой системы считается первый сектор, в который частично попадают эти данные, в него копируется их кусок, затем этот сектор записывается.
Далее уже идёт прямая запись в сектора из памяти с абсолютно произвольного по выравниванию места, которое будет зависеть от начального смещения по файлу...
aaarrr
Цитата(sonycman @ Dec 15 2011, 23:22) *
Но в чём проблема - в примерах для READ_SINGLE_BLOCK в качестве источника данных всегда указывается не регистр HSMCI_RDR, а так называемая "апертура" FIFOx Memory Aperture, при этом указатель на неё задаётся как инкрементируемый.

Упс. Да, забыл это обстоятельство. Тогда остается делать цепочку дескрипторов DMA. Впрочем, цепочку не обязательно - прерывания все равно будут, а перепрограммировать DMA - секундное дело.

Цитата(sonycman @ Dec 15 2011, 23:22) *
Далее уже идёт прямая запись в сектора из памяти с абсолютно произвольного по выравниванию места, которое будет зависеть от начального смещения по файлу...

Идея понятна, да. У меня просто между файловой системой и картой проложен еще один уровень из дискового кэша и буфера записи, поэтому вопросов с выравниванием нет.
Тогда остается извернуться через поле OFFSET регистра HSMCI_DMA, но он, как я понимаю, действителен только для записи.
sonycman
Цитата(aaarrr @ Dec 16 2011, 00:30) *
Упс. Да, забыл это обстоятельство. Тогда остается делать цепочку дескрипторов DMA. Впрочем, цепочку не обязательно - прерывания все равно будут, а перепрограммировать DMA - секундное дело.

Эх, вот если бы не было никакой "апертуры", а был бы регистр типа HCMI_RDR безо всякой инкрементации...
Почему так сделано, интересно?

Цитата
Идея понятна, да. У меня просто между файловой системой и картой проложен еще один уровень из дискового кэша и буфера записи, поэтому вопросов с выравниванием нет.
Тогда остается извернуться через поле OFFSET регистра HSMCI_DMA, но он, как я понимаю, действителен только для записи.

Я так и понял, у Вас куча памяти, и идёт копирование данных сначала в выровненную память\кеш, а уже потом на карточку...

Да, непонятно с этим офсетом.
Думаю, тут можно поступить тоже используя дескрипторы - к примеру, понадобится три штуки для выравнивания сектора из 512 байт:
1. (MEMORY_ADDRESS & 0x03) - получаем 1 - 3 байта, для которых создаём дескриптор с BYTE доступом.
2. дескриптор с WORD доступом, обрабатывающий основную часть данных.
3. последний дескриптор BYTE, перебрасывающий последние 1-3 байта.

Чтобы уменьшить частоту прерываний, выделю память для 3-4 дескрипторов.
С другой стороны, возможно не стоит париться и сделать всё на BYTE дескрипторах, знать бы ещё, насколько загружена получается внутренняя шина...
aaarrr
Цитата(sonycman @ Dec 16 2011, 05:41) *
Почему так сделано, интересно?

Надо полагать, для ускорения всего и вся sm.gif Вполне возможно, что этому процессору оно и не нужно, но ведь IP-блоки тоже подвержены copy-paste.

Цитата(sonycman @ Dec 16 2011, 05:41) *
Я так и понял, у Вас куча памяти, и идёт копирование данных сначала в выровненную память\кеш, а уже потом на карточку...

Именно так.

Цитата(sonycman @ Dec 16 2011, 05:41) *
Думаю, тут можно поступить тоже используя дескрипторы - к примеру, понадобится три штуки для выравнивания сектора из 512 байт:
1. (MEMORY_ADDRESS & 0x03) - получаем 1 - 3 байта, для которых создаём дескриптор с BYTE доступом.

Так нельзя: контроллер HSMCI ждет на входе 32 бита и никак иначе. Не получится ему три байта скормить, кроме как через OFFSET, который и указывает, сколько байт нужно проигнорировать.
А вот с чтением, похоже, остается только байтовый доступ.
sonycman
Цитата(aaarrr @ Dec 16 2011, 06:08) *
Так нельзя: контроллер HSMCI ждет на входе 32 бита и никак иначе. Не получится ему три байта скормить, кроме как через OFFSET, который и указывает, сколько байт нужно проигнорировать.
А вот с чтением, похоже, остается только байтовый доступ.

Да, с записью, оказывается, все много проще, задать offset и дело в шляпе sm.gif
Странно, что для чтения не предусмотрели такую фичу вместо сомнительного ROPT...

Интересно, а как себя поведет DMA при возникновении ошибки, к примеру, при чтении, если карта не отдаст количество данных, на которые он запрограммирован?
Повиснет?
aaarrr
Цитата(sonycman @ Dec 16 2011, 10:46) *
Интересно, а как себя поведет DMA при возникновении ошибки, к примеру, при чтении, если карта не отдаст количество данных, на которые он запрограммирован?
Повиснет?

Карта не отдать просто не сможет: хост подает клок и снимает данные вне зависимости от того, что думает карта. Другое дело, что в таком случае появится ошибка CRC, но DMA об этом и не узнает.
sonycman
Цитата(aaarrr @ Dec 17 2011, 00:47) *
Карта не отдать просто не сможет: хост подает клок и снимает данные вне зависимости от того, что думает карта. Другое дело, что в таком случае появится ошибка CRC, но DMA об этом и не узнает.

Ну как же - есть же Start Bit, есть специальные токены начала данных (по крайней мере в режиме SPI были), то есть хост может определить момент появления данных.
К примеру, если после команд чтения данных не ждать установки флага NOTBUSY и сразу попытаться подавать следующую команду - получаем зависон на циклическом опросе флага AT_MCI_RXRDY, который никогда уже не установится - карточка-то молчит.
Или просто попробовать прочитать больше данных, чем карта отдаёт - скажем, вместо 8 байт команды ACMD51 попытаться прочесть 9 - аналогичный зависон...

То есть хост определяет, отдаёт карта данные, или нет с точностью до байта.
Но это касается работы без DMA, с ним, возможно, будет несколько иначе...

PS: хотя бог знает, может просто я чего нибудь напутал... sm.gif
aaarrr
Цитата(sonycman @ Dec 17 2011, 05:39) *
То есть хост определяет, отдаёт карта данные, или нет с точностью до байта.

Тут некоторая путаница в понятиях получается. Чисто гипотетически предположим, что хост считывает 16 байт, а на деле карта возвращает 8.
В этом случае будут нормально приняты старт, первые 8 байт, а вместо остальных будут приняты 0xff, что повлечет ошибку CRC.
Понятно, что хост не знает, сколько на самом деле было передано картой.

Цитата(sonycman @ Dec 17 2011, 05:39) *
Но это касается работы без DMA, с ним, возможно, будет несколько иначе...

С DMA все просто - он знать ничего не знает об ошибках той периферии, которую обслуживает. То есть его придется при ошибках переконфигурировать полностью вручную.
sonycman
Эмм... дошёл до конфигурирования DMA применительно к HSMCI.
Поставил в тупик регистр DMAC_CFGx, конкретно - его поля DST_PER и SRC_PER.
Где искать эти идентификаторы?

Как понимаю, нужны ID для HSMCI и для MEMORY.
Нашёл только табличку с ID на 43 странице мануала, но это по ходу не то sad.gif...

А, все, нашел, в другом разделе было sm.gif

И имеет ли смысл что-то записывать в поле AHB_PROT? Так и не понял, для чего оно и чем отличаются его значения.
aaarrr
Цитата(sonycman @ Dec 20 2011, 14:30) *
Нашёл только табличку с ID на 43 странице мануала, но это по ходу не то sad.gif...

Табличка есть на странице 28 (7.6 DMA Controller).

Цитата(sonycman @ Dec 20 2011, 14:30) *
И имеет ли смысл что-то записывать в поле AHB_PROT? Так и не понял, для чего оно и чем отличаются его значения.

Ну, как минимум младший бит должен стоять, как я понимаю.
sonycman
Цитата(aaarrr @ Dec 20 2011, 17:34) *
Табличка есть на странице 28 (7.6 DMA Controller).

Ну, как минимум младший бит должен стоять, как я понимаю.

Спасибо! Усиленно искал таблицу в разделе DMAC, к которому она и относится, а они ее почему-то засунули в общий DMA...

Поэкспериментирую с различными по ширине режимами доступа (WORD/BYTE), может, получится что нибудь интересное sm.gif
sonycman
В мануале в примерах программирования DMA под HSMCI присутствуют поля регистров DMAC, такие, как:
Цитата
DIF and SIF are set with their respective layer ID. If SIF is different from DIF, the
DMA controller is able to prefetch data and write HSMCI simultaneously.

Цитата
DST_REP is set to zero meaning that address are contiguous.

Цитата
Program LLI_W.DMAC_DSCRx with the address of LLI_B descriptor. And set
DSCRx_IF to the AHB Layer ID.

которые отсутствуют в описании самих регистров.
Очередной copy\paste, на который стоит забить?
aaarrr
Цитата(sonycman @ Dec 21 2011, 01:40) *
Очередной copy\paste, на который стоит забить?

Ага. Просто у некоторых атмелов есть DMAC с двумя AHB-интерфейсами. Эти поля относятся к нему.
sonycman
Попробовал запрограммировать DMAC на чтение из HSMCI 512 байтового сектора с доступом BYTE для записи в не выравненный буфер:
Код
HDMA_CTRLA = AT_HDMA_SRC_WIDTH_BYTE | AT_HDMA_DST_WIDTH_BYTE | AT_HDMA_SCSIZE_1 | AT_HDMA_DCSIZE_1 | AT_HDMA_BTSIZE(512);

Ничего не получилось crying.gif
В память записалась 1/4 часть данных (128 байт, вместо 512), всё вперемешку, флаги окончания передачи DMA не выставились.
Видимо, читать из фифо побайтно оно не может, хватает сразу слово и получается мешанина...

Получилось так:
Код
HDMA_CTRLA = AT_HDMA_SRC_WIDTH_WORD | AT_HDMA_DST_WIDTH_BYTE | AT_HDMA_SCSIZE_1 |     AT_HDMA_DCSIZE_1 | AT_HDMA_BTSIZE(128);

Целостность данных в порядке, всё ровненько, флаги окончания установлены sm.gif
sonycman
По поводу мультисекторной записи - в примерах в мануале обрабатываются три флага готовности: окончание обработки цепочки буферов DMA CBTC, проверка FIFO на пусто FIFOEMPTY и XFRDONE.
Думается, про фифо это совершенно лишнее?
Зачем ждать его опустошения, когда есть флаг XFRDONE?
aaarrr
Мутный момент. Я смотрю DMADONE при чтении и BLKE при записи.

XFRDONE относится к командам, а не к данным.
sonycman
Цитата(aaarrr @ Dec 22 2011, 16:14) *
XFRDONE относится к командам, а не к данным.

Разве к командам?
Это комплексный флаг, который сбрасывается при подаче команды и устанавливается только после того, как все данные прошли и выставился NOTBUSY.
Если верить мануалу sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.