Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- library IEEE;
- use IEEE.STD_LOGIC_1164.all;
- use IEEE.STD_LOGIC_UNSIGNED.all;
- -- NeoPixel / WS2812 driver module
- -- behaves as MCU controlled SPI master
- -- clocks in data from MCU slave and switches
- -- between the generated 0 and 1 PWM signals depending
- -- on shifted in bit
- -- new data (beginning of frame) is signalled by slave pulling CE high
- entity neopix_drv is
- port(
- GCLK: in std_logic; -- global system clock 16MHz
- SDIN: in std_logic; -- serial data input
- CE: in std_logic; -- chip enable input
- SCLK: out std_logic; -- serial clock output
- DO: out std_logic -- NeoPixel data output
- );
- end neopix_drv;
- architecture neopix_drv_arch of neopix_drv is
- signal CLK_PRESC: std_logic_vector(4 downto 0); -- clock prescaler register
- signal CLK_SER: std_logic; -- intermediate signal for 800kHz serial clock
- signal PWM0, PWM1: std_logic; -- PWM signals, representing either logic 0 or 1 to WS2812 controller
- begin
- -- this process implements a counter register which
- -- overflows at a frequency of 800kHz (every 1.25us)
- -- the counter register is used for serial clock and PWM generation
- prescaler_proc: process(GCLK)
- begin
- if (rising_edge(GCLK)) then
- if (CLK_PRESC < 19) then
- CLK_PRESC <= CLK_PRESC + 1;
- else
- CLK_PRESC <= (others=>'0');
- end if;
- end if;
- end process prescaler_proc;
- -- these conditional signal assignments create intermediate
- -- 800kHz PWM signals which represent either a logic 0 or logic 1 to WS2812 LEDs
- PWM0 <= '1' when (CLK_PRESC < 6) else '0'; -- 375 ns pulse width
- PWM1 <= '1' when (CLK_PRESC < 12) else '0'; -- 750 ns pulse width
- -- generate an 800kHz serial clock signal from the clock prescaler register
- CLK_SER <= '1' when (CLK_PRESC < 10) else '0';
- -- reads data one bit at a time from MCU slave, timed by the rising edge of the 800kHz serial clock
- -- the data output (DO) will output the PWM signal corresponding to the value of the bit that the MCU sent
- -- as long as the chip enable (CE) is high, if CE is low DO is high impedance
- DO <= PWM1 when (SDIN = '1' and CE = '1') else PWM0 when (SDIN = '0' and CE = '1') else 'Z';
- -- output the serial shift clock to the master only when the chip enable signal is high, otherwise high impedance
- SCLK <= CLK_SER when (CE = '1') else 'Z';
- end neopix_drv_arch;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement