|
|
  |
Atmel SAM3U4, Различные вопросы |
|
|
|
Dec 15 2011, 10:55
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Dec 15 2011, 14:43)  но никакого эффекта...  Что делать - то? Странно, проверка NOTBUSY у меня вполне себе работает. Цитата(sonycman @ Dec 15 2011, 14:43)  Похоже, повторяется ситуация, как с командой ACMD41 - флаг NOTBUSY устанавливается мгновенно с CMDRDY... ACMD41 - это особый случай, и там совсем другой "busy". Кстати, взвода CMDRDY перед проверкой NOTBUSY дожидаетесь? Цитата(sonycman @ Dec 15 2011, 14:43)  ЗЫ: если ждать нужно ручками - зачем тогда вообще ввели специальный тип команды с ответом R1b? Толку то нет. Потому что в противном случае контроллер возможно даже смотреть не будет busy status.
|
|
|
|
|
Dec 15 2011, 11:00
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(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...
|
|
|
|
|
Dec 15 2011, 11:19
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Dec 15 2011, 15:14)  Ну, на CMD7(DESELECT) ответа и не должно быть.
Сдается мне, все правильно: повторная передача CMD7 переводит карту назад в stand-by, ответа и не должно быть. Да, спасибо, сейчас попробую отправить вслед за CMD7 другую команду. Действительно, с CMD7 всё не так просто - судя по спецификации на эту команду карта отвечает только при переходе с STBY на TRAN. ЗЫ: отправил следом ACMD51 - всё в порядке, ошибок нет  Впрочем, ошибок нет, даже если совсем убрать ожидание NOTBUSY. То ли это из-за низкой скорости интерфейса (работает пока на паре мегагерц, в отладочных соображениях), и карта успевает отпустить линию данных, то ли всё же контроллер отслеживает статус автоматически...
|
|
|
|
|
Dec 15 2011, 15:05
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Ну вот, вроде сделал чтение сектора, теперь надо бы DMA подключать. В даташите на этот счёт всё довольно мутно - какие-то дескрипторы, выравнивание по WORD и прочие грустные штуки  Мне бы организовать чтение\запись по произвольному адресу в памяти и с произвольным кол-вом секторов. Может ли DMAC выполнять чтение\запись памяти по произвольному адресу, а не только по выровненному до слова? Вроде бы есть поля в регистрах, этому сопутствующие. С дескрипторами так и не пойму, допустим, надо мне прочесть с карты памяти 32 сектора последовательно в память, неужели для этого придётся создавать в памяти 32 дескриптора? Можно ли обойтись одним так, чтобы чтение 32 секторов выполнялось за один раз, или придётся 32 раза перепрограммировать DMA (на каждый сектор)? Судя по описанию в даташите, придётся возиться с каждым сектором
|
|
|
|
|
Dec 15 2011, 16:15
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(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, лишь бы данные шли.
|
|
|
|
|
Dec 15 2011, 18:59
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(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, лишь бы данные шли. В общем, буду пробовать
|
|
|
|
|
Dec 15 2011, 19:10
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(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 одинаково.
|
|
|
|
|
Dec 15 2011, 19:22
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(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 это замедлит. Ну, к примеру, если я захочу записать пару килобайт данных, пусть даже выровненных в памяти, в файл с произвольным смещением от его начала (не нулевым), то это будет как работать? Сначала в буфер файловой системы считается первый сектор, в который частично попадают эти данные, в него копируется их кусок, затем этот сектор записывается. Далее уже идёт прямая запись в сектора из памяти с абсолютно произвольного по выравниванию места, которое будет зависеть от начального смещения по файлу...
|
|
|
|
|
Dec 15 2011, 20:30
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(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, но он, как я понимаю, действителен только для записи.
|
|
|
|
|
Dec 16 2011, 01:41
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(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 дескрипторах, знать бы ещё, насколько загружена получается внутренняя шина...
|
|
|
|
|
Dec 16 2011, 02:08
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Dec 16 2011, 05:41)  Почему так сделано, интересно? Надо полагать, для ускорения всего и вся  Вполне возможно, что этому процессору оно и не нужно, но ведь 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, который и указывает, сколько байт нужно проигнорировать. А вот с чтением, похоже, остается только байтовый доступ.
|
|
|
|
|
Dec 16 2011, 06:46
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Dec 16 2011, 06:08)  Так нельзя: контроллер HSMCI ждет на входе 32 бита и никак иначе. Не получится ему три байта скормить, кроме как через OFFSET, который и указывает, сколько байт нужно проигнорировать. А вот с чтением, похоже, остается только байтовый доступ. Да, с записью, оказывается, все много проще, задать offset и дело в шляпе  Странно, что для чтения не предусмотрели такую фичу вместо сомнительного ROPT... Интересно, а как себя поведет DMA при возникновении ошибки, к примеру, при чтении, если карта не отдаст количество данных, на которые он запрограммирован? Повиснет?
|
|
|
|
|
Dec 16 2011, 20:47
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Dec 16 2011, 10:46)  Интересно, а как себя поведет DMA при возникновении ошибки, к примеру, при чтении, если карта не отдаст количество данных, на которые он запрограммирован? Повиснет? Карта не отдать просто не сможет: хост подает клок и снимает данные вне зависимости от того, что думает карта. Другое дело, что в таком случае появится ошибка CRC, но DMA об этом и не узнает.
|
|
|
|
|
Dec 17 2011, 01:39
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Dec 17 2011, 00:47)  Карта не отдать просто не сможет: хост подает клок и снимает данные вне зависимости от того, что думает карта. Другое дело, что в таком случае появится ошибка CRC, но DMA об этом и не узнает. Ну как же - есть же Start Bit, есть специальные токены начала данных (по крайней мере в режиме SPI были), то есть хост может определить момент появления данных. К примеру, если после команд чтения данных не ждать установки флага NOTBUSY и сразу попытаться подавать следующую команду - получаем зависон на циклическом опросе флага AT_MCI_RXRDY, который никогда уже не установится - карточка-то молчит. Или просто попробовать прочитать больше данных, чем карта отдаёт - скажем, вместо 8 байт команды ACMD51 попытаться прочесть 9 - аналогичный зависон... То есть хост определяет, отдаёт карта данные, или нет с точностью до байта. Но это касается работы без DMA, с ним, возможно, будет несколько иначе... PS: хотя бог знает, может просто я чего нибудь напутал...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|