ESP-on-a-PMOD Runtime FPGA Configuration

Following on from my work yesterday, I needed something to quickly reconfigure the edge triggering FPGA (i.e. to use it as a generic smartcard trigger, if without support for true ISO7816 pattern triggering). My solution was to stick a PMOD connector onto an ESP-01 and just bit-bang it over a clocked serial line:

Simply put, the ESP-01 stands up a temporary wireless access network and a webserver. For all the shit-talking Arduino gets, I’d sure as fuck rather spend 15 minutes writing this in Arduino with HL functions than 3 days trying to debug why DHCP isn’t working.

The webserver serves three endpoints:

  • /, which displays a usage message
  • /configure?io=X&clk=Y, configuring the IO edge count and clock edge count
  • /program, which bit-bangs IO and CLK parameters to the FPGA

The ESP-FPGA communication is a simple fixed-length clocked signal, sampled on each rising edge of a dedicated clock line. It’s extremely slow, holding each signal for 40ms, but as a delay-tolerant configuration activity I don’t really care, an LED on the FPGA board is quickly repurposed to serve as a “programming indicator”.

A trivial Verilog state machine allows us to receive this incoming logic, and set the FPGA’s internal registers accordingly. For future reference and re-use:

always @(posedge prog_clk)
begin
    if(prog_reset == 0)
    begin         
        prog_shift <= 0;
        prog_wait_state <= 1;
    end
    else
    begin
        if(prog_wait_state == 1)
        begin
            if(prog_io == 1)
            begin
                IO_EDGE_TARGET <= 0;
                prog_state_io <= 1;
                prog_state_clk <= 0;
            end
            else
            begin
                CLK_EDGE_TARGET <= 0;
                prog_state_io <= 0;
                prog_state_clk <= 1;
            end
            prog_wait_state <= 0;
        end
        else
        begin
            if(prog_state_io == 1)  // start shifting bits in
            begin
                IO_EDGE_TARGET <= IO_EDGE_TARGET + (prog_io << prog_shift);
            end
            else if(prog_state_clk == 1)
            begin
                CLK_EDGE_TARGET <= CLK_EDGE_TARGET + (prog_io << prog_shift);
            end
            prog_shift <= prog_shift + 1;
        end
    end
end

For now, the ESP will always take 32-bit arguments and send the full 32-bits, but there is room for later optimisation.

About Norman

Sometimes, I write code. Occasionally, it even works.
This entry was posted in Bards, Computers, Jesting. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.