Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AT91SAM9260 и работа SMC в режиме Null Setup & Hold
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
-=Alexey=-
Спрашивал уже в ветке для начинающих, но с ответом пока глухо. Поэтому, да простят меня модераторы, задам вопрос здесь.

Контроллер SMC настроен с параметрами
PULSE = 0x03030202
SETUP = 0x00000000
CYCLE = 0x00030002
MODE = 0x00001003

MCK = 100 MHz
По 16-битной шине подсоединена FPGA. В ней смотрю что приходит на момент спада NWE и на момент, когда должно приходить 2е слово.

Если использовать хотябы 1 hold в цикле записи, то все работает нормально. Проблема именно с режимом Null Setup & Hold.
В Standalone приложении выполняю
STR R0, [R1]
, где в R0 хранится 0хDDCCBBAA, R1 - 0x1000 0000
В итоге по идее должно формироваться 2 запроса к адресам 0x1000 0000 и 0x1000 0002 и значением на шине данных 0хBBAA и 0хDDCC соответственно (так в общем то и происходит при hold отличном от нуля). По факту же считанные значения на момент спада NWE и на момент, когда должно приходить 2е слово, не отличаются и равны 0хBBAA. Подумал - может где задержки не учел. Считывал значение на 5 и 10 нс позже прихода 2го слова - результат рандомный.

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

На последок скажу, что FPGA работает на 200 МГц, все действия по борьбе с метастабильностью предприняты, да и результаты измерений не отличаются ни на 2й, ни на 10 раз.
aaarrr
Два вопроса по делу и один общефилософского плана:
1. А что показывает осциллограф?
2. Какой механизм используется в FPGA для разделения запросов?
3. Что побудило использовать режим Null Setup & Hold?
-=Alexey=-
1) К сожалению осциллографа нет. Тогда бы не пришлось париться с FPGA.
2) Определяется момент перехода NWE из 1 в 0 и соответственно через определенный интервал времени производится считывание с шин последующих слов, если не появился признак перехода NWE из 0 в 1
3) В FPGA планирую реализовать нечно вроде видео-контроллера. Поэтому нужна максимально возможная скорость передачи. Насколько я понял, в ARM'ах нельзя одной инструкцией копировать большие блоки данных (поправьте, если ошибаюсь). Но зато можно инструкцией STMIA сохранять блоки по 48 байт (4*12). Пока планирую реализовать обмен именно таким образом, если ничего лучше не придумаю.
aaarrr
Цитата(-=Alexey=- @ Jul 1 2010, 16:01) *
1) К сожалению осциллографа нет. Тогда бы не пришлось париться с FPGA.

В данной ситуации это весьма печально.

Цитата(-=Alexey=- @ Jul 1 2010, 16:01) *
2) Определяется момент перехода NWE из 1 в 0 и соответственно через определенный интервал времени производится считывание с шин последующих слов, если не появился признак перехода NWE из 0 в 1

ИМХО, очень стремный способ.

Цитата(-=Alexey=- @ Jul 1 2010, 16:01) *
3) В FPGA планирую реализовать нечно вроде видео-контроллера. Поэтому нужна максимально возможная скорость передачи.

Все равно не понимаю: сейчас у Вас длительность цикла стоит 2. Так что мешает поставить SETUP = 1, PULSE = 1, HOLD = 0 и спокойно защелкивать данные по заднему фронту WE?
-=Alexey=-
Цитата(aaarrr @ Jul 1 2010, 16:13) *
В данной ситуации это весьма печально.

Согласен. Но приобретать осцилограф только из-за одного проекта и неизвестно когда его в дальнейшем использовать - не разумно.

Цитата(aaarrr @ Jul 1 2010, 16:13) *
ИМХО, очень стремный способ.

Ну почему же? Проблемы только с тем, что спад/рост NWE из-за метастабильности приходит с точностью +- 1 клок. При PULSE=2 этоне создает никаких проблем.

Цитата(aaarrr @ Jul 1 2010, 16:13) *
Все равно не понимаю: сейчас у Вас длительность цикла стоит 2. Так что мешает поставить SETUP = 1, PULSE = 1, HOLD = 0 и спокойно защелкивать данные по заднему фронту WE?

Дело в том, что в конечном счете будет этот же режим, но с CYCLE=1. В общем то он уже был реализован, но когда столкнулся с вышеописанной ситуацией, пришлось перейти на CYCLE=2. Осциллографа-то нет, а разбираться в чем причина такого поведения лучше на бОльших циклах.

В общем совершенно случайно обнаружил, что при MODE = 0x00001000 режим работает нормально. Это довольно странно, т.к. при Null Setup and Hold какая разница чем управляются операции записи - WE или CS? Они же одновременно должны меняться.
Если у кого есть возможность посмотреть на осциллографе, может посмотрите, в чем может быть дело? Чем отличаются на практике запись, управляемая WE и CS в режиме Null Setup and Hold?
aaarrr
Цитата(-=Alexey=- @ Jul 1 2010, 16:34) *
Согласен. Но приобретать осцилограф только из-за одного проекта и неизвестно когда его в дальнейшем использовать - не разумно.

Можно "на покататься" взять, хотя это тоже не всегда удобно.

Цитата(-=Alexey=- @ Jul 1 2010, 16:34) *
Ну почему же? Проблемы только с тем, что спад/рост NWE из-за метастабильности приходит с точностью +- 1 клок. При PULSE=2 этоне создает никаких проблем.

Так ведь Вы сами пишете ниже, что в дальнейшем планируете выставить CYCLE=1. При 100MHz MCK и 200MHz тактовой FPGA ловить будет практически нечего.

Цитата(-=Alexey=- @ Jul 1 2010, 16:34) *
В общем совершенно случайно обнаружил, что при MODE = 0x00001000 режим работает нормально. Это довольно странно, т.к. при Null Setup and Hold какая разница чем управляются операции записи - WE или CS? Они же одновременно должны меняться.

Ну, одновременно они только на картинке меняются, надо внимательно EBI Timings посмотреть.
-=Alexey=-
Цитата(aaarrr @ Jul 1 2010, 16:53) *
Так ведь Вы сами пишете ниже, что в дальнейшем планируете выставить CYCLE=1. При 100MHz MCK и 200MHz тактовой FPGA ловить будет практически нечего.

Ну если считать что разность фаз клоков процессора и FPGA постоянно, то вроде как не все так печально.

Цитата(aaarrr @ Jul 1 2010, 16:53) *
Ну, одновременно они только на картинке меняются, надо внимательно EBI Timings посмотреть.

Хм... Действительно. Надо порыться. Спасибо за совет.

Кстати, попутно еще 1 вопрос. Если, скажем, SMC сконфигурирован на 1 PULSE и 1 HOLD(CYCLE=2), когда процессор начинает выполнять команду STR(H) он, насколько я понял, приостанавливается до полного ее завершения, так? Т.е. ждет следующего фронта MCK, зате 2 периода MCK выполняет команду вывода и только потом приступает к выполнению следующей команды. Все правильно?
Нет, например, такой возможности, чтобы, скажем, после того как процессор встретил команду вывода, он инициировал работу SMC, а сам стал выполнять другие команды?
Перефразирую вопрос для ясности: нельзя ли заставить процессор НЕ простаивать в ожидании завершения вывода контроллером SMC?
aaarrr
Цитата(-=Alexey=- @ Jul 1 2010, 17:22) *
Ну если считать что разность фаз клоков процессора и FPGA постоянно, то вроде как не все так печально.

Слишком много если получается, как мне кажется. Впрочем, попытка не пытка.

Цитата(-=Alexey=- @ Jul 1 2010, 17:22) *
Нет, например, такой возможности, чтобы, скажем, после того как процессор встретил команду вывода, он инициировал работу SMC, а сам стал выполнять другие команды?
Перефразирую вопрос для ясности: нельзя ли заставить процессор НЕ простаивать в ожидании завершения вывода контроллером SMC?

Уже все сделано - у процессора есть буфер записи на 16 слов.
-=Alexey=-
Цитата(aaarrr @ Jul 1 2010, 17:39) *
Уже все сделано - у процессора есть буфер записи на 16 слов.

Т.е. процессор станет ожидать завершения работы SMC только если в буфере все 16 слов еще не переданы? А можно ссылку на источник - хочется поподробнее узнать.

Я кстати пытался вызвать ассемблерную функцию, где 2 команды подряд - STRH. По результатам замеров FPGA между ними включается как минимум 1 hold, хотя режим - Null Setup and Hold. Т.е. выглядит как раз так, будто процессор подождал конца передачи 1го слова (при этом NWE был переведен в 1), а затем стал дожидаться нового фронта MCK для выполнения 2й команды STRH. Если бы был задействован буфер, то hold'а не вставилось бы, как мне кажется. Может быть названный вами буфер нужно как-то активировать/настраивать?

Сам же отвечу. Даташит, раздел 11.6.2.2.
Только насколько я понял (мельком пробежался) он используется только с включенным кэшем данных. Дело в том, что я еще не до конца прояснил для себя этот момент. Если, скажем, необходимо будет записать 1 пиксель, записанное значение поместиться в буфер и когда оттуда будет передано в FPGA - не понятно. Аналогично с чтением. Регистры FPGA должны читаться без всякой буферизации в кэше.
Т.е. сейчас использование кэша (и соответственно этого буфера?) зависит от того, можно ли его настроить на буферизацию чтения только по определенным адресам (исключить адресное пространство SMC) и настроить запись так, чтобы операция производилась даже при наличии только 1 измененного элемента (видимо надо читать про Write Through и т.п.). К тому же пока открыт вопрос по поводу того, как будет производиться запись при изменении только 1 слова - вся строка кэш передастся или только элементы, помеченные как измененные... В общем куча вопросов
aaarrr
Буфер записи можно использовать и в некэшируемом регионе памяти, но MMU, конечно, придется включить и настроить. Строками данные из кэша в память переносятся только в режиме Write Back, при Write Through каждая запись немедленно уходит в буфер.
Рекомендую почитать ARM926EJ-S Technical Reference Manual, в даташите лишь переложены отдельные моменты из него.
-=Alexey=-
Да, есть такой документ. Спасибо за подсказку.
Честно говоря, настройка MMU меня пугает как человека, ни разу не имевшего с ним дело smile.gif Но, если это действительно позволит задействовать вышеуказанный буфер, то он того стоит.
Кстати, может у вас есть примерчик по настройке MMU для похожего случая?
aaarrr
Цитата(-=Alexey=- @ Jul 1 2010, 18:37) *
Кстати, может у вас есть примерчик по настройке MMU для похожего случая?

Есть:
CODE

; ***************************************************************************
; * Cache and MMU Configuration

[ {TRUE}
mrc p15, 0, r0, c1, c0, 0 ; read CP15 register 1 into r0
bic r0, r0, #0x01 ; clear MMU enable
bic r0, r0, #(0x01 << 0x0c) ; disable I Cache
bic r0, r0, #(0x01 << 0x02) ; disable D Cache
mcr p15, 0, r0, c1, c0, 0 ; write value back

mov r0, #0x00
mcr p15, 0, r0, c7, c7, 0 ; invalidate caches
mcr p15, 0, r0, c8, c7, 0 ; invalidate TLBs


ldr r0, =ttb_first_level ; set start of Translation Table base (16k Boundary)
mcr p15, 0x00, r0, c2, c0, 0x00 ; write to CP15 register 2
;
; Create translation table for flat mapping
; Top 12 bits of VA is pointer into table
; Create 4096 entries from 000xxxxx to fffxxxxx
;
mov r1, #0x00 ; loop counter
ldr r2, =2_110111110010 ; set access permissions (AP) for full access SVC/USR (11:10)
; set for domain 15 (8:5)
; must be 1 (4)
; set non cachable non bufferable (CB) (3:2)
; set for 1Mb section (1:0)
init_ttb0
orr r3, r2, r1, lsl #0x14
ldr r4, =sections
init_ttb1
ldr r5, [r4], #0x04
tst r5, #0x01
bne init_ttb2
cmp r1, r5, lsr #0x14
addlo r4, r4, #0x08
blo init_ttb1
ldr r5, [r4], #0x04
cmp r1, r5, lsr #0x14
addhs r4, r4, #0x04
bhs init_ttb1
ldr r5, [r4]
orr r3, r3, r5
init_ttb2
str r3, [r0, r1, lsl #0x02]
add r1, r1, #0x01
cmp r1, #0x1000
blo init_ttb0
;
; Init domains
;
mov r0, #(2_01 << 0x1e) ; must define behaviour for domain 15 (31:30), set client
mcr p15, 0x00, r0, c3, c0, 0x00 ; write to CP15 register 3
;
; Set global core configurations
;
mrc p15, 0x00, r0, c1, c0, 0x00 ; read CP15 register 1 into r0

orr r0, r0, #(0x01 << 0x0c) ; enable I Cache
orr r0, r0, #(0x01 << 0x02) ; enable D Cache
orr r0, r0, #0x01 ; enable MMU
;
; Additional configuration options
;
; orr r0, r0, #(0x01 << 0x0e) ; enable Round Robin cache replacement
; orr r0, r0, #(0x01 << 0x0d) ; enable Hi Vectors
orr r0, r0, #(0x01 << 0x01) ; enable data address alignment checking

mcr p15, 0x00, r0, c1, c0, 0x00 ; write cp15 register 1
]

; ***************************************************************************
; *

sections
DCD 0x00000000 ; SRAM
DCD 0x00100000
DCD 2_1100 ; wb, buffered

DCD 0x20000000 ; SDRAM
DCD 0x22000000
DCD 2_1100 ; wb, buffered

DCD 0x00000001 ; END

; ***************************************************************************
; *

Вам остается только разместить где-нибудь на границе 16k ttb_first_level и поправить табличку секций под свои нужды.
-=Alexey=-
Огромное спасибо. Буду разбираться.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.