Close
0%
0%

CAT Board

The CAT Board is part of a Raspberry Pi-based hand-held FPGA programming system.

Similar projects worth following
The CAT Board is an OSHW Raspberry Pi HAT with a Lattice iCE40HX FPGA. It's meant to be programmed using the OSS myhdl, yosys, arachne-pnr, IceStorm tools right on the RPi.

Features
----------------------------------------------------------------
* Lattice iCE40-HX8K FPGA in 256-pin BGA.
* 32 MByte SDRAM (16M x 16).
* Serial configuration flash (at least 2 Mbit).
* Three Grove connectors.
* Two PMOD connectors.
* One 20x2 header with 3.3V, ground and 18 FPGA I/Os.
* Two SATA headers (for differential signals; don't know if they would work with SATA HDDs.)
* DIP switch with four SPST switches.
* Two momentary pushbuttons.
* Four LEDs.
* 100 MHz oscillator.
* 5.0 V jack for external power supply.
* 3.3 V and 1.2 V regulators.
* Adjustable voltage on one bank of FPGA I/O pins.
* 32 KByte HAT EEPROM.
* 40-pin RPi GPIO header.


  • Another KiCad Tool, Another Decision

    Dave Vandenbout06/11/2018 at 02:58 0 comments

    Over the past few weeks, I've done two things related to his project:

    1. Wrote a plugin for KiCad's PCBNEW that lets you paint pads of specific types.
    2. Prototyped a vertical HDMI connector and decided it wasn't worth it.

    Pad Painter

    When you're dealing with FPGAs having several hundred or more pins, most of which are interchangeable, it can be perplexing when trying to choose the correct pin to connect to some other peripheral. You want to choose one that's close to where it will be connected, but you also need to make sure it's the right type (don't connect an FPGA VCC pin to an HDMI connector data pin), and it's in the right I/O bank. I wrote the PadPainter plugin for KiCad to highlight pads of ICs that meet a set of conditions such as the electrical function (input, output, bidirectional, etc.) and the bank (or unit) to which its assigned. This tool quickly shows me the pins of the FPGA which are candidates for connection to other peripherals. If you're dealing with large FPGAs or SOCs, this tool may also be useful to you. You can read more about it here.

    Vertical HDMI Connector

    I decided to replace the SATA connectors on the original CAT Board with an HDMI port. Because of its location, the normal right-angle HDMI connector would be blocked by the USB ports of the Raspberry Pi. So I decided to use a vertical connector.

    Finding vertical HDMI connectors wasn't easy. Digikey and Mouser didn't have any. I finally found some on Aliexpress, but I had to piece together the footprint dimensions from several sources. Obviously, I couldn't really trust my footprint so I built a small prototype board using several hole sizes and trace/space widths:

    The PCB showed my footprint would work with the vertical HDMI connector:

    Even so, I decided not to pursue this any further. The choice of suppliers for the connector was too limited and sketchy, and the assembly process looked like bent pins would be a problem.

    Instead, I'll use the more common right-angle HDMI connector and bring it off the same side of the PCB that's used by the Raspberry Pi GPIO connector. To make room, I'll need to replace the through-hole GPIO socket with an SMT version.

  • A Pile of Parts

    Dave Vandenbout05/28/2018 at 02:39 0 comments

    In my last log, I had the SKiDL-generated netlist imported into an RPi HAT template. The problem with that is PCBNEW initially places all the parts pretty much any way it wants. That means you have to pick through a pile of parts to find which ones go with which. As an example, I highlighted (in white) the SDRAM chip and its bypass caps:

    My solution for this problem was two-fold:

    1. Since SKiDL descriptions are just programs with a natural hierarchy, I modified SKiDL to pass that hierarchy to PCBNEW by embedding it into the sheetpath fields of the netlists it generates.
    2. Then I wrote a plugin for PCBNEW that would group and arrange the parts to reflect their position within that hierarchy.

    With those two items in place, the relationships between the parts becomes much clearer. Here's the placement of the SDRAM and its bypass caps now:

    After that, I was able to create an initial, rough placement for the CAT Board:

    I still have to design the +3.3V and +1.2V voltage regulator circuits. After those are done, I can begin the detailed placing and routing.

  • CAT Board in SKiDL

    Dave Vandenbout05/20/2018 at 15:01 0 comments

    It's been a few weeks since my last log post. Since then, I've done the following:

    • Created SKiDL modules for each of the blocks shown in my last log post, except for the power section. I still haven't selected the voltage regulators for that.
    • Wrote a blog post describing how to do parameterized SKiDL modules for LED circuits. This is also directly applicable to the switch and pushbutton sections of the CAT Board.
    • Released a version update for SKiDL that includes improvements motivated by the need to simplify/condense the SKiDL description of the CAT Board.
    • Merged the SKiDL-generated netlist for the CAT Board with my KiCad template for Rapsberry Pi HATs.

    With regard to the last item on the list, here are the components and the HAT PCB boundary:

    And here it is with the air-wires:

    So I've got my crap. I've got my bag. Now it's a question of whether I can get all my crap in my bag.

    The current state of the CAT Board is stored in the skidlized branch of the CAT Board repository.

  • Conversion to SKiDL

    Dave Vandenbout05/04/2018 at 14:07 0 comments

    The first step in this resurrection was to convert the schematic-based CAT Board design into a SKiDL program. That was actually pretty easy. First, I generated a netlist from within EESCHEMA. Then I ran the following program to convert it into a SKiDL program:

    netlist_to_skidl -i cat.net -o cat-flat.py

     While the conversion was easy, it's not exactly what I want. The resulting code is flat: just a list of component instantiations and nets to interconnect them without any hierarchical structure. Making changes to that is no easier than hacking on the actual netlist file.

    The actual hierarchy for the CAT Board is shown below. It isn't a deep tree: just a bunch of peripherals attached to a central FPGA. But my goal is to make a parameterized SKiDL module for each peripheral. Then I can build not only the CAT Board by interconnecting those modules, but reuse them in other designs as part of a circuit library. A simple example would be an LED module that instantiates multiple LEDs and current-limiting resistors based upon the width of the bus entering the module.

    So why did I bother making the flat version of the SKiDL code? Some of the motivation was to show the use of the netlist_to_skidl utility since it's an easy way to generate SKiDL for those used to working with schematics. In addition, the flat code also includes the detailed templates of the components used in the CAT Board. I can reuse those in my parameterized version.

  • Resurrection

    Dave Vandenbout05/02/2018 at 02:39 1 comment

    My last log post for this project was over 1-1/2 years ago, but I'm returning to it now with the following objectives:

    • Rebuild the design using the SKiDL design language.
    • Replace the power supply section with smaller LDO/switching regulators.
    • Replace the large DC jack with a micro-USB connector that will be compatible with a Raspi power supply.
    • Replace the SDRAM in the TSSOP-54 package with a smaller VFBGA version.
    • Replace the two SATA connectors with an HDMI connector.
    • Add the PCB slot for the Raspi camera flex cable.

    Rebuilding the CAT Board using SKiDL will guide me in adding features to make the language more expressive and concise. The remaining changes will improve the capabilities of the board while possibly compacting the circuitry enough so I can get all the components on a single side of the PCB.

    Also, I took advantage of a StickerMule special to get 50 vinyl stickers for just $9. It'd be a shame to have these and no new board to go with 'em.

  • It Just Keeps Getting Easier!

    Dave Vandenbout09/25/2016 at 13:10 0 comments

    I learned about a new FOSS project a few weeks ago: apio. It's stated mission is:

    Experimental open source micro-ecosystem for open FPGAs. Based on platformio. Apio is a multiplatform toolbox, with static pre-built packages, project configuration tools and easy commands to verify, synthesize, simulate and upload your verilog designs.

    That sounded pretty good to me. It was easy to install on my RPi3:

    pip install apio
    That just installs the apio "shell". In order to get all the synthesis, simulation, and board tools, I used the command:

    apio install --all

    That automatically downloads and installs some system utilities, the Icestorm FPGA toolchain, the iverilog simulator, and some design examples for several types of iCE40 FPGA boards. Once that was completed, I could check to see what boards were supported:

    pi@raspberrypi:~ $ apio boards --list
    
    Supported boards:
    
    --------------------------------------------------------------------------------
    Board         FPGA                 Type  Size  Pack
    --------------------------------------------------------------------------------
    icoboard      iCE40-HX8K-CT256     hx    8k    ct256
    icezum        iCE40-HX1K-TQ144     hx    1k    tq144
    icestick      iCE40-HX1K-TQ144     hx    1k    tq144
    go-board      iCE40-HX1K-VQ100     hx    1k    vq100
    iCE40-HX8K    iCE40-HX8K-CT256     hx    8k    ct256
    
    Use `apio init --board <boardname>` for creating a new apio proyect for that board
    
    What!?!? No CAT Board in the list!?! I needed to fix that situation. I poked around in the apio Python code and found a likely file at apio/resources/boards.json. Inside that file, I pretty much copied the existing entry for the icoboard with a few modifications:
      "Cat-board": {
        "fpga": "iCE40-HX8K-CT256",
        "prog": "litterbox",
        "check": {
          "arch": "linux_armv7l"
        }
      }
    
    The only thing I changed (besides the board identifier) was the "prog" entry to list the litterbox utility that uploads bitstreams from the RPi3 to the FPGA on the CAT Board.

    I also had to modify the following section of the SConstruct file in the same directory:

    # -- Upload the bitstream into FPGA
    upload_cmd = ''
    if PROG == 'ftdi':
        upload_cmd = 'iceprog{0} -d i:0x0403:0x6010:{1} $SOURCE'.format(
            EXT, DEVICE)
    elif PROG == 'gpio':
        # Icoboard + RPI2: sram
        upload_cmd = 'export WIRINGPI_GPIOMEM=1; icoprog -p < $SOURCE'
    elif PROG == 'litterbox':
        # Cat Board + RPI2,3
        upload_cmd = 'sudo litterbox -c $SOURCE'

    This just adds the command for uploading a bitstream using the litterbox utility.

    Finally, after a little more poking around, I found the apio/managers/scons.py file and added the following code to its upload function:

            # -- Litterbox
            elif programmer == 'litterbox':
                # Cat Board + RPI2,3
                # Device argument is ignored
                if device and device != -1:
                    click.secho(
                        'Info: ignore device argument {0}'.format(device),
                        fg='yellow')
                # Check architecture
                arch = self.resources.boards[board]['check']['arch']
                current_arch = util.get_systype()
                if arch != current_arch:
                    # Incorrect architecture
                    click.secho(
                        'Error: incorrect architecture: RPI2 or RPI3 required',
                        fg='red')
                    return 1

    This does a sanity check to make sure the upload process for the CAT Board is occurring on an RPi2 or RPi3.

    Now when I regenerate the board list, I can see the CAT Board:

    pi@raspberrypi:~ $ apio boards --list
    
    Supported boards:
    
    --------------------------------------------------------------------------------
    Board         FPGA                 Type  Size  Pack
    --------------------------------------------------------------------------------
    icoboard      iCE40-HX8K-CT256     hx    8k    ct256
    icezum        iCE40-HX1K-TQ144     hx    1k    tq144
    Cat-board     iCE40-HX8K-CT256     hx    8k    ct256
    icestick      iCE40-HX1K-TQ144     hx    1k    tq144
    go-board      iCE40-HX1K-VQ100     hx    1k    vq100
    iCE40-HX8K    iCE40-HX8K-CT256     hx    8k    ct256
    
    Use `apio init --board <boardname>` for creating a new apio proyect for that board

    Once my modifications were complete, I went into the directory for the LED blinker and used the following command to indicate that this design was intended for the CAT Board:

    apio init --board Cat-board

    This creates an apio.ini file with a single line of text indicating the board...

    Read more »

  • That Was Fast!

    Dave Vandenbout09/01/2016 at 16:38 3 comments

    I've been away from this project for a few months (OK, four months) building things like a new tool for designing electronics. One of the things I haven't discussed here is the time it takes to download a bitstream to the FPGA on the CAT Board.

    As shown in previous logs, the FPGA is configured through one of the hardware SPI ports of the RPi. I've never considered SPI a very fast way of transferring data, so I initially set the port bit rate at 1 Mbps. That was good enough to get the FPGA going within a couple of seconds and there was no reason to push it and possibly cause errors while I debugged the board.

    But once the board was working reliably, I revisited the SPI bit-rate setting. I figured there was no harm in upping it to 5 Mbps just to see what happens. I went into the litterbox.py script and changed it to:

    self.spi.speed = 5000000
    Then I ran the command to load the FPGA with the bitstream for the LED blinker:
    sudo litterbox -c blinky.bin

    The download to the FPGA completed more quickly than before and the LED started blinking. Success!

    Then I started pushing for more: 10 Mbps, 20 Mbps, 50 Mbps, no problem; 100 Mbps, 150 Mbps, still five-by-five; 200 Mbps, complete and utter failure.

    OK, I hadn't expected to get even close to 200 Mbps. With a little trial and error, I finally found the maximum speed I could use was 199,999,999 bps. The reason for that becomes clear later.

    Now, was I actually transferring bits at 200 Mbps, or was the software making a promise that the hardware couldn't keep? To test that, I wrote some code to time the transmission of a 10 MByte payload and compute the effective bit-rate while I also observed the maximum SPI clock frequency and duty cycle with an oscilloscope:

    spi.speed (Mbps)Actual Speed (Mbps)Fmax (MHz)Duty Cycle (%)
    41.82.5---
    103.36.2554.0
    258.82536.1
    5010.75021.7
    6711.36717.9
    10012.010012.1
    15012.010012.1
    20012.82006.4

    As can be seen, the actual transmission speeds are quite a bit lower than the speed setting. The reason for that is the overhead in the python-spi module that copies and converts the individual 4096-byte packets of the payload before sending them to the SPI driver. Even though each packet gets transmitted at a high clock speed, there's a significant "dead time" (2.3 ms) while the software readies the next packet. As the raw speed increases, the packet transmission time decreases and the dead time (which stays constant) consumes a larger percentage of the time to send the full payload. That's why the duty cycle decreases as the speed setting increases.

    To decrease the overhead, I modified the python-spi code as follows:

    • The data payload is checked and no conversion or copying is done if it is already in the form of a string of bytes.
    • The address of the current packet within the payload is sent to the SPI device driver rather than making a copy of the packet.

    After these two changes, setting spi.speed to 100 Mbps resulted in an actual transmission speed of 65 Mbps (an increase of 540%).

    There's no reason to set the spi.speed to a value greater than 100 Mbps. The table indicates the RPi is generating the SPI clock by dividing a master 200 MHz clock by an integer. Any setting between 100 and 199 Mbps will result in an SPI clock of 100 MHz, and going to 200 Mbps has already proven too fast for sending an FPGA configuration bitstream. (The iCE40HX datasheet also shows the SPI clock in slave mode should not exceed 25 MHz, so getting to 100 MHz is really pushing it already.)

    A transfer rate of 65 Mbps opens up some interesting possibilities. That means there is an 8 MByte/second channel between the CAT Board FPGA and the RPi that uses only a few pins of the GPIO connector. I have some Xilinx-centric VHDL modules and a Python library that provide a printf-like debug interface for FPGA designs through the JTAG port. I can modify these to use the SPI port so the CAT Board + RPi will have the same capabilities. I'll be working on that next. I think. Maybe.

  • Getting to Blinky, MyHDL Style!

    Dave Vandenbout05/09/2016 at 23:34 2 comments

    In my previous post, I showed how to blink an LED on the CAT Board using Verilog. Now I'll do the same thing using MyHDL, a hardware description language based on Python.

    I'll assume a starting point of a Raspberry Pi running the Raspbian OS with the yosys, arachne-pnr and icestorm FPGA tools installed. If you're following along and haven't already got that, read the previous post. The stuff I describe here won't work without it.

    Install MyHDL

    Before you can use MyHDL, you have to install it. Installing the latest release is as simple as:

    sudo pip install myhdl

    But I like to use the development version because that's where all the new features are. That's installed like this:

    cd /opt
    sudo git clone https://github.com/jandecaluwe/myhdl.git
    cd myhdl
    sudo python setup.py install
    

    Blinky in MyHDL

    Blinking an LED with Verilog wasn't hard, and doing it in MyHDL isn't either. Here's the source code that's stored in a Python file called blinky.py.

    from myhdl import *
    
    # Define the Blinky module.
    @block
    def blinky(clk_i, led_o):
    
        cnt = Signal(intbv(0, 0, 50000000)) # Counter from 0 to 49999999.
        tgl = Signal(bool(0)) # Toggle flag drives the LED.
    
        # Sequential block triggered on every rising edge of the clock.
        @always_seq(clk_i.posedge, reset=None)
        def toggle_led():
            if cnt == cnt.max-1: # When the counter reaches its max value...
                tgl.next = ~tgl  # Toggle the flag...
                led_o.next = tgl # Output the flag to the LED...
                cnt.next = 0     # Reset the counter.
            else: # Counter hasn't reached max so just keep incrementing.
                cnt.next = cnt + 1
    
        # Return a reference to the Blinky logic.
        return toggle_led
    
    # Define the connections to Blinky.
    clk_i = Signal(bool(0))
    led_o = Signal(bool(0))
    
    # Create an instantiation of Blinky.
    top = blinky(clk_i, led_o)
    
    # Output Verilog code for Blinky.
    top.convert(hdl='Verilog')
    

    Compiling to Blinky

    The blinky.py file containing the MyHDL code shown above is executed as follows:

    python blinky.py

    This translates the MyHDL code into Verilog that's stored in the blinky.v file. Then this Verilog file can be compiled into a bitstream using the yosys, arachne-pnr and icepack tools just like in the previous post. Once the bitstream is downloaded to the CAT Board, the LED will blink.

    Raison de'Etre

    Why bother doing this in MyHDL? It just adds another step, but does it add any value?

    In this case, no, it doesn't. Because this design is so simple, the MyHDL code isn't any more compact or expressive than the original Verilog. The value of MyHDL is experienced when doing design exploration, i.e. trying various approaches to solving a problem. Then all the features of the Python ecosystem can be used with MyHDL to come up with a solution. I showed a few examples of this here and here.

  • Getting to Blinky, CAT Board Style!

    Dave Vandenbout05/02/2016 at 03:51 5 comments

    A fundamental rite of passage is getting your embedded system to blink an LED. In this post, I'll show you how to take a Raspberry Pi 3 fresh out of the box and get an LED blinking on the CAT Board.

    (If you're already experienced with the RPi, then a lot of this post will be redundant for you. However, I've found it useful to document processes so I can repeat them reliably at a later date when the details have grown fuzzy.)

    Install the OS

    The first thing to do is install an operating system (OS) on the RPi:

    1. Get the Raspbian OS for the RPi and unzip it on the PC.
    2. To write the OS image to the SD card, get the Win32DiskImager and install it on the PC.
    3. Use the Win32DiskImager to write the Raspbian OS to an SD card inserted in the PC. (This will take a while.)

    SSH Over Ethernet

    I'm going to use the RPi by connecting to it over a network SSH connection from my PC:

    1. Look in Network Connections to find the IP address of an Ethernet port the RPi can attach to.
    2. Go into the SD card and make a copy of the cmdline.txt file. Then rename the copy cmdline.normal. (This saves a copy of the original configuration in case I want to go back to it later.)
    3. Edit the cmdline.txt file to assign an IP address to the RPi that's identical to the one for the Ethernet port except for the last field. In my case, I selected 169.254.68.2 and appended it to the first (and only) line in the file to get:
      ip=169.254.68.2
    4. Save the cmdline.txt file and eject the SD card from the PC.
    5. Insert the SD card into the RPi.
    6. Connect the RPi to the PC's Ethernet port with a cable.
    7. Apply power to the RPi and let it boot up.
    8. To talk to the RPi using SSH from the PC, get PuTTY and install it.
    9. Run PuTTY and SSH into the RPi at address 169.254.68.2:
    10. Login to the RPi using the account "pi" and the password "raspberry".

    SSH Over the Wireless Network

    You can do everything over the wired Ethernet, but I prefer the convenience of using my local wireless network.

    1. To allow the RPi to access the local wireless network, open the /etc/wpa_supplicant/wpa_supplicant.conf file and append the following lines:
      network={
          ssid="XESS"
          psk="whatever_my_wireless_password_is"
      }
    2. Reboot the RPi and then look for the wireless connection using something like Advanced IP Scanner:
    3. Now disconnect the Ethernet cable and use PuTTY to SSH into the RPi over the wireless network using the IP address found in the last step (192.168.0.103).

    Enable File Sharing

    Sharing files between my PC and the RPi lets me use a familiar editor to write source that can then be dropped onto the RPi.

    1. To share files between the RPi and the PC, install Samba on the RPi like so:
      $ sudo apt-get update
      $ sudo apt-get install samba
      $ sudo apt-get install samba-common-bin
    2. Edit the /etc/samba/smb.conf file and add the following at the bottom:
    3. [pi]
      path=/home/pi
      writeable = yes
      browseable = yes
      only guest = no
      create mask = 0777
      directory mask = 0777
      public = yes
      Also, change the name of the workgroup to whatever is being used for the Windows PC:
      workgroup = XESS
    4. Start the Samba server running on the RPi:
    5. sudo service smbd start
    6. Open the Network window on the PC. The RPi should be visible there:
    7. Double-click the RASPBERRYPI icon and the shared directory will appear. Files can be transferred between the PC and RPi there:

    Reconfigure the RPi

    Before the RPi can be used to program the CAT Board FPGA, a few of its configuration settings need to be adjusted:

    1. On the RPi, type the command:
      sudo raspi-config
    2. In the initial screen that appears, select option 1 for expanding the linux partition. (The stock Raspbian OS image creates a 4GB partition. This won't be enough to compile the FPGA tools. Believe me, I tried.)As an alternative, you can also use the command-line version to do the same thing:
      sudo raspi-config --expand-rootfs
    3. Communicating with the CAT Board also requires the use of the RPi's hardware SPI port. That is enabled using the following screens:




    4. Finally, close raspi-config and reboot the RPi to let the changes take effect.

    Install the FPGA Software Tools

    There are five software...

    Read more »

  • CAT Board: All On It's Own

    Dave Vandenbout04/27/2016 at 02:51 2 comments

    One of the reasons for respinning the CAT Board PCB was to get the SPI flash chip connected correctly to the Lattice FPGA. The flash+FPGA+Raspberry Pi interconnection is complicated because it has to operate in three different modes:

    1. During development or when the FPGA is being used dynamically, the RPi has to be able to load a configuration bitstream into the FPGA.
    2. After development is completed, the RPi may want to store the finished FPGA bitstream into the flash.
    3. When the CAT Board is used stand-alone or when the FPGA performs some fixed function for the RPi, the FPGA has to be able to configure itself upon powerup with the bitstream stored in the flash.

    All three modes have to share a single SPI bus between all the devices while using a minimum of RPi GPIO signals and extra circuitry.

    Mode 3 is the easiest: when the FPGA powers up (or is reset), it checks to see if the SPI CS line is pulled high and, if so, becomes an SPI master and reads its configuration bitstream from the flash. The RPi GPIO signals are hidden behind the series resistors and can't interfere.

    Mode 2 is slightly more difficult. When the RPi is storing a bitstream by sending it to the flash chip's SI input, the SPI CS line is pulled low. But that also enables the SPI interface of the FPGA which could lead to interference if the FPGA's SDO output becomes active. To prevent this, the RPi asserts the reset pin of the FPGA so its SPI port can't turn on. Problem solved.

    Mode 1 is the most difficult. The RPi pulls the SPI CS line low as it removes the reset from the FPGA. This places the FPGA in slave mode so the RPi can send a bitstream to the FPGA's SPI port. But this also enables the flash chip's SPI port, which means the flash's SO output could interfere with the bitstream data. Unfortunately, there's no reset pin on the flash to keep it quiet. However, the flash does have a deep power-down mode that is entered by sending a specific command to the flash. Once in this state, it will not respond to anything until it receives another specific command to wake up. The RPi can then transfer the bitstream to the FPGA. During the transfer, there's no chance the wake-up command will be sent accidentally to the flash's SI input because 1) neither the RPi or FPGA will be driving that signal line during the configuration process, and 2) the flash only executes a command once its CS input goes high but the SPI CS line is held low for the entire duration of the bitstream transfer. So the flash will stay quiet and the RPi can send the bitstream to the FPGA in peace.

    Another complication of the shared SPI bus is that the roles of the RPi's MOSI and MISO pins are reversed in modes 1 and 2. In mode 1, the RPI's MOSI output pin drives the SDI input of the FPGA and the FPGA's SDO output drives the RPI's MISO input. That allows the hardware SPI port of the RPi to be used for the SPI transactions. But in mode 2, the RPi's MOSI pin acts as an input to receive data from the flash's SO output and the RPI's MISO pin has to drive the SI input pin of the flash. That precludes the use of the RPI's SPI hardware and the SPI transfers to/from the flash have to be done using bit banging.

    I searched for a ready-made SPI bit-banger program but nothing great popped up. So I just wrote one in Python using the RPi.GPIO library. It consists of a class for handling individual pin I/O, another class for SPI transactions, and a final class that handles most of the commands for the serial flash chip.

    To test the code, I first tried the command to read the device ID from the flash. The manufacturer and device IDs should have been 0x1F and 0x8401, respectively. Instead, I got 0xFF and 0xFFFF. That's OK; nothing ever works the first time.

    I probed with an oscilloscope to make sure the RPi was driving the correct pins of the flash. No problem there except that the SO pin was always high (naturally).

    Next, I pulled out my old HP LogicDart and sampled the waveforms on the CS, SCK and SI pins. Once again, no problems:...

    Read more »

View all 28 project logs

Enjoy this project?

Share

Discussions

Jason Wong wrote 07/14/2016 at 17:41 point

Do you have an update on whether you will be selling these and pricepoint?

  Are you sure? yes | no

Dave Vandenbout wrote 07/15/2016 at 02:05 point

No, I really don't have any plans for selling this. Lattice sells $22 iCE40 boards and Olimex has one for $25. Even though these use a small HX1K FPGA, they kind of set the price point of what people are expecting. Earlier this year, I calculated the part cost of the CAT Board with an HX8K at $17. Even if I could sell it at $50, I'd make almost nothing and still not many people would buy it.

It's open source, though, so feel free to build your own.

  Are you sure? yes | no

Mike Bloom wrote 06/02/2016 at 15:59 point

Hi Dave, very cool project.  I have actually been working on similar project off and on for a while with a Xilinx FPGA.  Glad to see that I am not the only one who had the idea of pairing the pi with FPGA.  I haven't posted anything yet but I might in the future.

Just a quick note based on an earlier comment where you mention the SPI as being slow.  I'm using this library (http://www.airspayce.com/mikem/bcm2835/index.html) to control the SPI interface.  My very rough calculations put the transfer rate at about 3 Mbit/s when I'm loading my bit file, and it can probably be pushed a bit faster.  I can share some code if you're interested.

  Are you sure? yes | no

Dave Vandenbout wrote 06/03/2016 at 17:40 point

Hi, Mike. Thanks for the reply. I actually sell the StickIt!-MB (http://www.xess.com/shop/product/stickit-mb-4_0/) that mates one of my XuLA Xilinx FPGA boards to an RPi. The only problem with that is I can't run the Xilinx programming tools on the RPi. Have you been able to do that?

In regards to the slow SPI, that's a problem only when I program the flash by bit-banging to arbitrary GPIO pins using Python. When I use the actual hardware SPI of the BCM2835 to program the FPGA directly, it's incredibly fast. I looked at the library you mentioned and it appears to only provide an interface to the hardware SPI port. Is the library also able to bit-bang to any set of GPIO pins?

  Are you sure? yes | no

Danny Bokma wrote 04/29/2016 at 20:03 point

Damn nice project! Funny name, just happen to have finished a etherCAT project :P (8 layer pcb from multi-circuit-boards.eu -> 5 boards 150 euro without stelcil ).


  Are you sure? yes | no

[deleted]

[this comment has been deleted]

Dave Vandenbout wrote 02/09/2016 at 00:38 point

Hi, Brosnan.

I used a hot air gun (actually, it's a paint remover) because that's what I have.

A few years ago, I made a video about how to solder BGAs. It's not that hard to do. 

  Are you sure? yes | no

Dave Vandenbout wrote 01/25/2016 at 14:40 point

Hi, Sami. The CAT Board isn't available for sale at this time. I'm still considering whether that would be worthwhile.

The main limitation of the CAT Board is the slow interface to the RPi through the GPIO connector.

  Are you sure? yes | no

Sami wrote 01/16/2016 at 10:38 point

Hi, 

I would like to get and test one of your CAT FPGA board for Raspberry Pi 2 B. How can I order one from you?  

Have you found any limitations in your CAT board?

Best regards,

Sami

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates