Advertisement
Guest User

NeoPixelVHDL

a guest
Apr 20th, 2014
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VHDL 2.31 KB | None | 0 0
  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.all;
  3. use IEEE.STD_LOGIC_UNSIGNED.all;
  4.  
  5. -- NeoPixel / WS2812 driver module
  6. -- behaves as MCU controlled SPI master
  7. -- clocks in data from MCU slave and switches
  8. -- between the generated 0 and 1 PWM signals depending
  9. -- on shifted in bit
  10. -- new data (beginning of frame) is signalled by slave pulling CE high
  11. entity neopix_drv is
  12.     port(
  13.         GCLK: in std_logic;     -- global system clock 16MHz
  14.         SDIN: in std_logic;     -- serial data input
  15.         CE:   in std_logic;     -- chip enable input
  16.         SCLK: out std_logic;    -- serial clock output
  17.         DO:   out std_logic     -- NeoPixel data output
  18.     );
  19. end neopix_drv;
  20.  
  21. architecture neopix_drv_arch of neopix_drv is
  22.     signal CLK_PRESC: std_logic_vector(4 downto 0); -- clock prescaler register
  23.     signal CLK_SER: std_logic;                      -- intermediate signal for 800kHz serial clock
  24.     signal PWM0, PWM1: std_logic;                   -- PWM signals, representing either logic 0 or 1 to WS2812 controller
  25. begin
  26.     -- this process implements a counter register which
  27.     -- overflows at a frequency of 800kHz (every 1.25us)
  28.     -- the counter register is used for serial clock and PWM generation
  29.     prescaler_proc: process(GCLK)
  30.     begin
  31.         if (rising_edge(GCLK)) then
  32.             if (CLK_PRESC < 19) then
  33.                 CLK_PRESC <= CLK_PRESC + 1;
  34.             else
  35.                 CLK_PRESC <= (others=>'0');
  36.             end if;
  37.         end if;
  38.     end process prescaler_proc;
  39.    
  40.     -- these conditional signal assignments create intermediate
  41.     -- 800kHz PWM signals which represent either a logic 0 or logic 1 to WS2812 LEDs
  42.     PWM0 <= '1' when (CLK_PRESC < 6) else '0';  -- 375 ns pulse width
  43.     PWM1 <= '1' when (CLK_PRESC < 12) else '0'; -- 750 ns pulse width
  44.    
  45.     -- generate an 800kHz serial clock signal from the clock prescaler register
  46.     CLK_SER <= '1' when (CLK_PRESC < 10) else '0';
  47.  
  48.     -- reads data one bit at a time from MCU slave, timed by the rising edge of the 800kHz serial clock
  49.     -- the data output (DO) will output the PWM signal corresponding to the value of the bit that the MCU sent
  50.     -- as long as the chip enable (CE) is high, if CE is low DO is high impedance
  51.     DO <= PWM1 when (SDIN = '1' and CE = '1') else PWM0 when (SDIN = '0' and CE = '1') else 'Z';
  52.    
  53.     -- output the serial shift clock to the master only when the chip enable signal is high, otherwise high impedance
  54.     SCLK <= CLK_SER when (CE = '1') else 'Z';
  55.    
  56. end neopix_drv_arch;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement