As Nature intended!

In my last post I mentioned removing the blue LEDs from the fascia of the case I plan to use for my FPGA project.  I have an extreme dislike of blue LEDs – or at least of the seemingly universal pervasiveness of blue LEDs.  We’ve been able to make them cheaply for, what, a decade now?  Get over it, people!  It’s not novel any more.  They’re annoyingly bright and unpleasantly piercing.  I’m tired of hiding them behind Post-it notes.

So I replaced these obnoxious blue LEDs with bog-standard red, yellow, orange and green LEDs, which worked but weren’t really bright enough to shine through the diffusing layer on the case.  (This layer’s task is presumably to make the blue LEDs vaguely bearable.  Hint: you can make them much *more* bearable by not using them in the first place.)

I ordered some high-brightness LEDs, somewhat skeptical about how different they’d be.  The difference is dramatic, and the LEDs are now clearly visible even in strong light:

There!  Doesn’t that look much nicer than a row of blue lights?

Latching power circuit – in the flesh!

Having breadboarded the latching power circuit from my last post and found it works pretty well, I’ve made a more permanent version that plugs directly onto the headers on my Cyclone 3 board.  While I’d normally build something like this on stripboard, it’s not really appropriate for this project because the pins on the 40-pin headers are only one row of holes apart.  Therefore I’ve used matrix board this time around.

This is the case I plan to use to house this project.  It’s the case from an old, dead Acer Aspire L320 – a nice looking machine that, unfortunately, seems to have insufficient chipset cooling, so tends to die a horrible death.  Dead ones crop up on Ebay fairly frequently, and with a little bit of cleaning up and removing of label residue, they’re an ideal housing for a project like this one.

Behind the power button is a little circuit board with four LEDs (actually only three on mine, but space for a fourth) and the actual power button switch.  I rewired this board slightly – removed the blue LEDs (*please* people, can we get over the blue LED thing now!) and replaced them with green, yellow, orange and red ones.  I also wired the LED anodes in common, to keep the component count down.  The common anode will be fed from 3.3v through a small resitor, then the four LEDs’ cathodes will be tied directly to FPGA pins.  When the respective FPGA pin is low, the LED will light up.

The obvious problem with this arrangement is that when more than one LED is lit, the current will be shared between them, making them dimmer – to avoid this, I’ll use a pulse-width modulation system, giving each LED a 25% duty cycle, and alternating between them, so no two LEDs will be lit at the same time.

The VHDL code for this is as follows:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.numeric_std.ALL;

entity statusleds_pwm is
    port(
        clk : in std_logic;
        leds_in : in std_logic_vector(3 downto 0);
        leds_out : out std_logic_vector(3 downto 0)
    );
end statusleds_pwm;

architecture rtl of statusleds_pwm is
    signal counter : unsigned(18 downto 0);
begin
    process(clk)
    begin
        if rising_edge(clk) then
            counter <= counter+1;
            if counter(16 downto 0)=X"0000"&"0" then
                leds_out<="1111";
                case counter(18 downto 17) is
                    when "00" =>
                        leds_out(0)<=not leds_in(0);
                    when "01" =>
                        leds_out(1)<=not leds_in(1);
                    when "10" =>
                        leds_out(2)<=not leds_in(2);
                    when "11" =>
                        leds_out(3)<=not leds_in(3);
                end case;
            end if;
        end if;
    end process;
end architecture;

As I mentioned in my previous post, the Cyclone 3 board I’m using has four general purpose IO headers, but two of these headers share FPGA pins with the RAM chips, so on a board like mine that’s populated with two RAM chips, there are only a handful of available IOs on headers J3 and J4.  There are, however, enough to run my latching power circuit, the LEDs, and a couple left over which I’ll use for an RS232 port.

The following matrix board layout describes a board which connects directly to headers J3 and J4 on the FPGA board, leaving the IO-rich J1 and J2 free for A/V, SD Card and joystick interfaces.

I’m currently waiting for delivery of some MAX3232s (MAX232 variant that runs from 3.3v) – so that part of the board isn’t yet built – but the power aspect is built and working.

(The above is not quite the final version – I moved one signal to a different IO pin, and added a small capacitor between LED+ and GND.)

Latching power circuit

While the Altera DE1 board has been a great development platform for the MiniSOC project, I don’t want the project to live on that board forever.  I’ve bought a relatively cheap Cyclone 3 board from EBay featuring an EP3C25 FPGA (this is the same FPGA as appears in the Turbo Chameleon 64), which has a shade under 25,000 logic elements to play with.  (The board in question can be found here: http://www.ebay.co.uk/itm/Cyclone-III-FPGA-EP3C25-board-/270910317225  –  that version has only a single 8-bit wide SDRAM chip, but when I contacted the sellers they were extremely helpful, and added a second chip for just $5 extra.)

I have a rather nice small form factor case in which I’d like to install this project, but the case has a PC-style momentary push-button power switch, so I need some kind of latching power circuit.

The requirements for the circuit are:

  • Must draw only negligible power in the “off” state.
  • Must latch reasonably quickly, and not turn off again until the button is released and pressed again.
  • If FPGA signal pins are used, must not allow voltage to reach them in the “off” state.

After studying a few similar circuits on the web, I decided to use a P-channel MOSFET and a BC547, with the base of the latter being driven by the FPGA.

The schematic of my current circuit is as follows:

A few explanatory notes:

  • PWR_BUTTON and PWR_HOLD are signal pins on the FPGA.  The FPGA is powered from VOUT.
  • S1 triggers the MOSFET and allows power to flow to VOUT
  • The FPGA fires up, and as soon as it’s configured, sets PWR_HOLD to a high output, causing the BC547 to keep the MOSFET open.
  • The FPGA sets PWR_BUTTON to an input with weak pullup, allowing it to detect a second press of the button.  D1 prevents +5V reaching the non-5v-tolerant FPGA pin, and also prevents any voltage reaching that pin while the FPGA is off.  R2 prevents the action of the BC547 interfering with the button press detection.
  • R5 is a load resister that just drains away any stray charge that’s left when the circuit powers off.

The button itself has to be debounced in the FPGA.  The easiest way to do this is just to begin a delay any time the button line’s state changes, then sample it a second time when the delay’s elapsed, and compare.

The VHDL looks like this:

signal debounce_counter : unsigned(11 downto 0) := X"fff"; 
signal power_button_deb : std_logic; 
signal power_button_deb1 : std_logic; 
...
-- debounce the power switch 
    process(clk) 
    begin 
        if rising_edge(clk) then 
            if debounce_counter=X"000" then 
                if power_button_deb1='1' and power_button='1' then    -- Is button stable? 
                    power_button_deb<='1'; 
                elsif power_button_deb1='0' and power_button='0' then 
                    power_button_deb<='0'; 
                else -- No? Start a delay... 
                    debounce_counter<=X"FFF"; 
                end if; 
                power_button_deb1 <= power_button; 
            else 
                debounce_counter<=debounce_counter-1; 
            end if; 
        end if; 
    end process;