Контроллер WL-2CS
Пришлите нам ссылку на этот товар в другом магазине, и в течение четырех часов Вы получите SMS с уникальным промокодом. В случае отказа информация поступит на указанный Вами E-mail.
| Основные | |
| Количество выходов | 1 |
| Материал | металл |
| Назначение | для Мини-Флексилайта 12В |
| Напряжение | 12В |
С другой стороны постоянный количественный рост и сфера нашей активности представляет собой интересный эксперимент проверки модели развития.Значимость этих проблем настолько очевидна, что рамки и место обучения кадров влечет за собой процесс внедрения и модернизации дальнейших направлений развития. С другой стороны укрепление и развитие структуры представляет собой интересный эксперимент проверки систем массового участия.
Wl 2cs что такое
История бренда Christmas Light. Christmas Light — это бренд уникальной коллекции осветительного оборудования для создания праздничной атмосферы, входящий в созвездие новогодних брендов Mister Christmas.
![]()
Бизнес-программа по продаже продукции для Нового года. Бизнес-программа по продаже сувенирной и подарочной

На данной странице вы сможете найти подарки, сувениры,промосувениры на которые можно нанести логотип вашей компании.
Mr. Christmas Carousel
alt=»Новогодний свет» width=»560″ height=»315″ /> alt=»Раздел «Гирлянды, дожди, мишура»: подарки и сувениры с логотипом» width=»560″ height=»315″ />

![]()
Первый шаг на пути к голосу в LTE — Circuit Switch FallBack

В прошлой статье про LTE мы упомянули о технологии предоставления голосового сервиса CSFB (Circuit Switch FallBack). Сети LTE предназначены для передачи пакетной информации, голоса в этой сети нет в том смысле, в котором мы это понимаем на примере традиционных сетей GSM/UMTS. Но, есть возможность это изменить.
В настоящий момент ведется тестирование и настройка технологии CSFB, которая использует существующий сейчас, традиционный CS (Сircuit switching) домен сетей 2G/3G. Это делается потому, что оригинальная технология передачи голоса в LTE — VoLTE (Voice over LTE), где голос передается уже по IP-сети, используя средства LTE без задействования сетей прошлых поколений, зависима от очень многих решений и разрешений государственного уровня. Для того, чтобы создать условия для совершения звонков с помощью VoLTE, необходимо обеспечить поддержку этого функционала не только сетью, но и пользовательским оборудованием (User Equipment/UE).
Оставим VoLTE для будущих статей, а пока рассмотрим CSFB с технической стороны.
CSFB – Circuit switch fallback

Особенности/характеристики оборудования поддерживающего CS fallback
UE, естественно, имеет доступ и к E-UTRAN/EPC, и к CS domain через сеть GERAN и/или UTRAN.
MME использует LAI и hash-значение, получаемое из IMSI, для определения номера VLR, в случае, если данный LAI обслуживают несколько MSC/VLR, в SGSN используется это же hash-значение/функция.
С MSC всё понятно, но также возможно расширение функционала CS fallback поддержкой ICS и/или SRVCC.
Mobile Originated Call – Абонент звонит из LTE

Рассмотрим базовый сценарий развития событий
Счастливый обладатель телефона с поддержкой LTE идет по улице в зоне покрытия сетей 4G и 3G/2G. В фоновом режиме обновляется почта, Facebook, Twitter и другие сервисы. Решив позвонить, он совершает привычные для себя действия: набирает номер и нажимает кнопку вызова касается того место на экране, где изображена кнопка вызова.
В этот момент генерируется первый расширенный запрос (еще 2 года назад сложно было вообразить, что простейший голосовой вызов будет интерпретироваться как расширенный запрос) на предоставление сервиса. MME получает запрос, имея информацию о том, что абонент находится в сети LTE, сообщает об этом eNodeB, чтобы он инициировал процедуру CSFB. Процедура CSFB подразумевает перевод в 2G/3G-сеть, но телефон в это время уже активно использует сеть: получает почту и обновления от сервисов, и прерывать этот процесс нельзя. eNodeB, видя активную передачу данных, принимает решение произвести handover в сеть 3G или 2G. Решение о выборе сети принимается на основании полученных от UE измерений. Таким образом, переход между сетями происходит без разрыва активных сессий передачи данных.
Свое решение eNodeB сообщает MME, и тогда MME уже начинает договариваться с SGSN. Чтобы начать этот процесс, необходимо удостовериться в наличии необходимых ресурсов для данного абонента в SGSN (PFCs, PDP context, APN) и в RNC. Для этого MME передает запрос на изменение местоположения (Update Location) в SGSN. SGSN, в свою очередь, проводит соответствие LTE сервисов (EPS bearer service) не-LTE сервисам (PDP context) и запрашивает выделение ресурсов (PFCs — Packet Flow Context) в RNC. Не обязательно все сервисы будут приняты, в зависимости от загруженности 3G-сети, часть EPS-сервисов может быть отброшена.
Затем RNC подготавливает так называемый «прозрачный контейнер от источника к получателю», в котором будут данные, как для 3G-сети (Handover Radio Resources), так и для LTE (NAS контейнер). Получив подтверждение о наличии необходимых ресурсов, SGSN сообщает об этом MME, который инициирует процедуру Handover (посылает «прозрачный контейнер» на eNodeB).
eNodeB, получив команду, начинает «переключать» сервисы с MME на SGSN, и вместе с этим посылает команду Handover (с «прозрачным контейнером») на UE. По этой команде UE (смартфон) начинает перестраиваться на радиочасть 3G-сети. Именно для этих целей «прозрачный контейнер» содержит данные для handover как LTE, так и сетей 3G. После перестройки в новую сеть UE посылает сообщение XID (eXchange IDentifier) и в этот же момент возобновляет передачу данных. RNC информирует SGSN об успешном завершении handover, а так же ретранслирует XID на SGSN. После получения подтверждения Update Location начинается высвобождение ресурсов MME и eNodeB.
А далее происходит отработанная годами процедура стандартного голосового вызова в сетях 2G/3G.
Mobile Terminated Call – Абоненту звонят в LTE

Для начала по SGs-интерфейсу MME принимает paging от MSC с необходимой информацией (IMSI, VLR TMSI, Location Information). В зависимости от настроек paging проходит либо по IMSI, либо по TMSI. В первом случае MME использует IMSI, во втором генерирует из полученных данных S TMSI и передает на eNodeB. Получив paging, смартфон начинает запрашивать радиоресурсы и генерирует расширенный запрос. Как и в предыдущем сценарии, происходит handover, и после него UE отвечает на paging в сети 2G/3G. Голосовое соединение установлено.
Вот так относительно просто можно задействовать legacy-сеть для восполнения голосовых сервисов в сети нового поколения на пути к грядущему VoLTE.
Советы по настройке Larnitech
У меня сейчас активный период настройки нескольких систем Larnitech, я даже сделал отдельную страницу по этой услуге.
Настраивать с ноля систему Larnitech, уже установленную на объекте, крайне неудобно. Как, разумеется, и любую другую систему, особенно на шине.

Я немного замучил вопросами техподдержку, зато разобрался во многих моментах касательно настройки и нашёл, как работать с оборудованием проще. Что-то покажется вполне очевидным, до чего-то удалось дойти не сразу.
Сначала обновите программное обеспечение
Первым делом после подключения к новому контроллеру надо обновить программное обеспечение. Уже несколько раз мне поступали вопросы о том, почему что-то в системе на этапе первичной настройки работает не так, все проблемы решились обновлением ПО.
В web интерфейсе контроллера (в браузере) надо выбрать пункт меню «Обновления», там обновить до последних доступных версий LT Setup и LT Server. И нажать кнопку «установить заплатки безопасности».
На картинке ниже у LT Setup установлена версия 1.30, доступна более новая 1.91, нажимаем справа кнопку Обновить и ждём пару минут, всё произойдёт автоматически.

API Plugin отвечает за работу системы с голосовым помощником Siri. Все прочие пункты (Coolmaster, EIB и далее) устанавливаем и поддерживаем в актуальном состоянии только если соответствующие функции используются.
Далее заходим в Модули и смотрим, не предлагается ли обновить прошивку контроллера и подключенных модулей на релизной. Если доступно, то обновляем.
Редактор логики
Редактор логики находится в пункте интерфейса «Структура», кнопка «Редактировать логику».
Если в нём разобраться, то мы получим возможность гораздо быстрее выполнять настройку названий элементов и комнат. Хоть визуальное меню редактирования структуры тоже достаточно наглядное и удобное, но как минимум названия выходов и входов удобнее менять здесь.

А ещё в редакторе логики удобно быстро задавать назначение каждого входа и выхода. Нужно найти строчку с ID элемента :98.

Сразу видно назначение выходов модуля: L это лампа, B — штора, K — замок. В документации на wiki есть все возможные обозначения входов и выходов.
Съёмные клеммники
Клеммники подключения шины на всех модулях Larnitech, а также на датчиках CW-CO2 и CW-HTML — съёмные. Если надо переключить модуль, то проще всего снять клеммник и переставить на другой модуль, а не выдергивать проводки шины и питания.

Вот казалось бы, что это очевидно, а до меня дошло только на третьей системе. Вместо того чтобы разбирать все соединения и собирать потом заново, можно просто снять шину вместе с клеммниками и переставить на другие модули.
Настройка BW-SW06 и датчиков температуры
При подключении датчика температуры пола стандарта 1-wire (это FW-FT и FW-TS) к модулю BW-SW06 на контакт G подключается земля, на контакт 1 — сигнал, а на 2 — питание.
У FW-FT земля чёрная, сигнал жёлтый, а питание красное.
У FW-TS чуть сложнее: земля зелёная, сигнал бело-оранжевый, а питание оранжевое.

При настройке работы модуля BW-SW06.B мы задаём на вход 1 датчик температуры, а поле назначения входа 2 автоматически меняется на «Питание». Но вот с более новым модулем BW-SW06.C мы не можем выбрать «Питание», его нет в списке вообще.

Если замкнуть жилу питания на контакт GND, то датчик работает и показывает температуру, но нестабильно: чуть тронешь его, и показания пропадают. Если не подключать питание вообще, то датчик показывает ерунду: то -15 градусов, то +30.
Для решения проблемы заходим в меню «Структура», нажимаем «Редактировать логику». Находим строчку с номером модуля :98, и задаём для него настройку hw=»in=’T+BBBB’». То есть, принудительно задаём, что второй вход это +. Датчик подключаем как по инструкции.

Подключение датчиков протечки воды к DW-SW16
Для подключения датчиков протечки воды обычно используется модуль DW-WL02, к нему можно подключить до 16 датчиков протечки воды и 2 группы кранов. Иногда нам удобнее поставить для подключения датчиков протечки воды модуль дискретных входов DW-SW16, но при его настройке нам не задать в меню настроек HW назначение входа как «датчик протечки». Что делать?
Снова лезем в настройки логики и задаем тип входа L — leak. На скриншоте первые 9 входов модуля выключатели, далее 6 датчиков протечки воды. Последний вход — GND всех датчиков и выключателей.
![]()
Датчики протечки воды Larnitech работают не так, как обычные датчики, они периодически посылают сигнал автотеста кратковременным замыканием тревожного выхода. Так что при настройке его как геркон мы будем получать тревогу «Обрыв», так как геркон не посылает сигнал автотеста.
Пропали скрипты
В Larnitech большая база готовых стандартных скриптов для разных потребностей. Но вот мы заходим в меню Сценарии, нажимаем «Добавить скрипт», а список скриптов пустой. Что делать?
Нужно зайти в меню Обновления, найти там Scripts и нажать Переустановить. Хотя они и так установлены.

Но нажимаем, ждём загрузку, далее снова заходим в Сценарии, и список скриптов на месте.

Серийные номера модулей и датчиков
На всех датчиках и модулях есть серийный номер на серебристой наклеечке со штрих-кодом. Он продублирован также на такой же наклейке на коробке.

По этому серийному номеру можно идентифицировать модуль или датчик. Но если модуль можно идентифицировать и более просто, нажав на соответствующую кнопку в списке модулей (он начнёт мигать светодиодами), то на датчиках светодиодов нет, тут найти, где какой датчик, сложнее.
Эти самые серийные номера элементов можно посмотреть, почему-то, только в том же незаменимом редакторе логики. Нужно найти строчку <item addr=»ID:98 …>, там будет вписан серийный номер (sn). Эти номера я в рамках преднастройки системы переписываю в таблицу с цоколёвкой контроллера Larnitech.

Обновление прошивок модулей
Лучше всего все модули и датчики обновлять до прошивки «Релиз». Но иногда есть необходимость (например, по указанию техподдержки) обновить элемент до прошивки «Альфа» или «Бета». Просто так это не сделать. Нужно зайти в меню «Общие» и сдвинуть ползунок настроек обновления на «Advanced», это даст нам возможность выбора прошивки для обновления.
Перезагрузка контроллера
В процессе изменения ID устройств (а я люблю, когда ID модулей в щите нумеруются по порядку, так удобнее впоследствии) устройство с новым ID может не появляться в списке устройств. Сначала дайте системе немного времени: подождите секунд 10-15 и нажмите F5 для обновления списка модулей. Но если обновление списка модулей не помогает, нужно перезагрузить LT Setup, это можно сделать в меню Перезагрузка. Перезагрузка занимает порядка 10 секунд. Дёргать питание контроллера не нужно.
Ставим автоматы или предохранители на питание датчиков
При установке датчиков лучше отключать питание шины датчиков, чтобы случайное замыкание проводов не привело к отключению всего блока питания.
Если у нас в системе не стоит отдельный блок питания на датчики, а контроллер и датчики питаются от одного блока, лучше питание датчиков подключить через автомат, который можно было бы отключать при необходимости. Если от контроллера идёт 2 шины или больше шины датчиков, то ставим отдельные автоматы на разные шины, чтобы отключать только то, с чем собираемся работать.
Но вообще, система поддерживает «горячее» (без отключения питания) переподключение модулей отлично. В приложении Larnitech сразу отображаются подключенные элементы, даже если в списке устройств в web интерфейсе контроллера они не появились.
Хочу отдать должное контроллерам Larnitech. В процессе настройки нескольких систем, когда приходится много добавлять, убирать, переподключать, переименовывать модули, обновлять разные программные блоки, ни разу не возникало никаких зависаний контроллера, необходимости его полной перезагрузки или отказа интерфейса.
Wl 2cs что такое

Выберите способ оплаты «В кредит» при оформлении заказа или нажмите здесь «Купить в кредит». После подтверждения заказа в личном кабинете заполните заявку. Банк ответит через несколько минут. Подробнее
Добавить в избранное
Доступно для зарегистрированных пользователей
Подписка на товар
При поступлении товарвв на скалд Вам придет уведмление на e-mail
За свои покупки вы получаете бонусные рубли, которыми сможете оплатить следующие покупки. 1 балл = 1 рубль. Подробнее
Купить в кредит

Характеристики товара
Отзывы о товаре
Поличили в своём посёлке на почте. Уже не первый раз тут делаю заказ. Мы довольны покупкой.
Не много задержали, но доставили до дома. Прислали все необходимые документы. Подарок удался на славу.
Груз пришёл целым. Мы очень долго оформляли заказ, замучили менеджеров, но тем не меннее все были предельно вежливы. На сайте нашли много интересных штучек, докупили что бы добрать до акции.
В интернет-магазине MaxHall перед отправкой все товары дополнительно подлежат обязательной проверке на наличие дефектов.
Во время доставки:
- Если товар в следствии транспортировки сломался, разбился или пришел в негодность, вы имеете право отказаться от товара. Денежные средства будут направлены Вам в этот же день, перевод может занять до 3-х дней.
- Вы имеете право отказаться от товара в любое время до его получения, а после передачи товара – в течении 7 (семи) календарных дней (в соответствии со статьей 26.1. Закона РФ «О защите прав потребителей»).
Во время использования:
Если в процессе эксплуатации в течении гарантийного срока у полученного товара были обнаружены какие-либо недостатки, то мы бесплатно произведем ремонт в сервисном центре или обменяем товар.
Все товары, которые предоставляет интернет-магазин MaxHall – это товары, соответствующие международным стандартам качества: технологическим, потребительским и экологическим. Это соответствие подтверждается всеми необходимыми сертификатами и разрешительными документами.
Хотите узнать, как ещё выгодней совершить покупку на нашем сайте MaxHall?
-
Вступайте в наш MaxClub для VIP клиентов и получайте персональные скидки на все товары до 12% в зависимости от категории.
Подробнее: https://maxhall.ru/news/skidka_nashim_klientam/
Но это ещё не все! Все члены клуба, так же получают возможность участвовать в закрытых распродажах, использовать подарочные промокоды, которые мы заботливо высылаем на почту по особым дням.
Для того чтобы стать членом клуба MaxClub зарегистрируйтесь по ссылке https://maxhall.ru/profile/
У вас есть вопрос по товару?
Задайте его в онлайн чате, позвоните по телефону 8 (800) 302-66-39 (звонок по РФ бесплатный), или пришлите электронное письмо на почту contact@maxhall.ru
Заказ, сделанный в нашем интернет-магазине, можно оплатить любым удобным способом:
- Наличными при получении (подробнее)
- Банковскими картами онлайн (подробнее)
- В кредит (подробнее)
- По счету (подробнее)
Обратите внимание! Если общая стоимость товара превышает сумму в 100 000 руб., то его отгрузка будет осуществляться только по ПРЕДОПЛАТЕ.
Все платежи надежно защищены. Получить подробную консультацию по вопросам порядка оплаты, а также поинтересоваться состоянием проведенного платежа можно по телефону 8 (800) 302-66-39 (бесплатно по России).
Доставка заказов осуществляется транспортными компаниями СДЭК и ДПД:
- До ближайшего к Вам пункта выдачи.
- Курьером до двери.
Удобный вариант доставки можно выбрать в процессе оформления заказа.
Если Вы оплачиваете заказ на сайте он-лайн, доставка рассчитывается по акции:
- Фиксированная цена доставки до пункта выдачи по всей территории России, не зависимо от суммарного веса заказа, составит 300 рублей *.
- Бесплатная доставка по всей территории России при сумме заказа свыше 7000 рублей*.
*акция НЕ распространяется на доставку в Казахстан и Беларусь.
При заказе товаров с удаленных складов поставщиков (под заказ), сроки доставки будут варьироваться от 5 рабочих дней до 2 недель.
Zynq 7000. Прикручиваем Wi-Fi модуль RTL8822CS с использованием SDIO через EMIO
Наконец-то пришла пора продолжить изучение возможностей платы Zynq QMTech и SoC XC7Z020. Следующая интересная задача, которую я для себя придумал в качестве обучающей — оснастить плату Wi-Fi модулем Realtek RTL8822CS и, если Wi-Fi модуль будет не нужен, а нужна будет ещё одна флешка — вторым портом для SD-карточки. Если интересны подробности того, как я это всё реализовал — добро пожаловать под кат.

Важно! Перед началом повествования, хотелось бы заранее оговориться, что основная цель, которую я преследую при написании этой статьи — рассказать о своем опыте, с чего можно начать, при изучении отладочных плат на базе Zynq. Я не являюсь профессиональным разработчиком под ПЛИС и SoC Zynq, не являюсь системным программистом под Linux и могу допускать какие-либо ошибки в использовании терминологии, использовать не самые оптимальные пути решения задач, etc. Но отмечу, что любая конструктивная и аргументированная критика только приветствуется. Что ж, поехали…
Сформулируем цель и задачи
Итак, у нас есть плата, описанная в этой статье и есть желание прикрутить к ней Wi-Fi модуль Realtek RTL8822CS. Модуль, разумеется, должен корректно инициализироваться в ОС Linux и обеспечить пропускную способность до 150 Мбит\с (с чем связано такое ограничение и именно этой цифрой — ниже). В качестве альтернативного варианта для использования выведенного SDIO — необходимо организовать второй порт для подключения SD-карт.
Исходя из этого можно сформировать несколько задач, решив которые мы можем достигнуть цели:
Проверить возможность выноса линий SDIO через EMIO (т.е. через пины PL-части Zynq) и подготовить bitstream-файл;
Проверить работоспособность SDIO через EMIO в приложении baremetal с использованием microSD-карточки;
Изготовить мезонинные платы для Wi-Fi модуля и смонтировать на них компоненты;
Подготовить First Stage Bootloader, Device Tree Source, U-Boot, Linux Kernel в нужной конфигурации для запуска Wi-Fi модуля;
Подготовить модуль ядра для работы Wi-Fi модуля, а именно модуль cfg80211, который является линуксовым API для 802.11 устройств;
Подготовить модуль ядра 88x2cs, который является драйвером для модуля Wi-Fi RTL8822CS который работает поверх SDIO-шины;
Проверить работоспособность сети, сделать сканы эфира, посмотреть рабочие уровни, сделать замеры скорости downstream/upstream-трафиком через iPerf;
Итак. Перейдем к реализации намеченного, в целом, не выглядит сильно сложно =)
Настройка проекта в Vivado и конфигурация PL
В этой главе я кратко (без скриншотов) опишу процедуру создания нового проекта с акцентами на важных моментах. Если необходима инструкция с картинками — можно обратиться к моим предыдущим статьям.
Открываем Vivado и создаем проект через кнопку Create Project. Откроется мастер настройки нового проекта, быстро пройдемся по шагам.
Даём имя проекту, например SDIO_EMIO и указываем папку сохранения;
Указываем, что это RTL Project, оставляем включенной галочку Do not specify sources at this time;
Находим модель SoC использованного на плате. В моем случае это xc7z020clg400-1;
В левом меню IP Integrator нажимаем Create Block Design и создаем новый дизайн. Назовём его для простоты block_design.
Добавляем примитив процессорной системы Zynq на диаграмму через нажатие правой кнопкой Add IP — ZYNQ7 Processing System. Сразу же выполним предложенные действия от автоматизатора, через команду на зеленом поле Run Block Automation и откроем настройки процессорной системы.
Я заранее сохранил шаблон настроек PS, чтобы в каждом проекте не прописывать всё заново. Взять его можно тут: ссылка на Github. Через меню Presets — Apply Configuration применяем его и сразу переходим в меню Peripherial I/O Pins.
Ставим галочку возле меню SD 1 и проверяем, что выбран вариант подключения через EMIO:

Остальные настройки я оставил без изменений, в т.ч. частоты тактирования SDIO, PL. Получаем следующую картину (если развернуть группу сигнальных линий SDIO_1):

В данном случае нас интересуют линии CLK, CMD и 4 линии DATA, что в общем-то является стандартным набором для SDIO-шины. Но вот незадача, каждая из линий организована тремя отдельными сигналами. Для решения этой задачи нам необходимо руками создать буфер IOBUF, который будет управляться через активный пин T с тремя состояниями и разрулит Input, Output сигналы как нам нужно для использования его с двунаправленным сигналом I/O. Выглядит он следующим образом:

Т.к. в стандартной библиотеке графических примитивов он отсутствует — нужно будет создать свой IP-модуль и добавить его на схему. Для каждого из сигнала он будет свой.
Через меню Sources — Add Sources (Alt + A) добавляем Design Source — Create File, выбираем тип файла Verilog и назовём его iobuf_cmd.
Запишем следующее содержимое:
То же самое сделаем для сигнала CLK, только файл назовём iobuf_clk. Запишем в него следующее содержание:
С SDIO DATA немного сложнее т.к. она состоит из нескольких линий. Так же создадим файл iobuf_data и запишем в него следующее содержимое:
Для каждой из линии создается свой экземпляр примитива IOBUF.
Поочередно размещаем добавленные модули на диаграмму через клик правой мышкой по Diagram — Add Module. Соединяем сигналы с нужными портами и получится следующее:

Хотелось бы обратить внимание на две важные вещи:
На порт iobuf_t модуля для сигнала CLK я добавил Constant с шириной в 1 бит и со значением 0, т.к. управляющего T-пина для CLK не предусмотрено;
Сделал порты iobuf_io как External и дал им соответствующие названия;
Соединил порты Input с портами Output;
На текущем этапе можно запустить синтез и назначить выходы портов на реальные физические порты. Для этого нужно:
Нажимаем на меню block_design правой кнопкой и выбираем команду Create HDL Wrapper.
В меню IP Integrator выбираем Generate Block Design;
Выбираем Synthesis Option — Global и нажимаем Apply, затем Generate.
Дожидаемся окончания генерации;
Выбираем Run Synthesis для старта синтеза нашего дизайна.
Дожидаемся окончания синтеза;
После окончания синтеза переходим в меню Open Synthesized Design и откроется меню Package с нижним меню I/O Ports. Далее необходимо:
Отметить подходящие физические I/O пины
Убедиться, что включена подтяжка PULLUP на всех пинах кроме CLK;
В моем случае получается следующее:

Сохраняем настройки, будет предложено создать файл с constraints. Называем его как удобно и нажимаем Ok. После нажимаем Generate bitstream, соглашаемся с тем, что синтез устарел и ждем окончания всех необходимых процедур до получения сообщения:

После этого можем экспортировать BSP в SDK и запустить проверку работоспособности SDIO в baremetal. Делается это через меню File — Export — Export Hardware, ставим Include bitstream. Нажимаем Ok и запускаем SDK через команду File — Launch SDK.
Проверка SDIO через microSD-карту в Baremetal
Прежде чем приступить к проверке необходимо подключить microSD-карту к пинам, которые мы размечали в следующем разделе. Смотрим в первую очередь на распиновку microSD-карты:

С пинами VDD (3.3V) и VSS (GND) всё в целом понятно. С другими пинами есть нюанс, для пина CMD и шины DATA требуется подтяжка к высокому уровню через 10 кОм резисторы. В моем случае, чтобы не городить навесным монтажом резисторы, я взял одну из плат, заготовленных для Wi-Fi модуля и запаял на него все что нужно:

Если посмотреть на принципиальную схему этой платы — все выглядит вот таким образом:

Питание подключено напрямую в соответствии с тем, как оно выведено на гребенку. Для удобства отладки логическим анализатором — я подпаивал МГТФ-проводки.
После того, как все необходимые линии подключены — можно вернуться в SDK к созданию проекта. После запуска SDK обзываем проект SDIO_EMIO и нажимаем Next, выбираем шаблон проекта Hello World.

Открываем файл helloworld.c из древа проекта и пишем в него следующий код, который подключит нужные библиотеки и поможет нам быстро сделать проверку:
Кликаем правой кнопкой по проекту SDIO_EMIO и выбираем Build Project. Смотрим, что проект собирается без проблем. Важный момент — выбрать правильный SDIO-контроллер в строке SdConfig = XSdPs_LookupConfig(XPAR_XSDPS_1_DEVICE_ID);
Подключаем JTAG-отладчик и после сборки проекта заливаем bitstream-файл выполнив команду Xilinx — Program FPGA и дожидаемся сигнала FPGA DONE на плате.
Открываем Serial Port, который принадлежит нашей плате. Например: minicom -D /dev/ttyUSB0. Узнать какой порт принадлежит плате можно запустив команду udevadm monitor | grep ttyUSB и выткнуть-воткнуть miniUSB кабель из платы. Там можно увидеть сообщения по которым можно понять какой у нас порт. Например:
После запускаем проект также кликнув по корневому значку проекта выбрав меню Run As — Launch on hardware (System Debugger). В выводе в консоль мы должны увидеть следующее:

Что означают эти сообщения? Это значит, что драйвер успешно “достучался” до карточки и может спокойно начать с ней обмен. Значит наш SDIO-контроллер работает. Идём дальше.
Трассировка и изготовление мезонинных плат для Wi-Fi модуля
Следующим шагом нужно подготовить платы, на которые я запаяю радиомодуль, со всей необходимой обвязкой. В качестве первого радиомодуля был взят модуль от FN-Link с Realtek RTL8822CS чипом, модель модуля 6222B-SRC. Подробнее можно посмотреть тут, ссылка на Datasheet.
Кратко скажу, что это простой MIMO 2×2 Dual Band модуль Wi-Fi с поддержкой 802.11ac и Bluetooth 4.2 или 5.0 в зависимости от модели.
Так как модуль мы будем подключать к гребенке PLS на плате с шагом в 2.54мм. — было решено сделать такой же разъем и на мезонинной плате.
Распиновка со стороны платы:

Распиновка со стороны модуля:

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

Всё в целом достаточно примитивно и в соответствии с референсной схемой и небольшими изменениями, такими как пин включения\выключения питания модуля и прочих мелких доработок. Антенный тракт было решено вывести на u.FL-разъем, для удобства и возможности подключения любых подходящих для 2.4/5ГГц антенн.
Получившиеся платы достаточно просты в трассировке и не представляют собой никакого технического ноу-хау, но линии данных нужно выровнять т.к. SDIO-шина тут достаточно скоростная, чтобы пренебречь таким важным аспектом трассировки.
Результат трассировки в 2D:

Результат трассировки в 3D:



Вид платы после монтажа компонентов:

Т.к. плата изначально разрабатывалась не только для этой версии Wi-Fi модуля — остались не установленными некоторые компоненты.
В целом можно переходить к подготовке всего необходимого для работы с радиомодулем с точки зрения основных управляющих сигналов и подготовки необходимых файлов для работы радиомодуля в Linux. Об этом в следующих главах.
Небольшое дополнение проекта в Vivado
Для того, чтобы была возможность запустить радиомодуль необходимо соблюсти два условия:
Подать низкое напряжение на затвор P-канального ключа VT1, т.е. на линию WL_BT_ON, чтобы подать питание на радиомодуль;
Подать высокое напряжение на ножку WL_REG_ON радиомодуля, чтобы запустить его;
Поэтому на этом этапе нам будет нужно слегка модернизировать проект и добавить 2 сигнала с AXI GPIO-контроллера и завести их на соответствующие ножки:
Для транзисторного ключа это ножка 11 на общей гребенке, что соответствует физическому пину W20;
Для сигнала WL_REG_ON это 25-я ножка на той же гребенке, что соответствует в моем случае пину V17;
Как работать с AXI GPIO Я рассказывал в этой статье и на деталях повторяться не буду. В нашем случае нужно выполнить лишь несколько шагов:
Добавляем в дизайн IP-модуль AXI GPIO;
Выполняем предложенные шаги автоматизации предложенные Vivado, отметив все галочки;
Появится блок AXI GPIO, необходимо зайти в его опции и поставить галочку All Outputs, поставить ширину шины GPIO Width в значение 2 (нужно 2 сигнала) и в Default Output вписать 0x00000002, чтобы по умолчанию после загрузки bitstream-файла оба пина приняли необходимое значение;
Называем External Interface от AXI GPIO как MGMT_GPIO и сохраняемся. Должно получиться следующее:
Синтезируем дизайн, проверяем, что всё прошло успешно;
Переходим в меню Open Synthesized Design и назначаем MGMT_GPIO[0] пин W20, а MGMT_GPIO[1] пин V17;
Изменяем у этих двух пинов I/O Std на LVCMOS3.3 и сохраняем;
Запускаем генерацию bitstream-файла через Generate bitstream;
Экспортируем сгенерированный bitstream и всё что необходимо для дальнейших шагов через команду File — Export — Export Hardware;
Все изменения, необходимые на этом этапе мы внесли. Переходим к подготовке всего необходимого для работы с радиомодулем в Linux;
Подготовка FSBL, Device Tree Sources, U-Boot
На этом этапе можно переходить к созданию загрузчиков, файлу описания железа и компиляции ядра Linux. Многие моменты и детали Я целенаправленно опущу т.к. уже рассказывал в предыдущей статье а отличающимся моментам посвящу основную часть повествования.
Первым этапом надо подготовить FSBL. Для этого нужно:
В меню Xilinx SDK переходим в меню File — New — Application Project;
Именуем его как FSBL;
Нажимаем клавишу Next;
Из заготовок выбираем Zynq FSBL;
Дожидаемся окончания компиляции и проверяем, что появился файл FSBL.elf
Вторым этапом необходимо подготовить Device Tree Source/Blob файл который будет использован для сборки U-Boot. Для этого сделаем следующее:
Добавляем BSP Repository из репозитория device-tree-xlnx. Для этого нужно выбрать меню Xilinx — Repositories и указать папку с device-tree-xlnx в секцию Global Repositories.
Добавляем BSP Project через меню File — New — Board Support Package, даём ему имя и выбираем внизу меню device_tree и в следующем меню нажимаем Ok, если не требуется внесения каких-либо изменений.
Выполним редактирование файла zynq-7000.dtsi и находим секцию описывающую SDIO1 в строке sdhci1: mmc@e0101000;
Дополняем секцию следующим содержанием (файл можно взять тут) :

Переходим в папку с сгенерированными dts-файлами в системной консоли:
Компилируем в blob:
Всё. Device Tree готов.
Следующим этапом необходимо подготовить U-Boot для нашей платы. Нужно выполнить несколько простых шагов:
Перейти в папку с U-Boot: cd u-boot-xlnx
Задать переменные для кросс-компиляции: export CROSS_COMPILE=arm-linux-gnueabihf-; export ARCH=arm
Очистить сырцы от предыдущих результатов компиляции и применить конфиг для Zynq по умолчанию: make distclean; make xilinx_zynq_virt_defconfig
Положить в папку с U-Boot полученный в предыдущем шаге system.dtb в папку arch/arm/dts/ c именем zynq-qmtech.dtb
Указываем какой Device Tree файл использовать: export DEVICE_TREE=»zynq-qmtech»
Далее необходимо зайти в меню конфигуратора и изменить ряд опций: make menuconfig
Опция для того, чтобы активировать поддержку AXI GPIO, которая используется для включения питания модуля и подачи сигнала WL_REG_ON на радиомодуле: Device Drivers — GPIO Support — Xilinx GPIO Driver
Сохраняем конфиг (можно взять тут) в файл .config
Запускаем сборку: make -j$(nproc) и дожидаемся окончания компиляции;
После этого можно скомпоновать FSBL, Bitstream-файл и U-Boot в один загрузочный файл BOOT.BIN. Подробное описание компоновки можно найти в моей прошлой статье. В целом надо выполнить несколько простых шагов:
Найти файл в каталоге с проектом First stage bootloader. По умолчанию он находится в SDIO_EMIO/SDIO_EMIO.sdk/FSBL/Debug/FSBL.elf
Найти Bitstream-файл для программируемой логики. Найти его можно в каталоге SDIO_EMIO/SDIO_EMIO.sdk/block_design_wrapper_hw_platform_0/block_design_wrapper.bit
Найти бинарный файл U-Boot. Данный файл после компиляции лежит в папке с U-Boot: u-boot-xlnx/u-boot.elf
Открываем в Xilinx SDK пункт меню Xilinx — Create Boot Image;
Выбираем куда сохранить новый bif-файл, я его сохраняю в корневом каталоге проекта;
Добавляем поочередно файлы FSBL.elf, block_design_wrapper.bit, u-boot.elf в секцию Boot Image Partitions;
Нажимаем Create Image и видим как в каталоге с bif-файлом появляется BOOT.BIN;
Теперь необходимо залить этот файл на загрузочную SD-карту и можно попробовать загрузиться. Если мы видим приглашение от U-Boot и что светится светодиод FPGA DONE — значит мы всё выполнили правильно.

Можно перейти к проверке того, проинициализирован ли AXI GPIO в U-Boot и проверим их. Для этого сначала выведем список устройств которые проинициализированы. Это можно сделать через команду dm tree.

Отлично. Видно, что у нас на борту есть два SDIO-контроллера, и два GPIO-контроллера. Попробуем изменить состояние ножки транзистора. Для этого нужно:
Посмотреть какие адреса в GPIO доступны и какие отвечают за те, или иные ножки: gpio status -a
В конце вывода видно, что есть Bank GPIO с двумя ножками, которые соответствуют значению по умолчанию:
Проверки ради можно изменить состояние ножки gpio@412000000 через команду: gpio toogle gpio@412000000 или gpio set gpio@412000000 / gpio clear gpio@412000000 для установки логической 1 или 0 соответственно
Так. Загрузчик подготовлен. Теперь можно переходить к подготовке ядра Linux и RootFS со всем необходимым для нас содержимым
Компиляция ядра Linux и подготовка RootFS с использованием Buildroot
Так же как и прошлых главах, для исключения необходимости подробного объяснения каждого шага, сошлюсь на предыдущую статью как скомпилировать ядро Linux. Перейдем к выполнению шагов, необходимых для сборки ядра с необходимыми модулями и драйверами. Для этого нужно:
Перейти в папку с клонированным репозиторием linux-xlnx;
Обновить его (при необходимости): cd linux-xlnx; git fetch -p; git checkout master; git pull;
Экспортируем также переменные для кросс-компиляции: export CROSS_COMPILE=arm-linux-gnueabihf-; export ARCH=arm
Делаем очистку от результатов предыдущих сборок: make distclean
Загружаем дефолтный конфиг: make ARCH=arm xilinx_zynq_defconfig;
Изменим дефолтный конфиг загрузив меню конфигурации: make ARCH=arm menuconfig
Изменим опции конфигурации (можно взять тут) , устанавливаем опцию (проследим, что там вместо [M] в поле выбора стоит символ звездочки [*] : Networking Support — Wireless — cfg80211
Сохраняем конфиг в файл .config и выходим из меню конфигурации;
Запускаем процесс компиляции: make ARCH=arm UIMAGE_LOADADDR=0x8000 uImage -j8
Компилируем модули ядра: make ARCH=arm -j8 modules
Копируем uImage из каталога linux-xlnx/arch/arm/boot/ на загрузочную SD-карту;
Далее необходимо подготовить образ RootFS с всеми необходимым userspace-утилитами, типа wpa_supplicant, wpa_cli, etc. Собирать RootFS будем с помощью системы сборки buildroot, статью о которой я писал до этого. Итак, перейдем к сборке, для этого нужно:
Заходим в папку с buildroot: cd buildroot
Обновляем его до последней версии: git fetch -p; git checkout master; git pull;
Делаем очистку от результатов предыдущих сборок: make distclean
Запускаем меню конфигурации: make -C /home/megalloid/buildroot O=$PWD ARCH=arm nconfig
Изменяем опции конфигурации по списку ниже;
Опция 1: Target options — Target Architecture — ARM (little endian)
Опция 2: Target options — Target Architecture Variant — cortex-A9
Опция 3: Target options — Enable NEON SIMD extension support — [*]
Опция 4: Target options — Enable VFP extension support — [*]
Опция 5: Target options — Target ABI — EABIhf
Опция 6: Target options — Floating point strategy — NEON
Опция 7: Build options — Number of jobs to run simultaneously — 8 (по количеству ядер CPU)
Опция 8: Toolchain — C library — glibc
Опция 9: Toolchain — Kernel headers — Custom Git Repository
Опция 10: Toolchain — URL of custom repository — </home/megalloid/linux-xlnx>
Опция 11: Toolchain — Custom repository version — <хэш-сумма от git show-ref | grep master из папки linux-xlnx>
Опция 12: Toolchain — Custom kernel headers series — 5.15.x
Опция 13: Toolchain — Install glibc utilities — [*]
Опция 14: Toolchain — GCC compiler Version — gcc 9.x
Опция 15: Toolchain — Enable C++ support — [*]
Опция 16: Toolchain — Enable compiler link-time-optimization support — [*]
Опция 17: Toolchain — Enable compiler OpenMP support — [*]
Опция 18: Target packages — Miscellaneous — haveged
Опция 19: Target packages — Networking applications — dhcpd
Опция 20: Target packages — Networking applications — dropbear
Опция 21: Target packages — Networking applications — ifupdown scripts
Опция 22: Target packages — Networking applications — hostapd
Опция 23: Target packages — Networking applications — iperf
Опция 24: Target packages — Networking applications — iperf3
Опция 25: Target packages — Networking applications — fping
Опция 26: Target packages — Networking applications — iw
Опция 27: Target packages — Networking applications — iwd
Опция 28: Target packages — Networking applications — wpa_supplicant
Опция 28: Target packages — Networking applications — wireless tools
Опция 29: Filesystem images — cpio the root filesystem — [*]
Опция 30: Filesystem images — Compression method — lzma
Опция 31: Host Utilites — host dosfstools
Опция 32: Host Utilites — host genimage
Опция 33: Host Utilites — host mtools
После этой длительной конфигурации выбираем Save и сохраняем конфиг (можно взять тут и подложить к себе);
Нажимаем F9 и запускаем процесс сборки: make -C /home/megalloid/buildroot O=» >PWD ARCH=arm BR2_JLEVEL formula inline» source=»((» alt=»((» src=»https://habrastorage.org/getpro/habr/upload_files/e5d/55b/77d/e5d55b77d535464756de9815f50f4c6a.svg» width=»15″ height=»24″/>(nproc) — 1))»
Ждём когда закончится компиляция, самое время заварить и выпить кофе =)
Теперь когда образ RootFS собрался надо его подписать и привести к виду, в котором его сможет корректно переварить U-Boot:
Переходим в папку с готовыми образами: cd buildroot/images
Производим подпись: mkimage -A arm -T ramdisk -C gzip -d rootfs.cpio uramdisk.image.gz
Складываем uramdisk.image.gz на загрузочную SD-карту;
Настраиваем загрузку образов в U-Boot:
Надо загрузиться в консоль U-Boot и записать туда: setenv mmc_boot “fatload mmc 0 0x2000000 uramdisk.image.gz; fatload mmc 0 0x4000000 uImage; fatload mmc 0 0x4500000 system.dtb; bootm 0x4000000 0x2000000 0x4500000;”
Сохраняем эту переменную через saveenv и перезагружаемся;
Дожидаемся загрузки ОС;
Теперь можно переходить к компиляции драйвера и непосредственно настройке Wi-Fi модуля.
Компиляция модуля ядра 88х2cs для Wi-Fi модуля
Переходим к последнему элементу, необходимому для работы Wi-Fi модуля — драйверу нашего Wi-Fi модуля. На просторах GITHUB я нашел вполне себе собираемый и рабочий вариант драйвера. Чтобы собрать драйвер out-of-tree нужно сделать следующее:
Переключим ветку на версию драйвера совместимую с 5.15: git checkout tune_for_jethub_5_14
Запускаем компиляцию: make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KSRC=»/home/megalloid/linux-xlnx» (где KSRC — путь до папки с ядром LInux из предыдущего шага);
На выходе мы получим в этой папке файл 88x2cs.ko, его нужно положить туда же на загрузочную SD-карту;
Проверяем, загрузится ли модуль ядра и появится ли wlan-интерфейс:
Монтируем SD-карту в файловую систему: mount /dev/mmcblk0p1 /mnt
Переходим в каталог SD-карты: cd /mnt/
Выполняем insmod 88x2cs.ko для загрузки модуля ядра;
Запускаем программу ifconfig — и видим, что появился wlan0 интерфейс:

Это говорит о том, что модуль ядра успешно загрузился и готов к работе. В следующей главе перейдем к настройке wlan0 интерфейса и проверке работоспособности Wi-Fi, прогону скорости через iPerf;
Настройка Wi-Fi интерфейса и измерение скорости с использованием iPerf
Для настройки Wi-Fi необходимо первым делом создать конфиг, удобнее всего в этом случае его создать на SD-карте в виде файла wpa_supplicant.conf.
Выполним в консоли Zynq следующие команды:
Создадим файл конфигурации: touch /mnt/wpa_supplicant.conf
Открываем его на редактирование: vi /mnt/wpa_supplicant.conf
Записываем в него следующее содержимое и сохраняем:
Запускаем wpa_supplicant: wpa_supplicant -B -Dnl80211 -iwlan0 -c/mnt/wpa_supplicant.conf -P/var/run/wpa_supplicant.pid -dd -f/mnt/wpa_supplicant.log
Через некоторое время появится IP-адрес на интерфейсе wlan0 и будет установлена связь с роутером;
Теперь можно прогнать трафик с компьютера (который подключен к роутеру кабелем) на Zynq и обратно. Для этого нужно:
Запустить на компьютере: iperf3 -s
Запустить на Zynq: iperf3 -c <IP компьютера> -N -i1 -t60 -u
Чтобы пустить трафик в обратном направлении на Zynq нужно выполнить: iperf3 -c <IP компьютера> -N -i1 -t60 -R -u
Скорость в целом соответствует заявленным Xilinx цифрам: около 20 Мбайт\сек (около 150 Мбит\с). В итоге если будем иметь подходящие условия в эфире — эта скорость будет максимальной и в 2.4 ГГц и 5 ГГц. Результат соответствует всем ожиданиям.
Подведем итог
После длительного кропотливого исследования без каких-либо how-to удалось обуздать эту железку. На общую проработку этого всего ушло около недели, что в целом доставило немало удовольствия по мере продвижения к решению задачи. Буду надеяться, что мой опыт кому-нибудь пригодится и будет высоко оценен. Спасибо!
Как настроить
универсальный пульт
для телевизора?
Универсальный пульт может управлять разными моделями телевизоров, приставок, DVD-плееров и спутниковых тюнеров. Оригинальные пульты проходят настройку на заводе — в них уже записан определённый набор команд, совместимый только с одним устройством или с несколькими похожими ТВ одного бренда. Универсальный пульт можно настроить самостоятельно. В его памяти — настройки для десятков телевизоров. Некоторые модели создаются для конкретного бренда, другие работают с любыми ТВ независимо от производителя.
Чаще всего универсальные пульты покупают на замену потерянным или поломанным оригиналам. Можно настроить пульт, чтобы он управлял сразу несколькими устройствами, например телевизором, приставкой T2 и DVD-плеером.


В пультах используется инфракрасный светодиод, передающий устройству команды с помощью невидимого для глаз луча. В сигнале записаны три цифры — единицы или нули. Например, комбинация 111 включает телевизор, 011 — увеличивает громкость, а 001 — переключает канал вперёд. Разница между брендами и моделями заключается в последовательности, частоте и длительности инфракрасных сигналов. В оригинальном пульте есть чёткий набор команд, совместимый с конкретным телевизором. В универсальном пульте могут быть готовые настройки — просто нужно найти их в списке или воспользоваться функцией автоматического подбора. Если нет — каждую команду придётся программировать самостоятельно.
Как найти код телевизора для универсального пульта?
Начните с инструкции на упаковке с пультом. Обычно в ней есть коды для настройки под популярные модели ТВ.
Если такого раздела в инструкции универсального пульта нет или вы не видите подходящей модели, обратитесь к документации самого телевизора. Ищите в названии устройства 3-х или 4-значный код. Например, у Hi VHIX-43U169MSY это 169, у LG NanoCell 55NANO866NA — 866, у Philips 43PFS5505 — 5505, у Samsung UE65TU7170U — 7170.
Также в инструкции к телевизору могут быть описаны настройки универсального пульта.
Как автоматически настраивать универсальные пульты по брендам?
Включите телевизор с помощью оригинального пульта или кнопки на корпусе. Направьте универсальный пульт на ТВ и не отводите его в сторону до окончания процедуры.
Vivanco
- зажмите кнопки SET и TV на 5–10 секунд, пока не включится индикатор у клавиши POWER;
- если телевизор выключился, сразу же нажмите OK;
- включите ТВ с помощью универсального пульта и попробуйте разные команды;
- если вы недостаточно быстро нажали OK, процедуру нужно повторить.
Philips
- чтобы настроить универсальный пульт, зажмите кнопку TV на 5–10 секунд;
- когда подсветка кнопок или экрана мигнёт, а индикатор режима ТВ загорится, введите код телевизора;
- если настройки приняты, подсветка мигнёт ещё три раза;
- если настройку закончить не удалось, подсветка мигнёт один раз и загорится индикатор режима ТВ. В таком случае переходите к другим способам, о которых мы расскажем далее.
- для настройки зажмите кнопку TV на 5–10 секунд;
- когда загорится индикатор, нажмите кнопку питания;
- направляйте универсальный пульт на телевизор;
- когда экран отключится, как можно быстрее нажмите кнопку OK, чтобы настроить устройство.
Thomson
- зажмите кнопку TV на 5–10 секунд;
- направьте универсальный пульт на телевизор;
- подождите минуту — если в памяти есть нужные коды, устройство удастся настроить автоматически.
OFA (One for all)
- нажмите кнопку TV;
- зажмите кнопку Magic, SET или SETUP, в зависимости от того, какая есть на вашем пульте, на 5–10 секунд;
- когда загорится светодиод, введите код телевизора;
- если вам удалось настроить пульт, светодиод мигнёт дважды, а телевизор выключится. Если устройство продолжает работать, переходите к следующим способам настройки.
Как настроить универсальный пульт вручную?
Есть несколько вариантов последовательности действий. Но в первую очередь надо перейти в режим программирования — зажать кнопку POWER или TV на 5-10 секунд. В зависимости от бренда или модели устройства могут быть использованы сочетания кнопок: POWER и SET, POWER и TV, POWER и C, TV и SET. Чтобы не ошибиться, сверьтесь с инструкцией. Если вам удалось настроить всё правильно, светодиод универсального пульта загорится.
Вариант А
- введите код телевизора;
- попробуйте выключить устройство пультом, переключить каналы или отрегулировать громкость.
Вариант Б
- нажмите кнопку переключения каналов;
- если светодиод мигнёт, вы перейдёте к следующему набору команд;
- нажимайте кнопку переключения каналов до тех пор, пока телевизор не выключится;
- в течение 5 секунд нажмите кнопку OK.
Вариант В
- не отпуская кнопки программирования универсального пульта, нажмите клавишу «9» четыре раза с интервалом около секунды;
- если светодиод мигнёт два раза, положите пульт на ровную поверхность и направьте на телевизор — процедура настройки занимает до 15 минут;
- когда универсальный пульт найдёт подходящий набор команд, телевизор выключится, нужно быстро нажать ОК.
Вариант только для моделей с функцией ручного программирования
- найдите коды для ручной настройки каждой команды в инструкции к телевизору;
- зажмите кнопки для перехода в режим программирования;
- когда светодиод включится, нажмите кнопку, на которую хотите назначить команду;
- через секунду введите код самой команды, например 111 или 101;
- повторяйте, пока вам не удастся настроить все нужные функции.
Вариант только для моделей с функцией автоматического обучения
- положите оригинальный и универсальный пульт друг напротив друга;
- на последнем зажмите кнопку LEARN, SET или SETUP, в зависимости от того, какая из них есть на вашем пульте, на 5–6 секунд;
- когда светодиод начнёт мигать, нажмите кнопку, которую вы хотите настроить;
- сразу после этого нажмите на оригинальном пульте кнопку, функцию которой нужно скопировать;
- повторяйте процедуру настройки для каждой клавиши.
Как сделать смартфон универсальным пультом
Для управления Smart TV установите фирменное мобильное приложение, например Samsung Smart Things или LG Remote. На экране смартфона появятся кнопки, дублирующие функции пульта — можно включить и выключить телевизор из любой точки мира, запустить запись передачи по таймеру, настроить звук и изображение. Похожие приложения доступны и для большинства смарт-приставок, включая Apple TV, Google Chromecast и Xiaomi Mi Box.




Вы также можете сделать Android-смартфон универсальным пультом для обычного телевизора без умных функций. Понадобится гаджет с инфракрасным передатчиком, например Xiaomi или Huawei. Если в смартфоне есть стандартное приложение для управления ИК-портом, начните с него. Если нет, установите одну из этих программ:
- Remote Control for TV
- Smartphone Remote Control
- Universal Remote TV
- Remote Control Pro
- Galaxy Remote
Вначале попробуйте автоматическую настройку. Выберите в меню подходящую модель телевизора, направьте ИК-порт на приёмник ТВ и попробуйте понажимать кнопки на сенсорном экране. Если нужного эффекта нет, введите коды вручную.
Какие телевизоры несовместимы с универсальными пультами?
Модели для американского и азиатского рынка могут использовать другие наборы команд — настроить их автоматически не получится. Есть шанс запрограммировать функции вручную, если вы найдёте таблицу соответствия команд в интернете. Телевизоры Samsung, выпущенные до 2012 года, также используют другие команды — для них нужны универсальные пульты тех же годов производства. Также у вас не получится воспользоваться пультом, если Smart TV принимает команды при помощи Bluetooth, а не инфракрасного сенсора.
Гайд по адресной светодиодной ленте
Данный гайд посвящен адресной светодиодной ленте применительно к использованию с микроконтроллерами (Arduino, esp8266). Рассмотрены базовые понятия, подключение, частые ошибки и места для покупки.
КУПИТЬ АДРЕСНУЮ ЛЕНТУ
Лента WS2812

- Giant4 30 LED
- Giant4 60 LED
- Giant4 144 LED
- AliExpress
- AliExpress
Гибкий профиль

- AliExpress
- AliExpress
- AliExpress
Гирлянда

- Giant4 (РФ)
- Giant4 (РФ)
- AliExpress
Полоски

- AliExpress
- AliExpress
Кольца

- AliExpress
- AliExpress
- AliExpress
Матрицы

- Giant4 16×16
- Giant4 32×8
- AliExpress
- AliExpress
- Black PCB / White PCB — цвет подложки ленты, чёрная / белая
- 1m/5m — длина ленты в метрах
- 30/60/74/96/100/144 — количество светодиодов на 1 метр ленты
- IPXX – влагозащита
- IP30 лента без влагозащиты
- IP65 лента покрыта силиконом
- IP67 лента полностью в силиконовом коробе
ТИПЫ АДРЕСНЫХ ЛЕНТ
Сейчас появилось несколько разновидностей адресных светодиодных лент, они основаны на разных светодиодах. Рассмотрим линейку китайских чипов с названием WS28XX.
Чип Напряжение Светодиодов на чип Кол-во дата-входов Купить в РФ WS2811 12-24V 3 1 30 led, 60 led WS2812 3.5-5.3V 1 1 30 led, 60 led, 144 led WS2813 3.5-5.3V 1 2 (дублирующий) 30 led, 60 led WS2815 9-13.5V 1 2 (дублирующий) 30 led, 60 led WS2818 12/24V 3 2 (дублирующий) 60 led У двухпиновых лент из линейки WS28XX достаточно подключить к контроллеру только пин DI, пин BI подключать не нужно. При соединении кусков ленты нужно соединять все пины!

WS2811 (WS2818) и WS2812
Сейчас популярны два вида ленты: на чипах WS2812b и WS2811 (и новая WS2818). В чём их разница? Чип WS2812 размещён внутри светодиода, таким образом один чип управляет цветом одного диода, а питание ленты – 5 Вольт. Чип WS2811 и WS2818 размещён отдельно и от него питаются сразу 3 светодиода, таком образом можно управлять цветом только сегментами по 3 диода в каждом. А вот напряжение питания у таких лент составляет 12-24 Вольта!


ЧТО ТАКОЕ АДРЕСНАЯ ЛЕНТА
Итак, данный гайд посвящен адресной светодиодной ленте, я решил сделать его познавательным и подробным, поэтому дойдя до пункта “типичные ошибки и неисправности” вы сможете диагностировать и успешно излечить косорукость сборки даже не читая вышеупомянутого пункта. Что такое адресная лента? Рассмотрим эволюцию светодиодных лент.
Обычная светодиодная лента представляет собой ленту с напаянными светодиодами и резисторами, на питание имеет два провода: плюс и минус. Напряжение бывает разное: 5 и 12 вольт постоянки и 220 переменки. Да, в розетку. Для 5 и 12 вольтовых лент нужно использовать блоки питания. Светит такая лента одним цветом, которой зависит от светодиодов.

RGB светодиодная лента. На этой ленте стоят ргб (читай эргэбэ – Рэд Грин Блю) светодиоды. Такой светодиод имеет уже 4 выхода, один общий +12 (анод), и три минуса (катода) на каждый цвет, т.е. внутри одного светодиода находится три светодиода разных цветов. Соответственно такие же выходы имеет и лента: 12, G, R, B. Подавая питание на общий 12 и любой из цветов, мы включаем этот цвет. Подадим на все три – получим белый, зелёный и красный дадут жёлтый, и так далее. Для таких лент существуют контроллеры с пультами, типичный контроллер представляет собой три полевых транзистора на каждый цвет и микроконтроллер, который управляет транзисторами, таким образом давая возможность включить любой цвет. И, как вы уже поняли, да, управлять такой лентой с ардуино очень просто. Берем три полевика, и ШИМим их analogWrit’ом, изи бризи.

Адресная светодиодная лента, вершина эволюции лент. Представляет собой ленту из адресных диодов, один такой светодиод состоит из RGB светодиода и контроллера. Да, внутри светодиода уже находится контроллер с тремя транзисторными выходами! Внутри каждого! Ну дают китайцы блэт! Благодаря такой начинке у нас есть возможность управлять цветом (то бишь яркостью r g b) любого светодиода в ленте и создавать потрясающие эффекты. Адресная лента может иметь 3-4 контакта для подключения, два из них всегда питание (5V и GND например), и остальные (один или два) – логические, для управления.

Лента “умная” и управляется по специальному цифровому протоколу. Это означает, что если просто воткнуть в ленту питание не произойдет ровным счётом ничего, то есть проверить ленту без управляющего контроллера нельзя. Если вы потрогаете цифровой вход ленты, то скорее всего несколько светодиодов загорятся случайными цветами, потому что вы вносите случайные помехи, которые воспринимаются контроллерами диодов как команды. Для управления лентой используются готовые контроллеры, но гораздо интереснее рулить лентой вручную, используя, например, платформу ардуино, для чего ленту нужно правильно подключить. И вот тут есть несколько критических моментов:
ОСОБЕННОСТИ ПОДКЛЮЧЕНИЯ
1) Команды в ленте передаются от диода к диоду, паровозиком. У ленты есть начало и конец, направление движение команд на некоторых моделях указано стрелочками. Для примера рассмотрим ws2812b, у нее три контакта. Два на питание, а вот третий в начале ленты называется DI (digital input), а в конце – DO (digital output). Лента принимает команды в контакт DI! Контакт DO нужен для подключения дополнительных кусков ленты или соединения матриц.

2) Если в схеме возможна ситуация, при которой на ленту не будет подаваться питание 5V, но будет отправляться сигнал с микроконтроллера – лента начнёт питаться от дата-пина. В этом случае может сгореть как первый светодиод в ленте, так и пин контроллера. Не испытывайте удачу, поставьте резистор с сопротивлением 200-500 Ом. Точность резистора? Любая. Мощность резистора? Любая. Да, даже 1/4.

2.1) Если между лентой и контроллером (Arduino) большое расстояние, т.е. длинные провода (длиннее 50 см), то сигнальный провод и землю нужно скрутить в косичку для защиты от наводок, так как протокол связи у ленты достаточно скоростной (800 кГц), на него сильно влияют внешние наводки, а экранирование земляной скруткой поможет этого избежать. Без этого может наблюдаться такая картина: лента не работает до тех пор, пока не коснёшься рукой сигнального провода.

2.2) При подключении ленты к микроконтроллерам с 3.3V логикой (esp8266, ESP32, STM32) появляется проблема: лента питается от 5V, а сигнал получает 3.3V. В даташите указана максимальная разница между питанием и управляющим сигналом, если её превысить – лента не будет работать или будет работать нестабильно, с артефактами. Для исправления ситуации можно:
- Уменьшить напряжение питания ленты до 4.5V, “промышленные” (металлические в дырочку) блоки питания позволяют это сделать (у них есть крутилка).
- Поставить конвертер (преобразователь) уровней с 3.3 до 5V на управляющий сигнал.
- Также я придумал весьма грязный трюк с диодом: первый светодиод в ленте можно запитать от более низкого напряжения через любой кремниевый диод (например 1N4007), а остальные – как обычно. На диоде падает около 0.6V, таким образом сигнал пройдёт через ступеньку повышения 3.3-4.4-5.0V и всё будет работать стабильно. Для этого нужно аккуратно вырезать кусочек дорожки 5V между 1 и 2 светодиодом, подключить питание ко второму, и диодом оттуда же – на первый (см. схему #1 справа).
- Ещё один способ с нашего форума: диодом “приподнять” землю самого микроконтроллера на те же 0,6V. Для этого диод ставится между GND питания катодом и GND микроконтроллера анодом (см. схему #2 справа). Ну и самый правильный способ – конвертация логического уровня при помощи любого PNP транзистора:
3) Самый важный пункт, который почему то все игнорируют: цифровой сигнал ходит по двум проводам, поэтому для его передачи одного провода от ардуины мало. Какой второй? Земля GND. Как? Контакт ленты GND и пин GND Ардуино (любой из имеющихся) должны быть обязательно соединены. Смотрим два примера.


4) Питание. Один цвет одного светодиода при максимальной яркости кушает 12 миллиампер. В одном светодиоде три цвета, итого
36 мА на диод. Пусть у вас есть метр ленты с плотностью 60 диод/метр, тогда 60*36 = 2.1 Ампера при максимальной яркости белого цвета, соответственно нужно брать БП, который с этим справится. Также нужно подумать, в каком режиме будет работать лента. Если это режимы типа «радуга», то мощность можно принять как половину от максимальной. Подробнее о блоках питания, а также о связанных с ними глюках читай здесь.

5) Продолжая тему питания, хочу отметить важность качества пайки силовых точек (подключение провода к ленте, подключение этого же провода к БП), а также толщину проводов. Как показывает мой опыт, брать нужно провод сечением минимум 1.5 квадрата, если нужна полная яркость. Пример: на проводе 0.75 кв.мм. на длине 1.5 метра при токе 2 Ампера падает 0.8 вольта, что критично для 5 вольт питания. Первый признак просадки напряжения: заданный программно белый цвет светит не белым, а отдаёт в жёлтый/красный. Чем краснее, тем сильнее просело напряжение!

6) Мигающая лента создаёт помехи на линию питания, а если лента и контроллер питаются от одного источника – помехи идут на микроконтроллер и могут стать причиной нестабильной работы, глюков и даже перезагрузки (если БП слабый). Для сглаживания таких помех рекомендуется ставить электролитический конденсатор 6.3V ёмкостью 470 мкФ (ставить более ёмкий нет смысла) по питанию микроконтроллера, а также более “жирный” конденсатор (1000 или 2200 мкФ) на питание ленты. Ставить их необязательно, но очень желательно. Если вы заметите зависания и глюки в работе системы (Ардуино + лента + другое железо), то причиной в 50% является как раз питание.

7) Слой меди на ленте не очень толстый (особенно на модели ECO), поэтому от точки подключения питания вдоль ленты напряжение начинает падать: чем больше яркость, тем больше просадка. Если нужно сделать большой и яркий кусок ленты, то питание нужно дублировать медным проводом 1.5 (или больше, надо экспериментировать) квадрата через каждый метр.

КАК ДЕЛАТЬ НЕЛЬЗЯ
Как мы уже поняли, для питания ленты нужен источник 5 Вольт с достаточным запасом по току, а именно: один цвет одного качественного светодиода на максимальной яркости потребляет 0.012 А (12 мА), соответственно весь светодиод – 0.036 А (36 мА) на максимальной яркости. У китайцев есть “китайские” ленты, которые потребляют меньше и светят тускло. Я всегда закупаюсь в магазине BTF lighting (ссылки в начале статьи), у них ленты качественные. Я понимаю, что порой очень хочется запитать ленту напрямую от Ардуино через USB, либо используя бортовой стабилизатор платы. Так делать нельзя. В первом случае есть риск выгорания защитного диода на плате Arduino (в худшем случае – выгорания USB порта), во втором – синий дым пойдёт из стабилизатора на плате. Если всё-таки очень хочется, есть два варианта:
-
Не подключать больше количества светодиодов, при котором ток потребления будет выше 500 мА, а именно 500/32
Вы наверное спросите: а как тогда прошивать проект с лентой? Ведь судя по первой картинке так подключать нельзя! Оч просто: если прошивка не включает ленту сразу после запуска – прошивайте. Если включает и есть риск перегрузки по току – подключаем внешнее питание на 5V и GND.
Wl 2cs что такое
История бренда Christmas Light. Christmas Light — это бренд уникальной коллекции осветительного оборудования для создания праздничной атмосферы, входящий в созвездие новогодних брендов Mister Christmas.

Бизнес-программа по продаже продукции для Нового года. Бизнес-программа по продаже сувенирной и подарочной

На данной странице вы сможете найти подарки, сувениры,промосувениры на которые можно нанести логотип вашей компании.
Mr. Christmas Carousel
alt=»Новогодний свет» width=»560″ height=»315″ /> alt=»Раздел «Гирлянды, дожди, мишура»: подарки и сувениры с логотипом» width=»560″ height=»315″ />


Zynq 7000. Прикручиваем Wi-Fi модуль RTL8822CS с использованием SDIO через EMIO
Наконец-то пришла пора продолжить изучение возможностей платы Zynq QMTech и SoC XC7Z020. Следующая интересная задача, которую я для себя придумал в качестве обучающей — оснастить плату Wi-Fi модулем Realtek RTL8822CS и, если Wi-Fi модуль будет не нужен, а нужна будет ещё одна флешка — вторым портом для SD-карточки. Если интересны подробности того, как я это всё реализовал — добро пожаловать под кат.

Важно! Перед началом повествования, хотелось бы заранее оговориться, что основная цель, которую я преследую при написании этой статьи — рассказать о своем опыте, с чего можно начать, при изучении отладочных плат на базе Zynq. Я не являюсь профессиональным разработчиком под ПЛИС и SoC Zynq, не являюсь системным программистом под Linux и могу допускать какие-либо ошибки в использовании терминологии, использовать не самые оптимальные пути решения задач, etc. Но отмечу, что любая конструктивная и аргументированная критика только приветствуется. Что ж, поехали…
Сформулируем цель и задачи
Итак, у нас есть плата, описанная в этой статье и есть желание прикрутить к ней Wi-Fi модуль Realtek RTL8822CS. Модуль, разумеется, должен корректно инициализироваться в ОС Linux и обеспечить пропускную способность до 150 Мбит\с (с чем связано такое ограничение и именно этой цифрой — ниже). В качестве альтернативного варианта для использования выведенного SDIO — необходимо организовать второй порт для подключения SD-карт.
Исходя из этого можно сформировать несколько задач, решив которые мы можем достигнуть цели:
Проверить возможность выноса линий SDIO через EMIO (т.е. через пины PL-части Zynq) и подготовить bitstream-файл;
Проверить работоспособность SDIO через EMIO в приложении baremetal с использованием microSD-карточки;
Изготовить мезонинные платы для Wi-Fi модуля и смонтировать на них компоненты;
Подготовить First Stage Bootloader, Device Tree Source, U-Boot, Linux Kernel в нужной конфигурации для запуска Wi-Fi модуля;
Подготовить модуль ядра для работы Wi-Fi модуля, а именно модуль cfg80211, который является линуксовым API для 802.11 устройств;
Подготовить модуль ядра 88x2cs, который является драйвером для модуля Wi-Fi RTL8822CS который работает поверх SDIO-шины;
Проверить работоспособность сети, сделать сканы эфира, посмотреть рабочие уровни, сделать замеры скорости downstream/upstream-трафиком через iPerf;
Итак. Перейдем к реализации намеченного, в целом, не выглядит сильно сложно =)
Настройка проекта в Vivado и конфигурация PL
В этой главе я кратко (без скриншотов) опишу процедуру создания нового проекта с акцентами на важных моментах. Если необходима инструкция с картинками — можно обратиться к моим предыдущим статьям.
Открываем Vivado и создаем проект через кнопку Create Project. Откроется мастер настройки нового проекта, быстро пройдемся по шагам.
Даём имя проекту, например SDIO_EMIO и указываем папку сохранения;
Указываем, что это RTL Project, оставляем включенной галочку Do not specify sources at this time;
Находим модель SoC использованного на плате. В моем случае это xc7z020clg400-1;
В левом меню IP Integrator нажимаем Create Block Design и создаем новый дизайн. Назовём его для простоты block_design.
Добавляем примитив процессорной системы Zynq на диаграмму через нажатие правой кнопкой Add IP — ZYNQ7 Processing System. Сразу же выполним предложенные действия от автоматизатора, через команду на зеленом поле Run Block Automation и откроем настройки процессорной системы.
Я заранее сохранил шаблон настроек PS, чтобы в каждом проекте не прописывать всё заново. Взять его можно тут: ссылка на Github. Через меню Presets — Apply Configuration применяем его и сразу переходим в меню Peripherial I/O Pins.
Ставим галочку возле меню SD 1 и проверяем, что выбран вариант подключения через EMIO:

Остальные настройки я оставил без изменений, в т.ч. частоты тактирования SDIO, PL. Получаем следующую картину (если развернуть группу сигнальных линий SDIO_1):

В данном случае нас интересуют линии CLK, CMD и 4 линии DATA, что в общем-то является стандартным набором для SDIO-шины. Но вот незадача, каждая из линий организована тремя отдельными сигналами. Для решения этой задачи нам необходимо руками создать буфер IOBUF, который будет управляться через активный пин T с тремя состояниями и разрулит Input, Output сигналы как нам нужно для использования его с двунаправленным сигналом I/O. Выглядит он следующим образом:

Т.к. в стандартной библиотеке графических примитивов он отсутствует — нужно будет создать свой IP-модуль и добавить его на схему. Для каждого из сигнала он будет свой.
Через меню Sources — Add Sources (Alt + A) добавляем Design Source — Create File, выбираем тип файла Verilog и назовём его iobuf_cmd.
Запишем следующее содержимое:
То же самое сделаем для сигнала CLK, только файл назовём iobuf_clk. Запишем в него следующее содержание:
С SDIO DATA немного сложнее т.к. она состоит из нескольких линий. Так же создадим файл iobuf_data и запишем в него следующее содержимое:
Для каждой из линии создается свой экземпляр примитива IOBUF.
Поочередно размещаем добавленные модули на диаграмму через клик правой мышкой по Diagram — Add Module. Соединяем сигналы с нужными портами и получится следующее:

Хотелось бы обратить внимание на две важные вещи:
На порт iobuf_t модуля для сигнала CLK я добавил Constant с шириной в 1 бит и со значением 0, т.к. управляющего T-пина для CLK не предусмотрено;
Сделал порты iobuf_io как External и дал им соответствующие названия;
Соединил порты Input с портами Output;
На текущем этапе можно запустить синтез и назначить выходы портов на реальные физические порты. Для этого нужно:
Нажимаем на меню block_design правой кнопкой и выбираем команду Create HDL Wrapper.
В меню IP Integrator выбираем Generate Block Design;
Выбираем Synthesis Option — Global и нажимаем Apply, затем Generate.
Дожидаемся окончания генерации;
Выбираем Run Synthesis для старта синтеза нашего дизайна.
Дожидаемся окончания синтеза;
После окончания синтеза переходим в меню Open Synthesized Design и откроется меню Package с нижним меню I/O Ports. Далее необходимо:
Отметить подходящие физические I/O пины
Убедиться, что включена подтяжка PULLUP на всех пинах кроме CLK;
В моем случае получается следующее:

Сохраняем настройки, будет предложено создать файл с constraints. Называем его как удобно и нажимаем Ok. После нажимаем Generate bitstream, соглашаемся с тем, что синтез устарел и ждем окончания всех необходимых процедур до получения сообщения:

После этого можем экспортировать BSP в SDK и запустить проверку работоспособности SDIO в baremetal. Делается это через меню File — Export — Export Hardware, ставим Include bitstream. Нажимаем Ok и запускаем SDK через команду File — Launch SDK.
Проверка SDIO через microSD-карту в Baremetal
Прежде чем приступить к проверке необходимо подключить microSD-карту к пинам, которые мы размечали в следующем разделе. Смотрим в первую очередь на распиновку microSD-карты:

С пинами VDD (3.3V) и VSS (GND) всё в целом понятно. С другими пинами есть нюанс, для пина CMD и шины DATA требуется подтяжка к высокому уровню через 10 кОм резисторы. В моем случае, чтобы не городить навесным монтажом резисторы, я взял одну из плат, заготовленных для Wi-Fi модуля и запаял на него все что нужно:

Если посмотреть на принципиальную схему этой платы — все выглядит вот таким образом:

Питание подключено напрямую в соответствии с тем, как оно выведено на гребенку. Для удобства отладки логическим анализатором — я подпаивал МГТФ-проводки.
После того, как все необходимые линии подключены — можно вернуться в SDK к созданию проекта. После запуска SDK обзываем проект SDIO_EMIO и нажимаем Next, выбираем шаблон проекта Hello World.

Открываем файл helloworld.c из древа проекта и пишем в него следующий код, который подключит нужные библиотеки и поможет нам быстро сделать проверку:
Кликаем правой кнопкой по проекту SDIO_EMIO и выбираем Build Project. Смотрим, что проект собирается без проблем. Важный момент — выбрать правильный SDIO-контроллер в строке SdConfig = XSdPs_LookupConfig(XPAR_XSDPS_1_DEVICE_ID);
Подключаем JTAG-отладчик и после сборки проекта заливаем bitstream-файл выполнив команду Xilinx — Program FPGA и дожидаемся сигнала FPGA DONE на плате.
Открываем Serial Port, который принадлежит нашей плате. Например: minicom -D /dev/ttyUSB0. Узнать какой порт принадлежит плате можно запустив команду udevadm monitor | grep ttyUSB и выткнуть-воткнуть miniUSB кабель из платы. Там можно увидеть сообщения по которым можно понять какой у нас порт. Например:
После запускаем проект также кликнув по корневому значку проекта выбрав меню Run As — Launch on hardware (System Debugger). В выводе в консоль мы должны увидеть следующее:

Что означают эти сообщения? Это значит, что драйвер успешно “достучался” до карточки и может спокойно начать с ней обмен. Значит наш SDIO-контроллер работает. Идём дальше.
Трассировка и изготовление мезонинных плат для Wi-Fi модуля
Следующим шагом нужно подготовить платы, на которые я запаяю радиомодуль, со всей необходимой обвязкой. В качестве первого радиомодуля был взят модуль от FN-Link с Realtek RTL8822CS чипом, модель модуля 6222B-SRC. Подробнее можно посмотреть тут, ссылка на Datasheet.
Кратко скажу, что это простой MIMO 2×2 Dual Band модуль Wi-Fi с поддержкой 802.11ac и Bluetooth 4.2 или 5.0 в зависимости от модели.
Так как модуль мы будем подключать к гребенке PLS на плате с шагом в 2.54мм. — было решено сделать такой же разъем и на мезонинной плате.
Распиновка со стороны платы:

Распиновка со стороны модуля:

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

Всё в целом достаточно примитивно и в соответствии с референсной схемой и небольшими изменениями, такими как пин включения\выключения питания модуля и прочих мелких доработок. Антенный тракт было решено вывести на u.FL-разъем, для удобства и возможности подключения любых подходящих для 2.4/5ГГц антенн.
Получившиеся платы достаточно просты в трассировке и не представляют собой никакого технического ноу-хау, но линии данных нужно выровнять т.к. SDIO-шина тут достаточно скоростная, чтобы пренебречь таким важным аспектом трассировки.
Результат трассировки в 2D:

Результат трассировки в 3D:



Вид платы после монтажа компонентов:

Т.к. плата изначально разрабатывалась не только для этой версии Wi-Fi модуля — остались не установленными некоторые компоненты.
В целом можно переходить к подготовке всего необходимого для работы с радиомодулем с точки зрения основных управляющих сигналов и подготовки необходимых файлов для работы радиомодуля в Linux. Об этом в следующих главах.
Небольшое дополнение проекта в Vivado
Для того, чтобы была возможность запустить радиомодуль необходимо соблюсти два условия:
Подать низкое напряжение на затвор P-канального ключа VT1, т.е. на линию WL_BT_ON, чтобы подать питание на радиомодуль;
Подать высокое напряжение на ножку WL_REG_ON радиомодуля, чтобы запустить его;
Поэтому на этом этапе нам будет нужно слегка модернизировать проект и добавить 2 сигнала с AXI GPIO-контроллера и завести их на соответствующие ножки:
Для транзисторного ключа это ножка 11 на общей гребенке, что соответствует физическому пину W20;
Для сигнала WL_REG_ON это 25-я ножка на той же гребенке, что соответствует в моем случае пину V17;
Как работать с AXI GPIO Я рассказывал в этой статье и на деталях повторяться не буду. В нашем случае нужно выполнить лишь несколько шагов:
Добавляем в дизайн IP-модуль AXI GPIO;
Выполняем предложенные шаги автоматизации предложенные Vivado, отметив все галочки;
Появится блок AXI GPIO, необходимо зайти в его опции и поставить галочку All Outputs, поставить ширину шины GPIO Width в значение 2 (нужно 2 сигнала) и в Default Output вписать 0x00000002, чтобы по умолчанию после загрузки bitstream-файла оба пина приняли необходимое значение;
Называем External Interface от AXI GPIO как MGMT_GPIO и сохраняемся. Должно получиться следующее:
Синтезируем дизайн, проверяем, что всё прошло успешно;
Переходим в меню Open Synthesized Design и назначаем MGMT_GPIO[0] пин W20, а MGMT_GPIO[1] пин V17;
Изменяем у этих двух пинов I/O Std на LVCMOS3.3 и сохраняем;
Запускаем генерацию bitstream-файла через Generate bitstream;
Экспортируем сгенерированный bitstream и всё что необходимо для дальнейших шагов через команду File — Export — Export Hardware;
Все изменения, необходимые на этом этапе мы внесли. Переходим к подготовке всего необходимого для работы с радиомодулем в Linux;
Подготовка FSBL, Device Tree Sources, U-Boot
На этом этапе можно переходить к созданию загрузчиков, файлу описания железа и компиляции ядра Linux. Многие моменты и детали Я целенаправленно опущу т.к. уже рассказывал в предыдущей статье а отличающимся моментам посвящу основную часть повествования.
Первым этапом надо подготовить FSBL. Для этого нужно:
В меню Xilinx SDK переходим в меню File — New — Application Project;
Именуем его как FSBL;
Нажимаем клавишу Next;
Из заготовок выбираем Zynq FSBL;
Дожидаемся окончания компиляции и проверяем, что появился файл FSBL.elf
Вторым этапом необходимо подготовить Device Tree Source/Blob файл который будет использован для сборки U-Boot. Для этого сделаем следующее:
Добавляем BSP Repository из репозитория device-tree-xlnx. Для этого нужно выбрать меню Xilinx — Repositories и указать папку с device-tree-xlnx в секцию Global Repositories.
Добавляем BSP Project через меню File — New — Board Support Package, даём ему имя и выбираем внизу меню device_tree и в следующем меню нажимаем Ok, если не требуется внесения каких-либо изменений.
Выполним редактирование файла zynq-7000.dtsi и находим секцию описывающую SDIO1 в строке sdhci1: mmc@e0101000;
Дополняем секцию следующим содержанием (файл можно взять тут) :

Переходим в папку с сгенерированными dts-файлами в системной консоли:
Компилируем в blob:
Всё. Device Tree готов.
Следующим этапом необходимо подготовить U-Boot для нашей платы. Нужно выполнить несколько простых шагов:
Перейти в папку с U-Boot: cd u-boot-xlnx
Задать переменные для кросс-компиляции: export CROSS_COMPILE=arm-linux-gnueabihf-; export ARCH=arm
Очистить сырцы от предыдущих результатов компиляции и применить конфиг для Zynq по умолчанию: make distclean; make xilinx_zynq_virt_defconfig
Положить в папку с U-Boot полученный в предыдущем шаге system.dtb в папку arch/arm/dts/ c именем zynq-qmtech.dtb
Указываем какой Device Tree файл использовать: export DEVICE_TREE=»zynq-qmtech»
Далее необходимо зайти в меню конфигуратора и изменить ряд опций: make menuconfig
Опция для того, чтобы активировать поддержку AXI GPIO, которая используется для включения питания модуля и подачи сигнала WL_REG_ON на радиомодуле: Device Drivers — GPIO Support — Xilinx GPIO Driver
Сохраняем конфиг (можно взять тут) в файл .config
Запускаем сборку: make -j$(nproc) и дожидаемся окончания компиляции;
После этого можно скомпоновать FSBL, Bitstream-файл и U-Boot в один загрузочный файл BOOT.BIN. Подробное описание компоновки можно найти в моей прошлой статье. В целом надо выполнить несколько простых шагов:
Найти файл в каталоге с проектом First stage bootloader. По умолчанию он находится в SDIO_EMIO/SDIO_EMIO.sdk/FSBL/Debug/FSBL.elf
Найти Bitstream-файл для программируемой логики. Найти его можно в каталоге SDIO_EMIO/SDIO_EMIO.sdk/block_design_wrapper_hw_platform_0/block_design_wrapper.bit
Найти бинарный файл U-Boot. Данный файл после компиляции лежит в папке с U-Boot: u-boot-xlnx/u-boot.elf
Открываем в Xilinx SDK пункт меню Xilinx — Create Boot Image;
Выбираем куда сохранить новый bif-файл, я его сохраняю в корневом каталоге проекта;
Добавляем поочередно файлы FSBL.elf, block_design_wrapper.bit, u-boot.elf в секцию Boot Image Partitions;
Нажимаем Create Image и видим как в каталоге с bif-файлом появляется BOOT.BIN;
Теперь необходимо залить этот файл на загрузочную SD-карту и можно попробовать загрузиться. Если мы видим приглашение от U-Boot и что светится светодиод FPGA DONE — значит мы всё выполнили правильно.

Можно перейти к проверке того, проинициализирован ли AXI GPIO в U-Boot и проверим их. Для этого сначала выведем список устройств которые проинициализированы. Это можно сделать через команду dm tree.

Отлично. Видно, что у нас на борту есть два SDIO-контроллера, и два GPIO-контроллера. Попробуем изменить состояние ножки транзистора. Для этого нужно:
Посмотреть какие адреса в GPIO доступны и какие отвечают за те, или иные ножки: gpio status -a
В конце вывода видно, что есть Bank GPIO с двумя ножками, которые соответствуют значению по умолчанию:
Проверки ради можно изменить состояние ножки gpio@412000000 через команду: gpio toogle gpio@412000000 или gpio set gpio@412000000 / gpio clear gpio@412000000 для установки логической 1 или 0 соответственно
Так. Загрузчик подготовлен. Теперь можно переходить к подготовке ядра Linux и RootFS со всем необходимым для нас содержимым
Компиляция ядра Linux и подготовка RootFS с использованием Buildroot
Так же как и прошлых главах, для исключения необходимости подробного объяснения каждого шага, сошлюсь на предыдущую статью как скомпилировать ядро Linux. Перейдем к выполнению шагов, необходимых для сборки ядра с необходимыми модулями и драйверами. Для этого нужно:
Перейти в папку с клонированным репозиторием linux-xlnx;
Обновить его (при необходимости): cd linux-xlnx; git fetch -p; git checkout master; git pull;
Экспортируем также переменные для кросс-компиляции: export CROSS_COMPILE=arm-linux-gnueabihf-; export ARCH=arm
Делаем очистку от результатов предыдущих сборок: make distclean
Загружаем дефолтный конфиг: make ARCH=arm xilinx_zynq_defconfig;
Изменим дефолтный конфиг загрузив меню конфигурации: make ARCH=arm menuconfig
Изменим опции конфигурации (можно взять тут) , устанавливаем опцию (проследим, что там вместо [M] в поле выбора стоит символ звездочки [*] : Networking Support — Wireless — cfg80211
Сохраняем конфиг в файл .config и выходим из меню конфигурации;
Запускаем процесс компиляции: make ARCH=arm UIMAGE_LOADADDR=0x8000 uImage -j8
Компилируем модули ядра: make ARCH=arm -j8 modules
Копируем uImage из каталога linux-xlnx/arch/arm/boot/ на загрузочную SD-карту;
Далее необходимо подготовить образ RootFS с всеми необходимым userspace-утилитами, типа wpa_supplicant, wpa_cli, etc. Собирать RootFS будем с помощью системы сборки buildroot, статью о которой я писал до этого. Итак, перейдем к сборке, для этого нужно:
Заходим в папку с buildroot: cd buildroot
Обновляем его до последней версии: git fetch -p; git checkout master; git pull;
Делаем очистку от результатов предыдущих сборок: make distclean
Запускаем меню конфигурации: make -C /home/megalloid/buildroot O=$PWD ARCH=arm nconfig
Изменяем опции конфигурации по списку ниже;
Опция 1: Target options — Target Architecture — ARM (little endian)
Опция 2: Target options — Target Architecture Variant — cortex-A9
Опция 3: Target options — Enable NEON SIMD extension support — [*]
Опция 4: Target options — Enable VFP extension support — [*]
Опция 5: Target options — Target ABI — EABIhf
Опция 6: Target options — Floating point strategy — NEON
Опция 7: Build options — Number of jobs to run simultaneously — 8 (по количеству ядер CPU)
Опция 8: Toolchain — C library — glibc
Опция 9: Toolchain — Kernel headers — Custom Git Repository
Опция 10: Toolchain — URL of custom repository — </home/megalloid/linux-xlnx>
Опция 11: Toolchain — Custom repository version — <хэш-сумма от git show-ref | grep master из папки linux-xlnx>
Опция 12: Toolchain — Custom kernel headers series — 5.15.x
Опция 13: Toolchain — Install glibc utilities — [*]
Опция 14: Toolchain — GCC compiler Version — gcc 9.x
Опция 15: Toolchain — Enable C++ support — [*]
Опция 16: Toolchain — Enable compiler link-time-optimization support — [*]
Опция 17: Toolchain — Enable compiler OpenMP support — [*]
Опция 18: Target packages — Miscellaneous — haveged
Опция 19: Target packages — Networking applications — dhcpd
Опция 20: Target packages — Networking applications — dropbear
Опция 21: Target packages — Networking applications — ifupdown scripts
Опция 22: Target packages — Networking applications — hostapd
Опция 23: Target packages — Networking applications — iperf
Опция 24: Target packages — Networking applications — iperf3
Опция 25: Target packages — Networking applications — fping
Опция 26: Target packages — Networking applications — iw
Опция 27: Target packages — Networking applications — iwd
Опция 28: Target packages — Networking applications — wpa_supplicant
Опция 28: Target packages — Networking applications — wireless tools
Опция 29: Filesystem images — cpio the root filesystem — [*]
Опция 30: Filesystem images — Compression method — lzma
Опция 31: Host Utilites — host dosfstools
Опция 32: Host Utilites — host genimage
Опция 33: Host Utilites — host mtools
После этой длительной конфигурации выбираем Save и сохраняем конфиг (можно взять тут и подложить к себе);
Нажимаем F9 и запускаем процесс сборки: make -C /home/megalloid/buildroot O=» >PWD ARCH=arm BR2_JLEVEL formula inline» source=»((» alt=»((» src=»https://habrastorage.org/getpro/habr/upload_files/e5d/55b/77d/e5d55b77d535464756de9815f50f4c6a.svg» width=»15″ height=»24″/>(nproc) — 1))»
Ждём когда закончится компиляция, самое время заварить и выпить кофе =)
Теперь когда образ RootFS собрался надо его подписать и привести к виду, в котором его сможет корректно переварить U-Boot:
Переходим в папку с готовыми образами: cd buildroot/images
Производим подпись: mkimage -A arm -T ramdisk -C gzip -d rootfs.cpio uramdisk.image.gz
Складываем uramdisk.image.gz на загрузочную SD-карту;
Настраиваем загрузку образов в U-Boot:
Надо загрузиться в консоль U-Boot и записать туда: setenv mmc_boot “fatload mmc 0 0x2000000 uramdisk.image.gz; fatload mmc 0 0x4000000 uImage; fatload mmc 0 0x4500000 system.dtb; bootm 0x4000000 0x2000000 0x4500000;”
Сохраняем эту переменную через saveenv и перезагружаемся;
Дожидаемся загрузки ОС;
Теперь можно переходить к компиляции драйвера и непосредственно настройке Wi-Fi модуля.
Компиляция модуля ядра 88х2cs для Wi-Fi модуля
Переходим к последнему элементу, необходимому для работы Wi-Fi модуля — драйверу нашего Wi-Fi модуля. На просторах GITHUB я нашел вполне себе собираемый и рабочий вариант драйвера. Чтобы собрать драйвер out-of-tree нужно сделать следующее:
Переключим ветку на версию драйвера совместимую с 5.15: git checkout tune_for_jethub_5_14
Запускаем компиляцию: make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KSRC=»/home/megalloid/linux-xlnx» (где KSRC — путь до папки с ядром LInux из предыдущего шага);
На выходе мы получим в этой папке файл 88x2cs.ko, его нужно положить туда же на загрузочную SD-карту;
Проверяем, загрузится ли модуль ядра и появится ли wlan-интерфейс:
Монтируем SD-карту в файловую систему: mount /dev/mmcblk0p1 /mnt
Переходим в каталог SD-карты: cd /mnt/
Выполняем insmod 88x2cs.ko для загрузки модуля ядра;
Запускаем программу ifconfig — и видим, что появился wlan0 интерфейс:

Это говорит о том, что модуль ядра успешно загрузился и готов к работе. В следующей главе перейдем к настройке wlan0 интерфейса и проверке работоспособности Wi-Fi, прогону скорости через iPerf;
Настройка Wi-Fi интерфейса и измерение скорости с использованием iPerf
Для настройки Wi-Fi необходимо первым делом создать конфиг, удобнее всего в этом случае его создать на SD-карте в виде файла wpa_supplicant.conf.
Выполним в консоли Zynq следующие команды:
Создадим файл конфигурации: touch /mnt/wpa_supplicant.conf
Открываем его на редактирование: vi /mnt/wpa_supplicant.conf
Записываем в него следующее содержимое и сохраняем:
Запускаем wpa_supplicant: wpa_supplicant -B -Dnl80211 -iwlan0 -c/mnt/wpa_supplicant.conf -P/var/run/wpa_supplicant.pid -dd -f/mnt/wpa_supplicant.log
Через некоторое время появится IP-адрес на интерфейсе wlan0 и будет установлена связь с роутером;
Теперь можно прогнать трафик с компьютера (который подключен к роутеру кабелем) на Zynq и обратно. Для этого нужно:
Запустить на компьютере: iperf3 -s
Запустить на Zynq: iperf3 -c <IP компьютера> -N -i1 -t60 -u
Чтобы пустить трафик в обратном направлении на Zynq нужно выполнить: iperf3 -c <IP компьютера> -N -i1 -t60 -R -u
Скорость в целом соответствует заявленным Xilinx цифрам: около 20 Мбайт\сек (около 150 Мбит\с). В итоге если будем иметь подходящие условия в эфире — эта скорость будет максимальной и в 2.4 ГГц и 5 ГГц. Результат соответствует всем ожиданиям.
Подведем итог
После длительного кропотливого исследования без каких-либо how-to удалось обуздать эту железку. На общую проработку этого всего ушло около недели, что в целом доставило немало удовольствия по мере продвижения к решению задачи. Буду надеяться, что мой опыт кому-нибудь пригодится и будет высоко оценен. Спасибо!
Советы по настройке Larnitech
У меня сейчас активный период настройки нескольких систем Larnitech, я даже сделал отдельную страницу по этой услуге.
Настраивать с ноля систему Larnitech, уже установленную на объекте, крайне неудобно. Как, разумеется, и любую другую систему, особенно на шине.

Я немного замучил вопросами техподдержку, зато разобрался во многих моментах касательно настройки и нашёл, как работать с оборудованием проще. Что-то покажется вполне очевидным, до чего-то удалось дойти не сразу.
Сначала обновите программное обеспечение
Первым делом после подключения к новому контроллеру надо обновить программное обеспечение. Уже несколько раз мне поступали вопросы о том, почему что-то в системе на этапе первичной настройки работает не так, все проблемы решились обновлением ПО.
В web интерфейсе контроллера (в браузере) надо выбрать пункт меню «Обновления», там обновить до последних доступных версий LT Setup и LT Server. И нажать кнопку «установить заплатки безопасности».
На картинке ниже у LT Setup установлена версия 1.30, доступна более новая 1.91, нажимаем справа кнопку Обновить и ждём пару минут, всё произойдёт автоматически.

API Plugin отвечает за работу системы с голосовым помощником Siri. Все прочие пункты (Coolmaster, EIB и далее) устанавливаем и поддерживаем в актуальном состоянии только если соответствующие функции используются.
Далее заходим в Модули и смотрим, не предлагается ли обновить прошивку контроллера и подключенных модулей на релизной. Если доступно, то обновляем.
Редактор логики
Редактор логики находится в пункте интерфейса «Структура», кнопка «Редактировать логику».
Если в нём разобраться, то мы получим возможность гораздо быстрее выполнять настройку названий элементов и комнат. Хоть визуальное меню редактирования структуры тоже достаточно наглядное и удобное, но как минимум названия выходов и входов удобнее менять здесь.

А ещё в редакторе логики удобно быстро задавать назначение каждого входа и выхода. Нужно найти строчку с ID элемента :98.

Сразу видно назначение выходов модуля: L это лампа, B — штора, K — замок. В документации на wiki есть все возможные обозначения входов и выходов.
Съёмные клеммники
Клеммники подключения шины на всех модулях Larnitech, а также на датчиках CW-CO2 и CW-HTML — съёмные. Если надо переключить модуль, то проще всего снять клеммник и переставить на другой модуль, а не выдергивать проводки шины и питания.

Вот казалось бы, что это очевидно, а до меня дошло только на третьей системе. Вместо того чтобы разбирать все соединения и собирать потом заново, можно просто снять шину вместе с клеммниками и переставить на другие модули.
Настройка BW-SW06 и датчиков температуры
При подключении датчика температуры пола стандарта 1-wire (это FW-FT и FW-TS) к модулю BW-SW06 на контакт G подключается земля, на контакт 1 — сигнал, а на 2 — питание.
У FW-FT земля чёрная, сигнал жёлтый, а питание красное.
У FW-TS чуть сложнее: земля зелёная, сигнал бело-оранжевый, а питание оранжевое.

При настройке работы модуля BW-SW06.B мы задаём на вход 1 датчик температуры, а поле назначения входа 2 автоматически меняется на «Питание». Но вот с более новым модулем BW-SW06.C мы не можем выбрать «Питание», его нет в списке вообще.

Если замкнуть жилу питания на контакт GND, то датчик работает и показывает температуру, но нестабильно: чуть тронешь его, и показания пропадают. Если не подключать питание вообще, то датчик показывает ерунду: то -15 градусов, то +30.
Для решения проблемы заходим в меню «Структура», нажимаем «Редактировать логику». Находим строчку с номером модуля :98, и задаём для него настройку hw=»in=’T+BBBB’». То есть, принудительно задаём, что второй вход это +. Датчик подключаем как по инструкции.

Подключение датчиков протечки воды к DW-SW16
Для подключения датчиков протечки воды обычно используется модуль DW-WL02, к нему можно подключить до 16 датчиков протечки воды и 2 группы кранов. Иногда нам удобнее поставить для подключения датчиков протечки воды модуль дискретных входов DW-SW16, но при его настройке нам не задать в меню настроек HW назначение входа как «датчик протечки». Что делать?
Снова лезем в настройки логики и задаем тип входа L — leak. На скриншоте первые 9 входов модуля выключатели, далее 6 датчиков протечки воды. Последний вход — GND всех датчиков и выключателей.

Датчики протечки воды Larnitech работают не так, как обычные датчики, они периодически посылают сигнал автотеста кратковременным замыканием тревожного выхода. Так что при настройке его как геркон мы будем получать тревогу «Обрыв», так как геркон не посылает сигнал автотеста.
Пропали скрипты
В Larnitech большая база готовых стандартных скриптов для разных потребностей. Но вот мы заходим в меню Сценарии, нажимаем «Добавить скрипт», а список скриптов пустой. Что делать?
Нужно зайти в меню Обновления, найти там Scripts и нажать Переустановить. Хотя они и так установлены.

Но нажимаем, ждём загрузку, далее снова заходим в Сценарии, и список скриптов на месте.

Серийные номера модулей и датчиков
На всех датчиках и модулях есть серийный номер на серебристой наклеечке со штрих-кодом. Он продублирован также на такой же наклейке на коробке.

По этому серийному номеру можно идентифицировать модуль или датчик. Но если модуль можно идентифицировать и более просто, нажав на соответствующую кнопку в списке модулей (он начнёт мигать светодиодами), то на датчиках светодиодов нет, тут найти, где какой датчик, сложнее.
Эти самые серийные номера элементов можно посмотреть, почему-то, только в том же незаменимом редакторе логики. Нужно найти строчку <item addr=»ID:98 …>, там будет вписан серийный номер (sn). Эти номера я в рамках преднастройки системы переписываю в таблицу с цоколёвкой контроллера Larnitech.

Обновление прошивок модулей
Лучше всего все модули и датчики обновлять до прошивки «Релиз». Но иногда есть необходимость (например, по указанию техподдержки) обновить элемент до прошивки «Альфа» или «Бета». Просто так это не сделать. Нужно зайти в меню «Общие» и сдвинуть ползунок настроек обновления на «Advanced», это даст нам возможность выбора прошивки для обновления.
Перезагрузка контроллера
В процессе изменения ID устройств (а я люблю, когда ID модулей в щите нумеруются по порядку, так удобнее впоследствии) устройство с новым ID может не появляться в списке устройств. Сначала дайте системе немного времени: подождите секунд 10-15 и нажмите F5 для обновления списка модулей. Но если обновление списка модулей не помогает, нужно перезагрузить LT Setup, это можно сделать в меню Перезагрузка. Перезагрузка занимает порядка 10 секунд. Дёргать питание контроллера не нужно.
Ставим автоматы или предохранители на питание датчиков
При установке датчиков лучше отключать питание шины датчиков, чтобы случайное замыкание проводов не привело к отключению всего блока питания.
Если у нас в системе не стоит отдельный блок питания на датчики, а контроллер и датчики питаются от одного блока, лучше питание датчиков подключить через автомат, который можно было бы отключать при необходимости. Если от контроллера идёт 2 шины или больше шины датчиков, то ставим отдельные автоматы на разные шины, чтобы отключать только то, с чем собираемся работать.
Но вообще, система поддерживает «горячее» (без отключения питания) переподключение модулей отлично. В приложении Larnitech сразу отображаются подключенные элементы, даже если в списке устройств в web интерфейсе контроллера они не появились.
Хочу отдать должное контроллерам Larnitech. В процессе настройки нескольких систем, когда приходится много добавлять, убирать, переподключать, переименовывать модули, обновлять разные программные блоки, ни разу не возникало никаких зависаний контроллера, необходимости его полной перезагрузки или отказа интерфейса.
Sorry, you have been blocked
This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.
What can I do to resolve this?
You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.
Cloudflare Ray ID: 75b6d43fd87a77f1 • Your IP: Click to reveal 155.133.64.137 • Performance & security by Cloudflare
