Внешняя шина ArduinoDue (SAM3X)

Все началось с того, когда, пролистывая datasheet контролера Atmel SAM3X, который стоит на небезызвестной плате Arduino Due, я наткнулся на интересную весч.

Ashampoo_Snap_2014.03.03_16h23m13s_007_

 

На тот момент я не стал разбираться, что это такое. Да и вскоре забыл.

Немного позже, я разрабатывал программу для ArduinoDue и мне критически не хватало оперативной памяти для моих нужд.  Я задумал поставить внешнюю с параллельным интерфейсом, но куда ее подключать? — К GPIO? — тогда я и вспомнил про эту штуку.

Заходим на forum.arduino.cc

Ashampoo_Snap_2014.03.03_16h35m31s_008_

 

Опа! 😉 Кто-то уже состряпал библиотеку.

Теория

Что это вообще — «параллельный интерфейс/шина«? В самом простом представлении: куча параллельно идущих проводов, каждый из которых несет бит информации.

Первое — шина данных.

1

 

Шина данных — самое главное, несколько проводников(бит), передающих информацию в двух (или одном) направлении. Количество этих жил будет равно ширине передаваемой единице информации. Если мы хотим передать байт, то это будет восемь проводов. Это также влияет на скорость передачи: мы можем сделать шины шире и передавать сразу несколько байт. Однако, имея только шину данных — мы можем передать устройству одну единицу этой информации.

Второе — шина адреса.

2

 

Шина адреса — грубо говоря, указатель на ячейку, куда мы хотим передать/забрать информацию по шине данных. Обычно она всегда шире, чем шина адреса, так как количество информации, которое мы сможем передать, будет: 2 ^ ШиринаАдреса * ШиринаДанных = .бит. В случае с 16бит шиной адреса и 8бит шиной данных, мы сможем передать 65536байт.

Чтобы точно понять принцип, давайте сократим до 3Bit Адрес и 1Bit Данные. Наглядно:

77

 

Стрелка — селектор, он управляется адресом, позволяя выбрать ячейку, с которой будет происходить работа по шине данных. Ячейка может быть каким-то регистром устройства, в случае с памятью у нас таких ячеек будет огромное количество. Любой параллельной памяти присуща линейность, что уравнивает скорости доступа к ячейкам.

Третье — управляющие сигналы.

3

 

Основные управляющие:

  1. WE -разрешение записи
  2. RE -разрешение чтения
  3. CS0..n -выбор устройства

Все три используют по одному биту. Если WE, то передаем информацию, если RE, то принимаем информацию. CSn — это разрешает взаимодействовать с устройством, что позволяет отключить его от всей шины. Тут у нас происходит разделение на главное устройство (одно) (Master) и ведомое(-ые) (Slave). Что же это дает? — Используя CS управляющие, мы можем подключить несколько устройств по одной шине! 🙂 Но, с каждым устройством — у нас будет уходить по одному пину CS.

4

 

Подобное используется в наших ПК. Данная система не имеет схем шифрования, сжатия — все сделано наиболее просто, а все простое — быстрое, но часто громоздкое. :-\ Скорость передачи будет напрямую зависеть от максимальной частоты I/O устройств. Если она 100MHz, а ширина данных8бит, то получаем 100МегаБайт/сек. 🙂 Таким может похвастаться не каждый HDD.

Устройство внешней шины контроллера

У контроллера ATSAM3X блок управления шиной состоит из нескольких частей.

Ashampoo_Snap_2014.03.13_22h36m36s_001_

 

SMC контроллер дает нам 24бита адреса и 16бит данных. NAND Flash — позволяет подключать флэш nand память, а также дает нам несколько линий CS и разрешения чтения/записи.

ECC — контролирует остальные сигналы.

При всем при этом, весь этот воз подключен к общей шине ЦП, что дает нам возможность обращаться напрямую к внешнему интерфейсу. То есть, мы можем просто послать данные на определенный адрес и он автоматом появится на внешней шине, причем со всеми необходимыми сигналами и установленными задержками. Это очень полезно при подключении доп. ОЗУ: при переполнении родного ОЗУ, данные пойдут на внешнее без участия пользователя.

1
2
3
4
5
uint8_t *addr = (uint8_t*)0x6xxxxxxx;
………
addr[x] = 128; //Отправим на внешнюю шину ячейку x (это ж указатель)
i = addr[x]; //Прочитаем что-то
memcpy(foo, addr, 978); //Или даже пересылки

Изобразить схему работы можно так:

Ashampoo_Snap_2014.03.17_08h21m22s_012_

 

Все задержки между сигналами — условные, тк. у каждого устройства они свои и настраиваются в SMC контроллере.

Максимальная скорость передачи, которую я смог получить (без DMA) = 36МегаБайт/сек, при восьмибитной шине.

Верните наши пины!

Теперь перейдем к основной части: железу. Используем нашу шину по минимуму: 8bit Данные, 16bit Адрес + пара управляющих. Первое, что нужно сделать — сопоставить пины Arduino с выводами SAM3X.

Ashampoo_Snap_2014.03.16_15h33m06s_001_

Теперь появляются проблемы. A6 — вообще никуда не выведен, а это седьмой бит адреса. Ничего не остается как припаять напрямую к микросхеме проводник:

DSCN5497

DSCN5498

C A9 — немного проще, так как он находится на RX светодиоде:

DSCN5499

С RE пином нельзя вообще что-либо сделать, так как он закорочен с A5 где-то на плате под микросхемой. 🙁 Зачем? — без понятия…

Вообще, RE пин — является противоположностью WE, соответственно, на крайний случай, можно поставить инвертор. Однако, во многих устройствах используется только WE: 1 — записываем, 0 — читаем. Так что все не так плохо.

Остальные пины разбросаны по всей плате, их соответствия вы можете найти по картинке:

Due-pinout-WEB

Схема и плата

Следующее действие — разработка платы переходика: пины Arduino -> параллельная шина. Но сперва определитесь, какое устройство вы будете подключать к МК — от этого зависит корректность работы всей передающей линии. Здесь частота ~40MHz, поэтому согласованием линий и средством от помех не следует пренебрегать! Подробнее об этом можно почитать там — /.

Ashampoo_Snap_2014.03.17_18h14m57s_015_

Все выведено на колодки. Я поставил SMD резисторы 89Ом последовательно в линии для уменьшения паразитных характеристик и защитой от КЗ. Вся плата «надевается» на Arduino Due, получается бутерброд.

В качестве устройства, с которым будет работать МК, может выступать микросхема ОЗУ или какая-нибудь флэш память:

Ashampoo_Snap_2014.03.16_18h18m03s_006_Ashampoo_Snap_2014.03.17_08h12m53s_009_

Причем максимальный возможный объем при данной конфигурации: 64кб на каждый CS пин. Могу посоветовать CY7C1019DV33-10ZSXI или IS62WV51216BLL.

Но мы рассмотрим видеопроцессор из этой статьи или просто ПЛИС EMP240. Тип подключения точно такой же как и у ОЗУ.

Концепт:

5

 

Передача данных будет происходить в одну сторону без замудрений: установили адрес, установили данные, записали.

Так как шлейф 90мм, нам не нужно согласовывать линию, но индуктивность/емкость/сопротивление проводников нужно учитывать. Также лучше использовать IDE 80PIN и чередуйте землю/сигнал.

Шлейф2

DSCN5402

DSCN5399

Со стороны ПЛИС ничего особенного нету, шлейф приключается напрямую к EPM240. Конфигурация портов очевидная:

  • ADDRESSINPUT
  • DATAINPUT (HI-Z)
  • WEINPUT

Ashampoo_Snap_2014.03.16_18h52m16s_007_

 

Тест

Во-первых, убедитесь, что вы подключили все пины правильно.

DSCN5501

Во-вторых, попробуйте подать на одну линию меандр с МК. Следите, чтобы на выходе сигнал имел минимально возможное искажение. Не должно быть выбросов, отражений и прочих гадостей.

posle

Иначе — колдуйте с резисторами.

Важное замечание: проверять работу шины нужно осциллографом, так как частоты там высокие, а мультиметор их не поймает. Когда проблемы с железами решены, переходим к программной части.

Идем на arduino.cc и стаскиваем с форума библиотеку ArduinoDueParallel, здесь несколько функций:

  • Parallel.begin(данные, cs, адрес, RE пин, WE пин);

Инициализация. Все вполне понятно, только нужно поставить false у readEnable, тк этот пин закорочен.

  • Parallel.setAddressSetupTiming(циклы до WE, циклы до CS и WE, циклы до RE, циклы до CS и RE);

Здесь нужно смотреть документацию к устройству, которое вы подключаете, у каждого разные задержки. В случае с ПЛИС — почти везде нужно поставить 0. 1цикл = 11ns.

  • Parallel.setPulseTiming(длит. WE, длит. CS WE, длит. RE, длит. CS RE);

То же самое, что и выше.

  • Parallel.setCycleTiming(цикл Записи всего, цикл Чтения всего);
См. документацию на устройство.
  • Parallel.write(адрес, данные);
Запись. Но я советую напрямую писать в область памяти через указатель.
  • uint8_t Paralle.read(адрес);
Тестовый код для видеопроцессора будет таким:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <Parallel.h>
 
uint8_t* gram = (uint8_t*)0×60000000; //Адрес видеопроцессора
 
void setup() {
   Parallel.begin(PARALLEL_BUS_WIDTH_8, PARALLEL_CS_NONE, 16, false, true);
   Parallel.setCycleTiming(1,1);
   Parallel.setPulseTiming(0,0,0,0);
   Parallel.setAddressSetupTiming(0,0,0,0);
}
 
void loop() {
   memset(gram, 255, 57344); //Заполняем весь экран белым
}

В этом примере CS вообще не используетеся, но внешнюю адресацию нужно знать:

Ashampoo_Snap_2014.03.17_08h05m09s_008_

Мы просто создаем указатель на той или иной адрес и работаем как хотим! ЦП принимает их как родную память, только с меньшей скоростью доступа. 🙂

DSCN654

Беленький 🙂

Заключение

Получившееся устройство выглядит так:

Ashampoo_Snap_2014.03.17_08h55m53s_013_

 

Что ж, внешняя параллельная шина весьма полезная весч. Можно вести параллельную обработку информации на нескольких устройствах, подключив ПЛИС, ОЗУ или еще чего-нибудь. Кстати, пересылать данные между двумя устройствами (CS на каждом) можно да же через memcpy, но при этом скорость пересылки падает в ~1.2раза.  🙂

Наконец, все эти SPI, Uart и прочая периферия, подключены к ЦП по принципу идентичному SMC контроллеру с внешней шиной: можно неплохо расширить возможности МК.

Иное возможное использование

1. Параллельный ЦАП или другой преобразователь

6

Я имею ввиду отдать адрес и данные или что-то одно под разряды преобразователя. Глупо, но работать будет 😀

 2. Подключить к FPGA (или CPLD)

8cd611115a7dbe1a37e3ad774cfd1f0a

Применение найти можно.

3. Дополнительные интерфейсы

Ashampoo_Snap_2014.03.17_09h21m55s_014_

Подключить по такому же принципу, как в самом МК подключены все контроллеры. Возможно понадобиться несколько дискретной логики, но это не страшно.

4. Подключить к ISA

Isa1

Тут, конечно, без сторонних компонентов не обойтись.

5. Соединить две Arduino Due!

DSCN5506

Файлы

Вы можите оставить комментарий, или поставить трэкбек со своего сайта.

Написать комментарий

XHTML: Вы можете использовать эти теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Bug Report
Локализовано: шаблоны Wordpress