Подключение плис к ethernet

Обновлено: 02.07.2024

Тем кто не знаком с основами лучше посмотреть предыдущую статью . Мы начинаем.

Проектирование передатчика

В состоянии ожидания на линии должна быть единица. Как только есть потребность в передаче двоичного слова, то на линию необходимо выставить стартовый бит с нулевым значением. Длительность этого бита определяется скоростью передачи информации. По предварительной договоренности пусть это будет 9600 бит в секунду. Чтобы определить сколько тактов кварцевого генератора нужно ожидать окончания передачи бита, разделим частоту генератора 50 миллионов импульсов в секунду на 9600 и получим около 5208 импульсов в одном бите. Ровно столько импульсов будет необходимо поддерживать уровень сигнала пока передается один бит. Конечно же это не идеальный расчет. Нацело поделить нельзя, но такая погрешность вполне допустима, так как фрейм довольно короткий и к его концу ошибка не успеет накопиться.

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

Автомат состояний

Граф автомата состояний будет выглядеть следующим образом.

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

Пишем код

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

Перечислим все состояния автомата: ожидание, старт бит, данные, стоп бит.

Делитель счетчика это число 5208 . Оно обеспечит нужную скорость передачи бит. В регистрах state и nextState будут храниться текущее и следующее состояние автомата.

Обнулим начальные значения регистров.

По переднему фронту тактового сигнала clk присваиваем текущему состоянию автомата state следующее состояние nextState . В состоянии ожидания Idle выставляем на линию передачи tx единицу. Если данные готовы к передаче, то переходим в состояние отправки стартового бита StartBit . Иначе остаемся в ожидании. В состоянии передачи стартового бита, на линию выставляем ноль и считаем импульсы. Если досчитали до нужного количества Divider , то следующее состояние будет передача бит данных DataBit и обнуляем счетчик импульсов. Пока не досчитали остаемся в этом состоянии. При передаче бит данных продолжаем ожидать временные интервалы отсчитывая импульсы. Если посчитали сколько нужно, сбрасываем счетчик и начинаем отсчитывать информационные биты bitCount . Как только их будет 8, следующее состояние StopBit . Сбросим счетчик бит. Если импульсы пришли еще не в полном количестве, то на линии передачи удерживаем бит данных. Порядок отправки от младших к старшим. Счетчик bitCount как раз помогает взять со входной шины данных нужный бит.

В состоянии StopBit выставляем на линию данных tx единицу. Сигнал о готовности к новой передаче данных выставляем в единицу и считаем импульсы для того, чтобы выдержать необходимую длину бита. Как только подождали окончания, следующим состоянием будет ожидание Idle . Сбрасываем счетчик импульсов.

Сразу напишем тестовый модуль. У него нет ни входов ни выходов. Внутри регистры и провода для связи с разработанным модулем передачи данных.

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



Часовой пояс: UTC + 3 часа

Ethernet PHY и какой-нибудь Cortex

Всем добра.
Вообщем, как обычно, есть тупая идея сделать одну штуку, и это штука следующая.
Есть FPGA от Altera (Cyclone V либо Arria II) которую надо подключить к Ethernet на 100 МБит/с. Казалось бы просто, берешь микросхему, реализующий физический уровень Ethernet, подключаешь её к ПЛИС и используешь удобный параллельный (либо какой другой) выход микросхемы физического уровня.
Но тут задачка немного интересней. Хочу эту микросхему физического уровня заменить микроконтроллером на каком-нибудь Cortex, и на нём реализовать свой PHY с программистками и светодиодами , который помимо того, что соединяет ПЛИС через Ethenet с внешним миром, ещё и делает для неё всякие сюрпризы (например, сбрасывает её, или меняет в загрузочной флешке прошивку).
Сначала, как родилась эта чудная мысль, почему-то был свято уверен, что у STM32, из его великого множества микроконтроллеров найдётся с Ethernet PHY и в мелком BGA корпусе, но не тут-то было. Все контроллеры от STM32 имеют лишь Ethernet MII, и Ethernet PHY надо вешать отдельно, что для меня неприемлимо, ведь нивелируется чудесная задумка о сюрпризах для ПЛИС
Начал смотреть в сторону других Cortex, и нашёл с Ethernet PHY лишь TM4C1294NCZAD в 212-ногом BGA размером 10х10мм, и он мне не нравиться, что у него между ножками всего 0,5мм, и мои "прямые руки" припаяют его как обычно "хорошо". Чтобы результат был хорошо, а не "хорошо", надо чтобы между ножками было хотя бы 0,8мм, но такие что-то не нашёл.
Для поиска открывал Digikey, вбивал нужные параметры, но находится лишь либо слишком большое (более 15х15мм), либо без Ethrnet PHY. И вообщем, уже немного не в восторге от этой идеи.
Что можете посоветовать из контроллеров? Вообще есть в природе, то, что я ищу? или я хочу невозможного?

P.S. Главные критерии: должен быть Ethernet PHY на 100 МБит/с и мелкий корпус (не более 15х15мм) с шагом ножек >0.8мм. И ядро Cortex.

_________________
Я в о л ш е б н и к

JLCPCB, всего $2 за прототип печатной платы! Цвет - любой!

_________________
Я в о л ш е б н и к

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Подключение платы Марсоход к сети Ethernet

f

Подключение к локальной сети может понадобится для различных задач.
В этой статье хочу рассмотреть самую простую операцию - передачу пакета Ethernet UDP платой Марсоход.

Для начала немного о стандарте Ethernet 10baseT.
Скорость передачи данных в этом режиме - 10Мбит.
Передача и прием данных происходят по двум разным парам кабеля UTP CAT5. В нашем случае понадобится только одна пара, предназначенная для передачи. В разъеме эта пара подключена к ножкам 1, 2. Для того чтобы сообщить хабу или сетевой карте, к которой мы хотим подключить наше устройство, с какой скоростью мы будем передавать данные, существует специальный механизм - "Autonegotiation".
Для скорости 10Мбит нужно с периодичностью 16ms (+/- 8ms) передавать в линию однополярный положительный импульс длительностью от 100 до 200ns. В результате этого на хабе (сетевой карте) должна загореться специальная лампочка, обозначающая, что к нему подключено 10Мбитное устройство.
Метод кодирования данных называется "Manchester". В нем каждый бит передаваемых данных кодируется последовательностью из двух бит несущей частоты. Для передачи "0" используется последовательность "1,0" а для "1" - "0,1". Для реализации такого алгоритма достаточно одного элемента XOR:

Данные передаются младшими битами вперед. Сам пакет должен начинаться со специального 8 - байтного префикса: 55h, 55h, 55h, 55h, 55h, 55h, 55h, D5h. Получается 63 бита - пилот и последний бит - это стартбит. Далее идут уже полезные данные, адрес получателя,отправителя и т.д. Более подробную информацию о различных типах пакетов и их структуре, а также о том, какие пакеты реально "ходят" в вашей локальной сети можно узнать при помощи программы "Ethereal" (Теперь эта программа называется Wireshark).

Заканчивается пакет четырехбайтной контрольной суммой ( CRC32 ).
Кроме того существуют ограничения на минимальную и максимальную длину пакета, минимальная - 60 байт ( без префикса и CRC32 ).

Для практической реализации мы взяли конкретную задачу - контроль, при помощи нашего устройства, платы Марсоход, большого промышленного холодильника, находящегося в отдельно-стоящем здании.

Для подключения к сети, как уже ранее было сказано, нам понадобится всего одна пара. На плате Марсоход мы подключаем ее с пинам DP и DN .

К пинам f0..f5 мы будем подключать шесть датчиков температуры (DS18B20). Об измерении температуры этим датчиком у нас уже была статья.

Кроме того, нужна тактовая частота 10Мгц (меандр). Для ее получения мы установили внешний кварцевый генератор на 80Мгц (можно какой-нибудь другой, из которого, целочисленным делением, можно получить 10Мгц ).

Подключение внешнего генератора к плате Марсоход

Для простоты, чтобы самим не изобретать значения различных полей в пакете, мы взяли за основу реальный пакет, отправленный программкой vdomsg.exe . Эта программка отправляет на IP-адрес, указанный в качестве параметра, тестовую строку.

Воспользовавшись программой Wireshark, мы перенесли все значения в константу C64X8.V - это файл на языке Verilog.

Таким образом, наш посылаемый пакет, до начала UDP-данных, будет всегда одинаковым.

Следующие четыре байта будут нести полезную нагрузку:
0 - Номер опрашиваемого датчика температуры
1 - Состояние кнопок key[3..0] (Для контроля дверей холодильника)
2,3 - Результат измерения температуры одного из датчиков.

Созданый нами проект для платы Марсоход для Altera Quartus II можно взять здесь:

В этом же архиве есть исходный текст программы (MS Visual C++ 6.0) udp-marsohod.exe, которая используется для приема наших пакетов. Там же есть и уже скомпилированные утилиты.

Зашиваем проект программатором Quartus II и приступаем к лабораторным испытаниям:

Для приема пакетов мы использовали программу udp-mаrsohod.exe, которая показывает принятые данные на экране.

Опишу, что тут видно на этом видео.

Первый столбец это номер датчика температуры, от которого пришла информация, пакет UDP. Второй это состояние кнопочек на плате. Видно как поочередно нажимаем кнопочки и приходят числа 8, 4, 2, 1. Следующие два байта - значение температуры. Видно как оно меняется когда к датчику прикасаемся пальцами.

В лабораторных условиях мы опробовали два разных датчика температуры DS18B20 и DS1820. Кроме того, мы пробовали отнести датчик на расстояние 10м от устройства и увеличивали длину сетевого кабеля до 80м - все работает.

О результатах испытаний и эксплуатации на реальном объекте мы сообщим дополнительно.

Сегодня использование устройств на ПЛИС с сетью Ethernet – обычное явление. Особенно если речь идёт о высокоскоростной передачи данных (АЦП/ЦАП с сетевым выходом, обработка видео, «сырца» с радиолокаторов и гидроакустических комплексов, сбора данных с большой сети (решётки датчиков и т.д. и т.п.). Когда я вижу, как люди, покрывшись испариной, пытаются упихать поток отсчётов с квадратурного демодулятора SDR в USB 3.0, мне их становится откровенно жалко. Напомним, наша новая отладочная плата VE-10CL025 имеет встроенный сетевой интерфейс 1 Гбит. В этой статье мы расскажем о передаче ethernet пакетов из FPGA во внешний мир.

Отдельная огромная тема — это на чём это реализовывать. Вариантов несколько, но, в большинстве своём, плисоводы приходят к выводу, что лучший вариант — это «рукопашный».

В начале стоит внешняя «физическая» микросхема (PHY), которая выполняет работу нулевого уровня (если строго следовать модели OSI), т.е. преобразование аналоговых сигналов в цифровые, битовую и кадровую синхронизации. Затем следует MAC-уровень, т.е. всё, начиная от проверки контрольной суммы (КС) пакета до разборки и вытаскивания «полезной нагрузки» из многочисленных IP-протоколов: начиная от TCP, UDP и ARP и заканчивая экзотикой типа H.248.

Для соединения MAC уровня и PHY обычно используется один из интерфейсов.

MII- Media Independent Interface.

pic2

MII (Media Independent Interface — независящий от среды передачи интерфейс) — стандартизованный интерфейс для подключения MAC-блока сети Fast Ethernet к блоку PHY. Интерфейс MII может быть выведен на разъём для подключения внешнего приемопередатчика или может просто соединять две микросхемы на одной печатной плате. Независимость от среды передачи означает, что существует возможность использования любых PHY-устройств без необходимости смены или переработки аппаратуры MAC-блока. Интерфейс MII состоит из двух частей: канала приема-передачи данных (MII) и служебного канала управления (MDIO и MDC). Все операции интерфейса MII выполняются в синхронном режиме.

GMII- Gigabit Media-Independent Interface.

pic2

GMII (Gigabit Media-Independent Interface) — расширение стандарта MII (Media Independent Interface — независимый от среды передачи интерфейс) для гигабитных Ethernet-интерфейсов, обеспечивающий передачу данных между устройствами, реализующими подуровень Media Access Control (MAC) канального уровня с устройствами, реализующими физический уровень (PHY) модели OSI (например, как с оптическими интерфейсами 1000BASE-*X стандарта 802.3z, так и с медными интерфейсами 1000BASE-T* стандарта 802.3ab). GMII обеспечивает работу на скоростях до 1000 Мбит с использованием восьмибитного интерфейса с тактовой частотой 125 МГц и является обратно совместимым с MII, поддерживая работу на скоростях 10/100 Мбит в соответствии со спецификацией MII. Определён (как и MII) в рамках стандарта IEEE 802.3[1].

RMII- Reduced Media Independent Interface.

pic2

RMII (Reduced Media Independent Interface — сокращенный независящий от среды передачи интерфейс) представляет собой стандартизованный интерфейс использующий сокращенный набор сигналов интерфейса RMII применяется для подключения MAC-блока сети FastEthernet к блоку PHY. Разрядность шин RXD и TXD сокращается вдвое по сравнению с MII, но соответственно вдвое поднимается частота синхронизации MAC. Такое решение позволяет упростить конструкцию печатной платы и сократить количество используемых выводов микроконтроллера. В ряде случаев возможно использовать единую частоту синхронизации для MAC и PHY. Интерфейс RMII имеет сокращенный набор сигналов и полностью совместим с IEEE 802.3u. Он позволяет работать в режимах 10 и 100 Мбит/c, имеет частоту синхронизации 50 МГц.

RGMII- Reduce Gigabit Media Independent Interface.

pic

RGMII (Reduce Gigabit Media Independent Interface) — улучшенный интерфейс GMII указывает конкретный интерфейс между Ethernet MAC и PHY. RGMII использует половину цепей, используемых в GMII интерфейсе. Это сокращение достигается за счет синхронизации данных как по фронту, так и по спаду клока в режиме 1000 Мбит/с, а также путём устранения несущественных сигналов (несущей и индикации). Таким образом RGMII состоит только из следующих цепей: RX_CTL, RXC, RXD [3:0], TX_CTL, TXC, TXD [3:0] (12 контактов, в отличие от GMII).

SGMII- Serial Gigabit Media Independent Interface.

pic2

SGMII — это последовательный интерфейс, который хорош тем, что ему требуется всего одна пара проводов (в одну сторону, есс-но дифференциальных, конкретнее — LVDS), если работа идёт без опорного генератора. А огромный минус его в том, что работа идёт на частоте аж 625МГц по обоим фронтам. Далее этот поток (если речь о приёме) следует преобразовать в параллельный код.

SGMII — это последовательный интерфейс, который хорош тем, что ему требуется всего одна пара проводов (в одну сторону, есс-но дифференциальных, конкретнее — LVDS), если работа идёт без опорного генератора. А огромный минус его в том, что работа идёт на частоте аж 625МГц по обоим фронтам. Далее этот поток (если речь о приёме) следует преобразовать в параллельный код. В принципе, топовые микросхемы, типа того же Stratix'а IV и V с максимальными суффиксами в состоянии выполнить такое преобразование «на себе», т.е. на схеме, реализованной на внутреннем массиве логических элементов (ЛЭ). Но, такая схема будет весьма нестабильна (ибо работать будет почти на пределе возможностей, когда, по-сути, цифровая схема превращается в «полу-аналоговую» и всё, что показывают имитаторы типа Modelsim'а — никакого отношения к действительности не имеет), да и ставить мегадорогущие каменюги ради стыковки с PHY — не очень серьёзно. Поэтому, во многие ПЛИСины втискивают аппаратные приёмопередатчики SGMII. Но настройка этих блоков — отдельная и непростая штука. Кроме того, нужно помнить про сложности разводки печатной платы, ибо даже исходная частота (625МГц), мягко говоря, не детская, а с учётом требований к фронтам и спадам (типично, максимум — 0,2нС) — можете легко посчитать требуемую широкополосность линий. Поэтому, мой совет — с SGMII связываться только в крайнем случае!

Гораздо проще ситуация с GMII и RGMII-интерфейсами. Это — параллельные (8 и 4, соответственно) линии связи. Тактовая частота снижена до разумных 125МГц, хотя даже такая частота может представлять определённую проблему для дешёвых вариантов современных ПЛИС, особенно если нужно «выжать» всё, что можно из 1Гбит-интерфейса и, соотвественно, пакеты должны формироватся «на лету». Поскольку, для RGMII-интерфейса при тактировании по одному фронту понадобилась бы тактовая частота в 250МГц (что уже совсем тяжеловато для большинства современных ПЛИС), здесь также производится тактирование по фронту и спаду тактового сигнала.

pic2

Если очень страшно связываться с двойным тактированием, то можно использовать GMII-интерфейс и тут, фактически, разработчик почти спокойно может использовать наработки, взятые из MII-интерфейса, разве что не забыв, что по GMII передаются байты, а не полубайты(нибблы) и, есс-но, подняв скорость передачи в 5 раз.

Но лишние выводы в современных ПЛИС'инах весьма дороги и RGMII-интерфейс предоставляет возможность разумной экономии (между GMII и SGMII) ценой некоторого (на самом деле, небольшого) усложнения схемы. И, кстати, если ваше устройство должно иметь возможность работать и с 1Гбит и с 100Мбит-устройствами, то, на самом деле, наиболее простой переход с MII обеспечивает RGMII.

Как стыковать RGMII с ПЛИС. Достаточно просто. Теоретически двухтактный буфер можно создать в основном массиве ЛЭ, используя (лучше всего) графику, или поизвращавшись (вообще, убогость этих языков — отдельная тема) в VHDL или Verilog'е (не забыв указать *useioff* у соответствующих выводов). Но, как показала практика, работать это всё будет весьма убого (ибо, с учётом требований к крутизне фронтов, широкополосность должна достигать 400 МГц!), правда, даст подсмотреть генирируемые сигнал в SignalTap (ChipScope).

Более правильный путь — использовать специализированные двухтриггерные буфера, например, в альтеровском случае — это ALTDDIO в соответствии с документом AN477 «Designing RGMII Interfaces».

pic2

На языке Verilog реализация передатчика 1 Gbit ethernet, с выходными буферами и передоваемым пакетом выглядит так:

А так выглядит графическое представление передатчика:

pic2

Строб пакета tx_en, как показывает практика, лучше тоже протаскивать через ALTDDIO (что и сделано под именем dataout[4]).

Показанная схема будет работать только при условии, что тактовая частота gtx_clk сдвигается на 90 градусов на внутреннем ФАПЧ микросхемы PHY (см. выше диаграмку с RGMII-сигналами). Такая весьма удобная опция предусмотрена в большинстве 1Гбит-PHY, но она включается в соответствующем регистре через MDIO. Например, для 88E1111 — это бит 1 регистра 20. Если же MDIO-приёмопередатчик писать лень, то тогда сдвинутую последовательность нужно сгенерить в ПЛИС с помощью ФАПЧ(PLL) и подать её на выход GTX_CLK. К сожалению, такой вариант часто не обеспечивает нужной стабильности и приводит к редким пропаданием отдельных пакетов.

Для работы блока Ethernet PHY нужна высокоточная частота тактирования 25МГц. Как правило, для этого используется отдельный генератор HSE2, запускаемый от внешнего резонатора на 25МГц. Дело в том, что внутренняя PLL имеет недопустимый по стандарту Ethernet джиттер, поэтому ее нельзя использовать для получения точной частоты. По этой причине со второй ревизии микроконтроллера 1986ВЕ1Т реализован отдельный генератор HSE2.

Второй вариант - использовать вместо резонатора внешний генератор на 25МГц, подключенный ко входу OSC_IN. В данном случае в HSE необходимо включить режим ByPass, при котором внутренний генератор HSE не работает, а лишь пропускает входную частоту. Таким образом, на выходе HSE будут необходимые стабильные 25МГц для PHY. Но на вход PLL можно подавать частоту от 2МГц до 16МГц, поэтому необходимо включить делитель на 2. Теперь на выходе мультиплексора CPU_C1 получится частота 25МГц/2, что уже вписывается в условие < 16МГц.

Резонатор 25МГц на вход HSE (вместо генератора) подключать нельзя, потому что внутренний генератор HSE формирует выходную частоту в диапазоне 2-16МГц. А поскольку генератор не умеет делить/умножать частоту, а только делает из синусоидального сигнала прямоугольные импульсы, то это означает, что на вход HSE можно подключать резонатор с теми же частотами 2-16МГц. Для тактирования PHY и ядра от HSE можно использовать только внешний генератор!

На самом деле частота 25 МГц - это частота, на которой передаются данные между блоками MAC и PHY в режиме 100 Мбит/c. Данные передаются по интерфейсу MII.

(В 1986ВЕ8Т блок PHY отличается от остальных - Особенности блока PHY в 1986ВЕ8Т)

Буферы приема и передачи

Для обработки пакетов Ethernet выделена память размером 8Кбайт. Это отдельная память в блоке периферии, а не часть ОЗУ ядра.

Регистр Delimeter делит эту память на два буфера - буфер входных данных и буфер выходных данных. В зависимости от того, чего ожидается больше - входных или выходных данных, можно поделить общую память в необходимой пропорции. Например, если в рассматриваемой задаче выходных данных генерируется много больше чем входных, то имеет смысл выделить больше памяти для передатчика, то есть выставить регистр Delimeter не в середину (0х1000), а в меньшее значение, например Delimeter = 0х800.

Буферы являются кольцевыми, поэтому для считывания и записи данных в каждый буфер выделено по два регистра Head и Tail, отдельные для приемника и передатчика. Head - указывает на начало действительных данных, Tail - на конец действительных данных. Соответственно регистры R_Head и R_Tail могут принимать значения [0 .. Delimeter-1], а регистры X_Head и X_Tail - [Delimeter .. 0x2000]. Данные регистры необходимы для "ручного" управления данными в буферах в линейном режиме. На рисунке 1 представлен схематичный вид буферов Ethernet.


На рисунке 2 изображена передача шести кадров с увеличивающейся длиной в 1986ВЕ8Т в режиме КЗ, то есть блок МАС принимает то, что сам посылает. Блок Phy в обмене не участвует. В Payload в первых 4-х байтах передается индекс кадра. В последние два байта записан импровизированный маркер длины пакета - по нему удобно отслеживать конец данных.


Рисунок 2 - Передача шести кадров в режиме КЗ на примере микроконтроллера 1986ВЕ8Т

Режимы работы буферов

В микроконтроллерах в блоке Ethernet реализовано три режима работы буферов - линейный, автоматический и FIFO.

В линейном режиме регистры R_Tail и X_Head изменяются аппаратно при приеме и передаче данных с линии, программист же должен модифицировать регистры R_Head и X_Tail. R_Head - при чтении из буфера полученных данных, X_Tail - при записи в буфер пакетов на отправку.

В автоматическом режиме происходит все тоже самое, только модифицировать регистры R_Head и X_Tail не надо. Они изменяются автоматически при чтении слова входных данных и при записи слова данных на отправку соответственно.

В режиме FIFO считывание входных данных происходит через чтение адреса 0х0000, отправка же через запись в адрес 0х0004. В SPL для ускорения работы с данными в этом режиме используется DMA. Регистры R_Head и X_Tail здесь не участвуют.

Следует отметить, что в случае, когда есть необходимость пропускать считывание из буфера входного пакета целиком, следует использовать линейный режим работы буферов. Только в нем есть возможность переместить указатель R_Head сразу за конец текущего пакета.

В SPL реализованы функции, которые инкапсулируют в себе работу с буферами во всех режимах. Изучение их реализации поможет в большем понимании принципов работы с буферами.

void ETH_SendFrame(MDR_ETHERNET_TypeDef * ETHERNETx, uint32_t * ptr_OutputBuffer, uint32_t BufLen);
uint32_t ETH_ReceivedFrame(MDR_ETHERNET_TypeDef * ETHERNETx, uint32_t * ptr_InputBuffer);

Отправка пакета

Для отправки пакета необходимо записать его в буфер передатчика.

Первым 32-х битным словом необходимо записать "Поле управления передачей пакета". В этом поле указывается длина пакета в байтах. Когда передатчик считывает это слово, он понимает, сколько последующих байт относится к данному пакету и должно быть передано. Данное слово должно располагаться по выровненному 32-битному адресу. После указания длины пакета в буфер записывается сам пакет обозначенной длины. В линейном режиме после записи пакета необходимо выставить указатель X_Tail на адрес, следующий за статусным словом (пункт 3). При передаче каждого слова передатчик перемещает указатель X_Head. После того, как передатчик осуществит посылку пакета в следующий выровненный 32-битный адрес, он запишет статус передачи пакета. Выставляется флаг прерывания от передатчика.

Далее передатчик читает длину следующего пакета и так далее по циклу, пока не дойдет до указателя X_Tail. Если X_Head = X_Tail, то это значит, что действительных данных для пересылки больше нет. Теперь передатчик ждет, пока программа не положит в буфер новый пакет, после чего работа возобновится.

Прием пакета

Приемник принимает пакет с линии и записывает его в буфер.

Первым 32-битным выровненным словом записывается "Поле состояния приема пакета". Это поле содержит биты статуса приема и длину пакета в байтах.

Со стороны приемопередатчика работа с буфером и регистрами всегда одинакова. Разница в режимах (линейный, автоматический и FIFO) сказывается только при обращении к буферу из ядра.

Когда данные принимаются с линии, они записываться в буфер приемника, начиная с указателя R_Tail. После приема заголовка с МАС адресами приемник проверяет, надо ли дальше принимать данные. Если прием чужих, широковещательных и т.д. типов пакетов выключен, то дальше данные не записываются. Все это время R_Tail стоит на месте. Если МАС адреса данных соответствуют принимаемым, то данные с линии сохраняются в буфер дальше. После приема всех данных проверяется CRC, и если пакет битый, а при этом установлена опция не принимать битые пакеты, то принятые данные опять игнорируются и R_Tail остается на месте. Если же пакет засчитывается принятым, то в поле приема пакета (адрес которого как раз содержится в R_Tail) записывается статусная информация, а в регистр R_Tail записывается адрес следующей свободной ячейки в буфере приема.

Поэтому неравенство R_Tail и R_Head говорит о том, что в буфере есть данные для считывания и пользовательская программа может с ними работать.

Подключение

Для подключения друг к другу двух микроконтроллеров необходимо использовать кабель Crossover. В этом кабеле пины выходного сигнала с одной стороны идут к входным пинам с другой стороны.

При подключении к PC можно использовать любой кабель, поскольку сетевые карточки, как правило, поддерживают режим Auto-MDI(X). При этом выводы на PC автоматически подстроятся на прием или выдачу сигнала.

При подключении двух устройств происходит процедура автосогласования (Autonegotiation) скорости обмена и дуплекса. Микроконтроллеры Миландр поддерживают скорости обмена 10Мбит/сек и 100Мбит/сек (Fast Ethernet). В режиме полудуплекса используется один кабель и обмен происходит то в одну сторону, то в другую - микроконтроллер, то передает, то принимает данные. В полнодуплексном режиме прием и передача идут одновременно - каждый по своему кабелю. При автосогласовании выбирается режим, который поддерживают оба устройства и который обеспечивает максимальную скорость обмена. Приоритеты выбора режимов такие:

Процедура Autonegotiation не является обязательной и ее можно отключить. В таком случае режим обмена должен быть выбран одинаковым в обоих подключенных устройствах. Делается это в регистре PHY_Control.

После записи бит в регистр PHY_Control (addr=0х34), например после смены поля Mode, необходимо выполнить сброс блока PHY. Тогда значения бит из регистра PHY_Control пропишутся в регистры самого блока PHY. Т.е. в такие регистры, как "Основной регистр управления (0)" и прочие, где в столбце "Значения по умолчанию" для полей указано PHY_CTRL.

Также в блоке PHY есть регистры, значения которых влияют на процесс выбора скорости и дуплекса. Доступ к этим расширенным регистрам осуществляется через интерфейс MDIO.

Интерфейс MDIO

Контроллер Ethernet состоит из двух частей блока MAC и блока PHY. Обмен данными между этими блоками происходит по интерфейсу MII. Настройка же блока PHY производится по интерфейсу MDIO.

По стандарту интерфейс MDIO позволяет адресовать до 31-го PHY устройства. Это обусловлено тем, что в обмене используется поле PHY_ADDR, который имеет ширину 5 бит. 0-й адрес является широковещательным, а остальные 31 - это адреса конкретного блока PHY. Соответственно, для работы с блоком PHY необходимо в регистре PHY_Control задать поле PHYADDR[15..11]. И затем именно этот адрес необходимо указывать в транзакциях по MDIO. В библиотеке SPL в функции ETH_StructInit() поле PHYADDR задается равным 0x1C, но значение может быть любым другим (ненулевым).

Для работы с MDIO используются два регистра:

MDIO_DATA - регистр данных для чтения и записи регистров PHY.

Именно в регистре MDIO_CTRL указывается PHY_ADDR для выбора блока PHY, с которым будет происходить обмен данными через регистр MDIO_DATA. В этом же регистре MDIO_CTRL указывается адрес внутреннего регистра PHY, текущая операция - чтение или запись, а также частота обмена и прочее. Подробно биты расписаны в спецификации. В SPL(pack) работа с MDIO реализована в функциях:

uint32_t ETH_WritePHYRegister(MDR_ETHERNET_TypeDef * ETHERNETx, uint16_t PHYAddress, uint16_t PHYReg, uint16_t PHYValue);
uint16_t ETH_ReadPHYRegister(MDR_ETHERNET_TypeDef * ETHERNETx, uint16_t PHYAddress, uint16_t PHYReg);

К примеру, вот как можно выключить подключение на скорости 100Мбит/сек при Autonegotiation. Функция сбрасывает биты 7 и 8 в "Регистре рекомендации автоподстройки (4)". После вызова данной функции МК будет подключаться к PC на скорости 10Мбит/сек.

void PHY_100TX_Disable(void)
volatile uint32_t regValue = ETH_ReadPHYRegister(MDR_ETHERNET1, ETH_PHY_ADDR, 4);
regValue &=

(3 << 7);
ETH_WritePHYRegister(MDR_ETHERNET1, ETH_PHY_ADDR, 4, regValue);
>

Бит G_CFGh.EXT_EN

Бит EXT_EN регистра G_CFGl определен в спецификации как "Включение режима дополнения коротких пакетов до размера SlotTime полем Extension".

Данный бит выставлен в регистре G_CFGl после Reset и предназначен для борьбы с коллизиями в Half Duplex режиме.

Время канала ST (slot time)- это минимальное время, в течении которого узел обязан вести передачу, занимать канал. Это время соответствует передаче кадра минимально допустимого размера, принятого стандартом Ethernet IEEE 802.3. Время канала связано с максимальным допустимым расстоянием между узлами сети - диаметром коллизионного домена.

При работе в Full Duplex необходимости в данном бите нет. Поэтому для работы в современных сетях данный бит необходимо сбросить.

По факту, при EXT_EN = 1 в конец пакета, отправляемого микроконтроллером, приписывается 10 дополнительных байт. Это происходит в любом случае - меньше ли отправляемый пакет минимального размера в 64 байта или больше.

Особенности блока PHY в 1986ВЕ8Т

Стоит отметить, что встроенный блок PHY в микроконтроллере 1986ВЕ8Т отличается от блоков PHY в микроконтроллерах 1986ВЕ1Т, 1986ВЕ3Т. К тому же он позволяет работать только на скорости 10 Мбит/c. Для работы на больших частотах к блоку MAC можно подключить внешний PHY.

Чтобы правильно запустить PHY необходимо выполнить следующие действия:

1. сбросить блок в регистре PHY_CONTROL в 15 бит записать лог 1;

2. произвести настройку, записав значения в регистры блока;

3. запустить работу блока, сбросив лог 1 в 15 бите регистра PHY_CONTROL.

(При тактировании блока частотой 80 МГц, необходимо использовать значение поля LINK_PERIOD=0x8).

Таким образом, тактировать блок Ethernet PHY микроконтроллеров 1986ВЕ1Т, 1986ВЕ3Т необходимо внешней стабильной частотой 25МГц . Для тактирования внутреннего PHY в 1986ВЕ8Т необходима внешняя стабильная частота 80МГц .

Толкование регистров

Согласно пункту 30.10 "Режим детерминированного времени доставки" спецификации на микроконтроллер 1986ВЕ1Т пакеты могут передаваться в привязке к отсчетам времени (с периодом BAG при DTRM_EN = 1). То есть, если передатчик успевает в окно JitterWnd начать передачу, то он ее начинает. Если не успевает, то ожидает следующего отсчета периода BAG. BAG и JitterWnd выражаются в квантах времени, которые задаются из ETH_Clock делителем PSC.

1/TimeStep = ETH_Clock / (PSC + 1), что согласуется с 1мкс для 50МГц из спецификации.

IPG - межпакетный интервал и в соответствии с IEEE802.3 должен составлять 96 битовых интервалов.

Читайте также: