USBasp based AVR programmer

A week ago i’ve ended my work on a new project which is AVR programer, entirely based on USBasp project. This programmer is supported by almost any normal operating system. It’s main features are:

  • it does not require LPT port – and that makes it usable with any sort of laptop, not only the old ones, that still have LPT,
  • firmware can be uploaded 10x faster than with LPT based programmers,
  • it is very small.

The programmer works without any problems with famous avrdude software. It has three configuration jumpers. First one (pins 1-2) is used to configure programming speed. When connected, targets slower than 1.5 MHz can be programmed. Jumper number 2 (pins 3-4) is used for upgrading firmware of programmer itself. The last one (pins 5-6) is used to connect target to VCC taken directly from USB port. I’ve taken some photos of my device and posted it below.

VGA signal generator written in VHDL

Today i’ve decided to post some information about making VGA signal generator, working in 640×480@60Hz mode. With use of such generator man can develop simple display device that works with almost any type of monitor. I wouldn’t go so far to call it a video card, but it’s definetley some part of video card project.

Every monitor (it does not matter if its LCD or an old CRT..) requires five signals to display things correctly. These are:

  • R,G,B – 3 color lines
  • v_sync – vertical synchonization
  • h_sync – horizontal synchronization

Those signals must satisfy timing norms, which are described in details on this page. Every single pixel is read from RGB lines at about 25MHz. Entire display area is 800×525 in size, and within this area there is so called active area that represents things that we see on monitor. It has a size of 640×480 px. The rest of the area is used for front and back porch and return. I’ll give some details of timing synchronization lines.

There are four stages of horizontal syncronization

  1. 640px of active area (pixels are read from rgb lines and are displayed on monitor) (HD)
  2. 16px  of horizontal front porch. (HF)
  3. 96px of horizontal return (HR)
  4. 48px of horizontal back porch (HB)

The sum of all 4 stages gives us 800 px. Horizontal sync signal should be driven to logical 0 during stage 3 and then should go high during stages 1,2 and 4.

Vertical sync is treated in simmilar manner.

  1. 480 lines  of active area (VD)
  2. 10 lines of vertical front porch (VF)
  3. 33 lines of vertical back porch (VB)
  4. 2 lines of vertical return (VR)

This gives us 525 lines when added together. Just like horizontal sync signal, this one should be low during stage 3 and high during any other stage. Now we go from theory to practice.

Firstly we should define VHDL entity. We already know that we require 5 output signals to drive monitor. Vertical sync signal is called vs, and horizontal sync is hs. We will generate three color signals (R,G,B) later.

entity vga_640_gen is
port (  – common signals
clk, rst : in std_logic;
– vga signals
pix_x, pix_y : out std_logic_vector(9 downto 0);
hs, vs, blank, pix_clk : out std_logic);
end vga_640_gen;

The purpose of signals: clk and rst is obvious. Clock source has a frequency of 50MHz. It will be devided per 2, to give us pixel clock of desired frequency equal to 25MHz, as mentrioned above. Ten bit signals pix_x and pix_y contain currently displayed pixel coordinates. Pixel (0,0) is the one in upper-left corner of display area. The blank signal is high when generator is not in active area.

Let’s implement some VHDL code:

architecture Behavioral of vga_640_gen is

– signals for pixel clock generation
signal pix_clk_reg, pix_clk_next : std_logic;

signal blank_reg, blank_next : std_logic;

– internal signals
signal h_tick, v_tick : std_logic;
signal h_sync_reg, h_sync_next : std_logic;
signal v_sync_reg, v_sync_next : std_logic;

– counters for horizontal and vertical sync
signal v_count_reg, v_count_next : std_logic_vector(9 downto 0);
signal h_count_reg, h_count_next : std_logic_vector(9 downto 0);

– horizontal and vertical syncs generating constants
constant HD : integer := 640;
constant HF : integer := 16;
constant HB : integer := 48;
constant HR : integer := 96;
constant VD : integer := 480;
constant VF : integer := 10;
constant VB : integer := 33;
constant VR : integer := 2;

begin

– update process
update : process (clk, rst)
begin
if (rst = ‘1′) then
h_count_reg <= (others => ‘0′);
v_count_reg <= (others => ‘0′);

pix_clk_reg <= ‘0′;
h_sync_reg <= ‘0′;
v_sync_reg <= ‘0′;

blank_reg <= ‘0′;
elsif rising_edge(clk) then
pix_clk_reg <= pix_clk_next;

h_count_reg <= h_count_next;
v_count_reg <= v_count_next;

h_sync_reg <= h_sync_next;
v_sync_reg <= v_sync_next;

blank_reg <= blank_next;
end if;
end process update;

– clock generation
pix_clk_next <= not pix_clk_reg;

– blank generation
blank_next <= ‘0′ when (h_count_reg < HD) and (v_count_reg < VD) else ‘1′;

– horizontal and vertical tick signal generation
h_tick <= ‘1′ when h_count_reg = (HD+HF+HB+HR-1) else ‘0′;
v_tick <= ‘1′ when v_count_reg = (VD+VF+VB+VR-1) else ‘0′;

– sync signals generation
h_sync_next <= ‘1′ when (h_count_reg >= (HD+HF)) and
(h_count_reg <= (HD+HF+HR-1)) else ‘0′;
v_sync_next <= ‘1′ when (v_count_reg >= (VD+VF)) and
(v_count_reg <= (VD+VF+VR-1)) else ‘0′;

– horizontal counter process
h_counter : process (pix_clk_reg, h_tick, h_count_reg)
begin
if pix_clk_reg = ‘1′ then
if (h_tick = ‘1′) then
h_count_next <= (others => ‘0′);
else
h_count_next <= h_count_reg + 1;
end if;
else
h_count_next <= h_count_reg;
end if;
end process h_counter;

– vertical counter process
v_counter : process (pix_clk_reg, h_tick, v_tick, v_count_reg)
begin
if pix_clk_reg = ‘1′ and h_tick = ‘1′ then
if (v_tick = ‘1′) then
v_count_next <= (others => ‘0′);
else
v_count_next <= v_count_reg + 1;
end if;
else
v_count_next <= v_count_reg;
end if;
end process v_counter;

– pixel clock signal
pix_clk <= pix_clk_reg;

– blank signal
blank <= blank_reg;

– generate horizontal sync signal
hs <= h_sync_reg;
– generate vertical sync signal
vs <= v_sync_reg;

– output pixel counter signals
pix_x <= h_count_reg;
pix_y <= v_count_reg;

end Behavioral;

Update process is responsible for writing new waluest to all registers, which were used in this implementation. Clock division is done by one bit register negating itself at main clock frequency. h_count is responsible for horizontal syncronization, it is implemented as a simple counter, that count to 800 and then resets itself. v_count is implemented in simmilar way. Ouput signals are generated by comparers that compare counter values with constants defined (HD, VD, HF, VF and so on…).

Generator test

In order to test our generator we need to create a testbed. The simplest way to do so is to display a xor pattern on our tube. In xor pattern pixel color is derived form xor of its coordinates. Here is an implementation of such testbed.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity test is
port( clk : in std_logic;

vga_hs, vga_vs : out std_logic;
vga_rgb : out std_logic_vector(7 downto 0));
end test;

architecture Behavioral of test is
signal pix_x, pix_y : std_logic_vector(9 downto 0);
signal blank : std_logic;
begin

vga_gen : entity vga_640_gen
port map(clk => clk, rst => ‘0′,
pix_x => pix_x, pix_y => pix_y,
hs => vga_hs, vs => vga_vs, blank => blank, pix_clk => open);

vga_rgb <= pix_x(7 downto 0) xor pix_y(7 downto 0) when blank = ‘0′ else x"00";

end Behavioral;

It’s worth noticing that RGB signals need to be low when we are out of acive area. If we dont take care of this some tubes are starting to freak out and emit strage noise (: I’ve heard it by myself, so beware of this. Testbed executed on NEXYS 2 board gives result shown below.
monitor

Turtelizer 2 JTAG Cloned.

Truly Integrated Turtelizer 2 Clone is another hardware implementation of well known Turtelizer 2, which was deriverd from ethrenut.de. The programmer was designed to be fully supported by OpenOCD. 10-pin JTAG connector is pin compatible with the original Turtelizer. Whole Project is based on FT2232 IC from FTDI. This IC is supported by Windows and Linux operating systems. Next to JTAG, this programmer has  RS232 interface, driven by ST3232. JTAG pins are connected via buffers which ensure that tis toy can support any target no matter its supply voltage (:.

In order to use programmers serial interface we need to load ftdi_sio module. Due to the fact that this device uses non-typical vendor and product id, we need to give parameters as follows:

# modprobe ftdi_sio vendor=0x403 product=0xbdc8

I heard that Windows drivers are included in OpenOCD package, but i never tested it, because i don’t have Windows on my computer.

Programator JTAG