Подключение встроенного модуля токового драйвера FPGA серии iCE5 (iCE40 Ultra)

В микросхеме iCE5LP2K есть встроенные токовые драйвера для светодиодов. Три канала слаботочных, с ограничением тока от 4 до 24 мА с шагом в 4 мА (настраивается статически) и один канал посильнее, от 50 до 500 мА с шагом в 50 мА.

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


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

Основная информация о модуле предоставлена в «LATTICE ICE™ Technology Library» и в «iCE40 LED Driver Usage Guide». В разных моделях микросхем могут встретится разные вариации модуля, но именно в этой он называется SB_RGB_DRV.
Типичная схема включения модуля дана в мануале:
Схема включения

Обратите внимание на модуль LED_DRV_CUR (2), который нужен для работы токовых драйверов, его тоже надо будет включить и завести сигнал на модуль RGB_DRV (1).

Модуль LED_DRV_CUR очень прост:
  • EN — сигнал разрешения, подадим туда 1, включён всегда;
  • LEDPU — опорный ток для токовых драйверов.

Модуль RGB_DRV управляется следующими сигналами:
  • RGBLEDEN — сигнал включения модуля, для начала подадим туда просто 1, пусть работает.
  • RGBPU — какой-то опорный ток из модуля LED_DRV_C- UR.
  • RGB0PWM, RGB1PWM, RGB2PWM — три входных логических управляющих сигнала, подадим на них сигнал, который моргал светодиодом в прошлой версии ПО.

Модуль имеет три выхода: RGB1, RGB2, RGB3, которые должны идти на специально выделенные под этот модуль выводы и никуда больше (видимо, там всего один провод, и он больше его никуда подключить и не сможет). Их даже не обязательно указывать в файле ограничений, т.к. сами встанут на единственно допустимое для них место.
Хотя там есть возможность отключить модуль RGB и использовать эти выводы как выводы с открытым стоком через другой блок, но сейчас речь не об этом.

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

Вот так он описан в описании библиотеки модулей для верилога:
SB_RGB_DRV RGB_DRIVER (
.RGBLEDEN(ENABLE_LED),
.RGB0PWM(RGB0),
.RGB1PWM(RGB1),
.RGB2PWM(RGB2),
.RGBPU(led_power_up),
.RGB0(LED0),
.RGB1(LED1),
.RGB2(LED2)
);
defparam RGB_DRIVER.RGB0_CURRENT = "0b111111";
defparam RGB_DRIVER.RGB1_CURRENT = "0b111111";
defparam RGB_DRIVER.RGB2_CURRENT = "0b111111";


Видим, что есть три параметра, которые задают ток на канале. Логика их проста, как мне кажется, — каждый битик подключает один токовый стабилизатор на 4 мА, всего их 6 и битиков тоже 6. Сколько битов установлено, такой ток и выйдет на канале (n * 4 мА). Если установленных битиков нет вовсе, то управление выводом идёт через модуль SB_IO_OD (режим открытого стока).

Окей, вроде бы всё понятно, осталось только это переписать на VHDL:
component SB_RGB_DRV is
	generic (
		RGB0_CURRENT : string := "0b000000";
		RGB1_CURRENT : string := "0b000000";
		RGB2_CURRENT : string := "0b000000");
	port (RGBLEDEN, RGBPU, RGB0PWM, RGB1PWM, RGB2PWM: in std_logic;
		RGB0, RGB1, RGB2: out std_logic);
end component;


И целиком код с инициализацией:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity rgbdrv is
    port (
        ri : in  std_logic;
        gi : in  std_logic;
        bi : in  std_logic;
        ro : out std_logic;
        go : out std_logic;
        bo : out std_logic
    );
end rgbdrv;

architecture behavior of rgbdrv is
    -- RGB constant reference current
    component SB_LED_DRV_CUR is
        port(EN: in std_logic;
             LEDPU: out std_logic);
    end component;

    -- RGB driver
    component SB_RGB_DRV is
        generic (
            RGB0_CURRENT : string := "0b000000";
            RGB1_CURRENT : string := "0b000000";
            RGB2_CURRENT : string := "0b000000");
        port(RGBLEDEN, RGBPU, RGB0PWM, RGB1PWM, RGB2PWM: in std_logic;
             RGB0, RGB1, RGB2: out std_logic);
    end component;

    signal LED_PU : std_logic;

    begin

        LEDDrv : SB_LED_DRV_CUR
        port map
        (
            EN => '1',
            LEDPU => LED_PU
        );

        RGBDrv : SB_RGB_DRV
        generic map (
            RGB0_CURRENT => "0b011111", -- 20 mA
            RGB1_CURRENT => "0b011111", -- 20 mA
            RGB2_CURRENT => "0b011111") -- 20 mA
        port map
        (
            RGBLEDEN => '1',
            RGBPU    => LED_PU,
            
            RGB0PWM  => ri,
            RGB1PWM  => gi,
            RGB2PWM  => bi,

            RGB0     => ro,
            RGB1     => go,
            RGB2     => bo
        );
end behavior;

Конкретно настройки указываем при добавлении компонента, укажем 5 бит, т.е. 20 мА. Кстати, аналогично можно указать и настройки генератора частоты, там есть настраиваемый предделитель.
Параметр RGBn_CURRENT именно строковый, а не числовой, почему так — я фз. Число он скушать не захотел, сказал, что тип аргумента неправильный.

В основном, главном файле main.vhd уберём led1 и добавим выходы по цветам:
entity test is
port (
led_r : out std_logic;
led_g : out std_logic;
led_b : out std_logic
);
end test;


И подключим их на сигнал моргалки:
rgbdrv_isnt : entity rgbdrv
port map(
	ri => test_led,
	gi => test_led,
	bi => test_led,
	ro => led_r,
	go => led_g,
	bo => led_b
);


Строку с led0 уберём, так как этот вывод пропал. Из файла с распиновкой тоже.

Вроде бы всё просто и логично, и даже должно бы заработать, но вот только фиг, синтезатор synplify на этапе «Import P&R Input Files» подкидывает мину:
Error: Illegal Connection: Pin 'RGB2' of instance 'rgbdrv_isnt.RGBDrv' of type 'SB_RGB_DRV' should be connected to only one top module port. It is connected to the following terminals : led_b_obuf/DOUT0

Я так и не смог понять, что ему не нравится, потому переключил синтезатор с Synplify на Lattice LSE.
Забавно ещё то, что аналогичная ошибка упоминается во всём интернете только один раз, на каком-то косячном сервисе ответов. Совет там довольно странный, добавьте в заголовок строки
library sb_ice40_components_syn;
use sb_ice40_components_syn.components.all;

Более нигде в интернете я о такой библиотеке не слыхал, как и в документации. И совет, естественно, не помог.

Контекстное меню на Synthesis Tool
Меню

Выбираем Lattice LSE
Окно

Кстати, он гораздо шустрее, чем Synplify, но не знаю, лучше или хуже. Проблема у Synplify именно со специально выделенными выводами, остальные он кушает как надо.
Lattice LSE, кстати, судя по логу, автоматически пытается линиям RGB0, RGB1, RGB2 назначить атрибут black_box_pad_pin.

Собираем, зашиваем и радуемся моргающим светодиодам, ток которых ограничен 20 мА.

Ссылки:
Файлы в топике: ledex_rgb.zip, test_bitmap_rgb.zip

Комментарии (7)

RSS свернуть / развернуть
Интересно, а для каких целей разработчики этой FPGA вообще запихнули в неё столь странную для этих микросхем периферию?
0
Насколько я понял, эта серия микросхем рассчитана на миниатюрность (есть корпуса и меньше, чем qfn48), низкое потребление и всякое такое. В том числе и миниатюрность по внешним компонентам — генератор встроенный, jотсутствие необходимости в резисторах для светодиода индикации (в телефонах, например, такой бывает), для IR-передатчика (силовой выход до 500 мА), который, наверное, может использоваться для вспышки, для эмуляции штрихкода или ещё для чего такого.

В интернете пишут, что микросхема ICE5LP4K поставлена в iPhone 7, т.ч. мб это были их требования к этой серии? А, может, просто им подошло.
Кстати, вот обоснование из описания в даташите:
The iCE40 Ultra family also features DSP functional block to off-load Application Processor to pre-process information
sent from the mobile sensors. The embedded RGB PWM IP, with the three 24 mA constant current RGB outputs
on the iCE40 Ultra provides all the necessary logic to directly drive the service LED, without the need of
external MOSFET or buffer.
The 500 mA constant current IR driver output provides a direct interface to external LED for application such as
IrDA functions. Users simply implement the modulation logic that meets his needs, and connect the IR driver
directly to the LED, without the need of external MOSFET or buffer. This high current IR driver can also be used as
Barcode Emulation, sending barcode information to external Barcode Reader.
The iCE40 Ultra family of devices are targeting for mobile applications to perform functions such as IrDA, Service
LED, Barcode Emulation, GPIO Expander, SDIO Level Shift, and other custom functions.
+1
Насчёт корпусов у серии iCE40 Ultra:
36-ball WLCSP, 0.35 mm, 2.078 mm x 2.078 mm
36-ball ucfBGA, 0.40 mm, 2.5 mm x 2.5 mm
48-ball QFN Package, 0.5 mm, 7.0 mm x 7.0 mm

Микросхема 2х2 мм, которая рулит RGB-светодиодом, вспышкой, и может ещё опрашивать датчики (не зря там по два I2C и SPI блока стоит). Достаточно интересная штука, думаю, для мобильного применения =)
Понятно, что той же альтере, у которой корпус 3х3см (условно) плевать на ещё какую-то рассыпуху вокруг, размеры просто несравнимы.
+1
Altera MAX10 идёт в корпусах от 3х3 мм, и имеет аналоговые блоки на борту :). Но сейчас ниша цплдешек сильно сократилась из-за быстрых МК. Они банально дешевле и быстрее в разработке, а «железный» риал-тайм далеко не всем нужен. Хилинх вообще забил на нижний сегмент, чисто для старых клиентов выпускают древние 9500 и Кулраннеры 2.
0
Посмотрел на MAX10, мелкое тоже всё в BGA, а QFP только со 144 ногами и 22х22мм о.о
Жаль, что такие вот нанокорпуса для обычных применений не очень подходят, больно уж мелкие и плотные, и им высококачественная печатная плата нужна с тонкими дорожками… Производители FPGA делают или супермелкие микросхемы, или супербольшие всё как-то =D Видимо, середнячки по размерам не особо популярны.
0
Говорю же, современные МК перекрывают 99% возможностей CPLD. Вещи типа Cypress PSoC покрывают наверное 99.5%. Вот на оставшихся полпроцента и толкутся мелкие CPLD.
0
ПЛИС с токовыми драйверами это вещь, и не только для диодов. Можно например мосфетами рулить без внешних драйверов. Но вот шаманские свистопляски при настолько простых задачах весьма удручают. Спасибо автору за труд и предупреждения.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.