推出莱迪思半导体的FPGA iCE40 UltraPlus移动开发平台

介绍



朋友们,美好的一天!最近在工作中,我们从莱迪思半导体获得了全新的iCE40 UltraPlus移动开发平台板。根据iCE40 UltraPlus官方网站上的开发人员的说法,MDP是一块包含4个iCE40 UltraPlus FPGA的电路板,每个FPGA都控制自己的一组外设。该集合包括:



  • 带有MIPI DSI接口的分辨率为240x240的移动显示器;
  • 分辨率为640x480(OVM7692)的图像传感器;
  • 4支低功率麦克风;
  • BLE模块用于无线数据传输;
  • 可编程SPI闪存;
  • 一整套各种传感器(压力,指南针,陀螺仪和加速度计);
  • 好吧,各种各样的按钮和灯泡。


关于这头鲸的最酷的事情是,借助特殊的软件包,您可以部署神经网络来处理视频和声音。更不用说莱迪思FPGA低功耗,小尺寸且相当便宜的事实。



UltraPlus MDP







作为测试用例,请使RGB LED指示灯闪烁(图中的D13,在左侧图片中以红色突出显示)。阅读文档后,我们得出结论,该LED由FPGA编号U3控制(在右图中以红色突出显示)。我们还从文档中了解到,LED由内置PWM调制器和电流驱动器控制。



我们注意到此信息。



设置板并编写程序



板上有一组跳线,您可以使用这些跳线选择需要刷新的FPGA才能与选定的一组外围设备一起工作。我们对三组跳线感兴趣,这些跳线负责为LED供电并为所需的FPGA编程。







步骤如下:



  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编写,但每个人都有自己的名字。



这是一个通用的方案,可以让您了解做什么和在哪里做:







因此,我前面提到的PWM调制器和电流驱动器已经浮出水面。这两个设备是内部模块。有必要编写一个逻辑控制设备并发送数据,以使整个厨房正常工作。让我们从顺序开始,描述“黑匣子”:



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


黑盒中缺少同步初始化。为此,使用一个内部模块,该模块声明如下:



-- Generator clock:
component SB_HFOSC is
	generic (
		CLKHF_DIV	: string := "0b00" );
	port (
		CLKHFPU	: in std_logic;
		CLKHFEN	: in std_logic;

		CLKHF 	: out std_logic );
end component;


图片该模块可以产生频率为48MHz,24MHz,12MHz和6MHz的信号。参数CLKHF_DIV负责分频系数(分别为“ 0b00”,“ 0b01”,“ 0b10”,“ 0b11”)。CLKHFPU和CLKHFEN使模块能够工作。CLKHF-时钟信号。



接下来,我们声明PWM调制器和电流驱动器:



-- Embedded PWM IP:
component SB_LEDDA_IP is
	port (
		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 is
	generic (
		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;


图片PWM调制器需要提供负责LED工作模式和某些控制信号的地址和数据。然后由RGB电流驱动器处理输出,该驱动器已经点亮了LED。


电流驱动器处理来自PWM调制器的数据,并调整提供给LED的电流值。参数RGB0_CURRENT,RGB1_CURRENT,RGB2_CURRENT设置每种颜色的电流量。 CURRENT_MODE-电源模式(完全或一半)。



图片



是的,很酷。有地址,有数据。好吧,要寄给他们什么?总的来说,莱迪思的开发人员在其文档中给出了相当详细的描述,但是数量很多。为了清楚起见,我将尝试将所有内容压缩为几行描述和代码。



PWM调制器需要9个地址。他们每个人都负责保持LED正常工作的特定功能。下表显示了地址的值和地址的名称:







为了发送数据,我们实现了有限状态机:



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


第一步是将数据写入LEDDBR寄存器。它存储PWM时钟频率的值。认为如下:



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寄存器记录LED激活的时间。该文档包含一个对应表,其中一组位属于某个LED燃烧时间。



when LEDDONR =>
		led_en			<= '1';
		led_cs			<= '1';
		led_exe			<= '0';
		LEDD_ADR		<= "1010";
		DAT_Bits(7 downto 0)	<= "00010001"; --    (0.5 c)


LEDDOFR寄存器包含LED不活动多长时间的数据。与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-关于LED软开启持续时间的数据。



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'; -- RESERVED
		DAT_Bits(3 downto 0)	<= "0011"; --   (0.5 )
		PWM_state_next		<= LEDDBCFR;


LEDDBCRR-关于LED软关闭持续时间的数据。



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 Extend
		DAT_Bits(5)		<= '1'; --    
		DAT_Bits(4)		<= '0'; -- RESERVED
		DAT_Bits(3 downto 0)	<= "0011"; --   (0.5 )
		PWM_state_next		<= LEDDPWRR;


寄存器LEDDPWRR,LEDDPWRG和LEDDPWRB分别以红色,蓝色和绿色LED的亮度记录数据。亮度值通过以下公式以百分比计算:



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 Width
		PWM_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 Width
		PWM_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 Width
		PWM_state_next		<= LEDDCR0;


好,最后一个寄存器LEDDCR0记录使能信息和PWM时钟信号频率的两个最高有效位:



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 Bit
		DAT_Bits(2)		<= '0'; -- PWM Mode Selection Bit
		DAT_Bits(1 downto 0)	<= "10"; --    
		PWM_state_next		<= DONE;


实施实例



RGB







紫色/白色







总结



恩,就这样。通过更改参数,可以通过更改LEDDPWRR,LEDDPWRG,LEDDPWRB寄存器中的值或RGB驱动器的当前值来实现具有不同颜色和亮度的LED的精美呼吸效果。以下是GitHub上的代码和所有必要文档的链接。



将来,我计划测试其他包子,如果可能的话,将它们放在这里进行检查。



评估板用户指南

iCE40 LED驱动器使用指南

代码



All Articles