Русский
Русский
English
Статистика
Реклама

Из песочницы Знакомство с FPGA iCE40 UltraPlus Mobile Development Platform от фирмы Lattice Semiconductor

Введение


Всем доброго времени суток, друзья! Недавно на работе обзавелись новенькой навороченной платой iCE40 UltraPlus Mobile Development Platform от фирмы Lattice Semiconductor. Со слов разработчиков на официальном сайте iCE40 UltraPlus MDP это плата, на которой расположены 4 ПЛИС iCE40 UltraPlus, каждая из которых управляет своим набором периферии. В набор входят:

  • мобильный дисплей с разрешением 240x240 с интерфейсом MIPI DSI;
  • датчик изображения с разрешение 640x480 (OVM7692);
  • малопотребляющие микрофоны в количестве 4 штук;
  • BLE модуль для беспроводной передачи данных;
  • программируемая SPI Flash память;
  • пак различных датчиков (давления, компас, гироскоп и акселерометр);
  • ну и всякие кнопочки и лампочки.

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

UltraPlus MDP




В качестве тестового примера, поморгаем RGB светодиодом (D13 на схеме, выделено красным на картинке слева). Просмотрев документацию, делаем вывод, что светодиод управляется ПЛИСом под номером U3 (выделено красным на картинке справа). Из документации также узнаем, что светодиод управляется встроенным ШИМ модулятором и токовым драйвером.

Данную информацию берем на заметку.

Настройка платы и написание программы


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



Порядок действия следующий:

  1. Перевести переключатель SW5 в положение ON/OFF
  2. Две перемычки на J19 горизонтально
  3. Установить на J26 перемычки так, чтобы замкнуть пины 1-2 и 3-4 (как указано на рисунке. Начало следования пинов начинается с белой стрелочки, указанной на плате)
  4. На джамперах J17, J25, J27 установить перемычки в положение 9-10 (но это вроде необязательно)

Да, понимаю, это все нудно, но без этого не заработает.

Также, чтобы подключить генератор тактовых сигналов необходимо установить перемычку джампера J23 в положение 2-3 (нумерация идет сверху).



Теперь программа. Для создания битового файла для прошивки iCE40 UltraPlus MDP необходима среда разработки Lattice iCE cube 2 (ссылочка на страницу с продуктом) и для прошивки самой платы Programmer and Deployment Tool. Продукт лицензионный, но после регистрации лицензию можно получить здесь www.latticesemi.com/Support/Licensing/DiamondAndiCEcube2SoftwareLicensing/iceCube2

Редактор в IDE весьма неудобный, поэтому я писал в Sublime Text, но каждому свое.

Вот общая схема, которая давала понимание что и куда надо делать:



Вот и всплыли ШИМ модулятор и токовый драйвер, о которых я упоминал ранее. Эти два устройства являются внутренними модулями. Необходимо написать устройство управления логики и отправки данных, чтобы вся эта кухня правильно работала. Начнем по порядку, описываем черный ящик:

entity DriverRGB isport (-- RGB Led:LED0 : out std_logic;LED1 : out std_logic;LED2 : out std_logic );end DriverRGB;

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

-- Generator clock:component SB_HFOSC isgeneric (CLKHF_DIV: string := "0b00" );port (CLKHFPU: in std_logic;CLKHFEN: in std_logic;CLKHF : out std_logic );end component;

imageДанный модуль может генерировать сигнал с частотами 48МГц, 24МГц, 12МГц и 6МГц. За коэффициент деление частоты отвечает параметр CLKHF_DIV (0b00, 0b01, 0b10, 0b11 соответственно). CLKHFPU и CLKHFEN разрешение работы модуля. CLKHF тактовый сигнал.

Далее объявляем ШИМ модулятор и токовый драйвер:

-- Embedded PWM IP:component SB_LEDDA_IP isport (LEDDCS: in std_logic;LEDDCLK: in std_logic;LEDDDAT7: in std_logic;LEDDDAT6: in std_logic;LEDDDAT5: in std_logic;LEDDDAT4: in std_logic;LEDDDAT3: in std_logic;LEDDDAT2: in std_logic;LEDDDAT1: in std_logic;LEDDDAT0: in std_logic;LEDDADDR3: in std_logic;LEDDADDR2: in std_logic;LEDDADDR1: in std_logic;LEDDADDR0: in std_logic;LEDDDEN : in std_logic;LEDDEXE: in std_logic;LEDDRST: in std_logic;PWMOUT0: out std_logic;PWMOUT1: out std_logic;PWMOUT2: out std_logic;LEDDON: out std_logic );end component;

-- RGB Driver:component SB_RGBA_DRV isgeneric (CURRENT_MODE: string := "0b0";RGB0_CURRENT: string := "0b000000";RGB1_CURRENT: string := "0b000000";RGB2_CURRENT: string := "0b000000" );port (CURREN: in std_logic;RGBLEDEN: in std_logic;RGB0PWM: in std_logic;RGB1PWM: in std_logic;RGB2PWM: in std_logic;RGB0 : out std_logic;RGB1 : out std_logic;RGB2 : out std_logic );end component;

imageШИМ модулятору необходимо скормить адрес и данные, которые отвечают за режимы работы светодиода и некоторые управляющие сигналы. Выходы затем обрабатываются токовым драйвером RGB, который уже зажигает светодиод.

Токовый драйвер обрабатывает данные с ШИМ модулятора и регулирует значения тока подтягиваемое к светодиоду. Параметры RGB0_CURRENT, RGB1_CURRENT, RGB2_CURRENT задают величину тока к каждому цвету. CURRENT_MODE режим питания (полный или половинный).

image

Да, круто. Есть адреса, есть данные. Ну а что на них отправлять? В общем, разработчики Lattice в своей документации дают достаточно подробное описание, но оно весьма объемное. Постараюсь сжать все в несколько строчек описания и код для наглядности.

ШИМ модулятор ожидает 9 адресов. Каждый из них отвечает за определенную функцию для поддержания работы светодиода. Ниже приведена таблица, в которой указаны значения и названия адресов:



Для отправки данных реализуем автомат конечных состояний:

type LED_Driver is (IDLE, LEDDBR, LEDDONR, LEDDOFR, LEDDBCRR, LEDDBCFR, LEDDPWRR, LEDDPWRG, LEDDPWRB, LEDDCR0, DONE);

Первым шагом запишем данные в регистр LEDDBR. В него записывается значение для частоты тактового сигнала ШИМ. Считается она следующим образом:

Register Value N = Fsys/64kHz-1

Структура записи данных выглядит следующим образом:



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

when LEDDBR =>led_en<= '1';led_cs<= '1';led_exe<= '0';LEDD_ADR<= "1001";DAT_Bits(7 downto 0)<= "11101101"; -- Генерация тактового сигнала ШИМ (без двух старших бит)PWM_state_next<= LEDDONR;

В регистр LEDDONR записывается время, в котором светодиод находится в активном состоянии. В документации есть таблица соответствия какому набору бит принадлежит определенное время горения светодиода.

when LEDDONR =>led_en<= '1';led_cs<= '1';led_exe<= '0';LEDD_ADR<= "1010";DAT_Bits(7 downto 0)<= "00010001"; --  Светодиод активен (0.5 c)

Регистр LEDDOFR содержит данные, сколько времени неактивен светодиод. Точно такие же значения, как и в LEDDONR.

when LEDDOFR =>led_en<= '1';led_cs<= '1';led_exe<= '0';LEDD_ADR<= "1011";DAT_Bits(7 downto 0)<= "00010001"; --  Светодиод неактивен (0.5 c)PWM_state_next<= LEDDBCRR;

LEDDBCRR данные о длительности плавного включения светодиода.

when LEDDBCRR =>led_en<= '1';led_cs<= '1';led_exe<= '0';LEDD_ADR<= "0101";DAT_Bits(7)<= '1'; -- Режим включения (вкл)DAT_Bits(6)<= '1'; -- Бит регулировки включенияDAT_Bits(5)<= '1'; -- Изменение скорости увеличения яркостиDAT_Bits(4)<= '0'; -- RESERVEDDAT_Bits(3 downto 0)<= "0011"; -- Длительность включения (0.5 с)PWM_state_next<= LEDDBCFR;

LEDDBCRR данные о длительности плавного выключения светодиода.

when LEDDBCFR =>led_en<= '1';led_cs<= '1';led_exe<= '0';LEDD_ADR<= "0110";DAT_Bits(7)<= '1'; -- Режим выключения (вкл) (disable/enable)DAT_Bits(6)<= '0'; -- PWM Range ExtendDAT_Bits(5)<= '1'; -- Изменение скорости уменьшения яркостиDAT_Bits(4)<= '0'; -- RESERVEDDAT_Bits(3 downto 0)<= "0011"; -- Длительность выключения (0.5 с)PWM_state_next<= LEDDPWRR;

В регистры LEDDPWRR, LEDDPWRG и LEDDPWRB записываются данные о яркости красного, синего и зеленого цвета светодиода соответственно. Значение яркости считается в процентах следующей формулой:

ADC(%) = PulseWidth/256

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

when LEDDPWRR =>led_en<= '1';led_cs<= '1';led_exe<= '0';LEDD_ADR<= "0001";DAT_Bits(7 downto 0)<= "00000001"; -- RED Pulse WidthPWM_state_next<= LEDDPWRG;

when LEDDPWRG =>led_en<= '1';led_cs<= '1';led_exe<= '0';LEDD_ADR<= "0010";DAT_Bits(7 downto 0)<= "11111111"; -- GREEN Pulse WidthPWM_state_next<= LEDDPWRB;

when LEDDPWRB =>led_en <= '1';led_cs<= '1';led_exe<= '0';LEDD_ADR<= "0011";DAT_Bits(7 downto 0)<= "00011111"; -- BLUE Pulse WidthPWM_state_next<= LEDDCR0;

Ну и в последний регистр LEDDCR0 записывается разрешающая информация и два старших бита значения частоты тактового сигнала ШИМ:

when LEDDCR0 =>led_en<= '1';led_cs<= '1';led_exe<= '0';LEDD_ADR<= "1000";DAT_Bits(7)<= '1'; -- Включение светодиода (вкл)DAT_Bits(6)<= '1'; -- Flick Rate Select Bit (125/250 Hz)DAT_Bits(5)<= '0'; -- Полярность выхода ШИМ (1/0)DAT_Bits(4) <= '0'; -- Режим снижения шумов при переключении ШИМDAT_Bits(3)<= '1'; -- Blinking Sequence Quick Stop Enable BitDAT_Bits(2)<= '0'; -- PWM Mode Selection BitDAT_Bits(1 downto 0)<= "10"; -- Два старших бита частотыPWM_state_next<= DONE;

Примеры реализации


RGB



Purple/White



Подведение итогов


Ну вот и все. Меняя параметры можно добиваться красивого эффекта дыхания светодиода при разной цветовой гамме и яркости, изменяя значения в регистрах LEDDPWRR, LEDDPWRG, LEDDPWRB или величину тока RGB драйвера. Ниже ссылки на код на GitHub и на всю необходимую документацию.

В дальнейшем планирую тестить другие плюшки и по возможности выкладывать сюда на обозрение.

Evaluation Board User Guide
iCE40 LED Driver Usage Guide
Код
Источник: habr.com
К списку статей
Опубликовано: 28.07.2020 16:18:22
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Fpga

Схемотехника

Vhdl

Ice40up5k

Lattice

Rgb led

Mobile development platform

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru