Compare commits
15 Commits
Author | SHA1 | Date |
---|---|---|
Sean Cross | 63315d9a58 | |
Sean Cross | 798a0f167e | |
Sean Cross | 9506159380 | |
Sean Cross | 89af26047e | |
Sean Cross | 9876d92981 | |
Sean Cross | f4297532d0 | |
Sean Cross | 4156a37d72 | |
Sean Cross | f2ae56a13e | |
Sean Cross | 61151b4618 | |
Sean Cross | d6bff65d0b | |
Sean Cross | ea6c170023 | |
Sean Cross | d2b4ff089d | |
Sean Cross | fb21ad75e2 | |
Sean Cross | 5e3ac61921 | |
Peter Marheine | eb328612b2 |
|
@ -16,7 +16,10 @@ The EVT boards can be attached directly to the Raspberry Pi as a "hat". When bu
|
|||
|
||||
The only pins that are required are 5V, GND, CRESET, SPI_MOSI, SPI_MISO, SPI_CLK, and SPI_CS.
|
||||
|
||||
You can improve performance by attaching SPI_IO2 and SPI_IO3 and running `fomu-flash` in quad/qpi mode by specifying `-t 4` or `-t q`.
|
||||
The Pi's hardware SPI interface must be enabled in the kernel- use
|
||||
`raspi-config` or add `dtparam=spi=on` to `/boot/config.txt` and reboot before
|
||||
using. You can improve performance by attaching SPI_IO2 and SPI_IO3 and running
|
||||
`fomu-flash` in quad/qpi mode by specifying `-t 4` or `-t q`.
|
||||
|
||||
You can get serial interaction by connecting the UART pins, but they are not necessary for flashing.
|
||||
|
||||
|
|
915
fomu-flash.c
915
fomu-flash.c
File diff suppressed because it is too large
Load Diff
112
fpga.c
112
fpga.c
|
@ -11,11 +11,11 @@
|
|||
#include "fpga.h"
|
||||
|
||||
struct ff_fpga {
|
||||
struct {
|
||||
int reset;
|
||||
int done;
|
||||
int cs;
|
||||
} pins;
|
||||
struct {
|
||||
int reset;
|
||||
int done;
|
||||
int cs;
|
||||
} pins;
|
||||
};
|
||||
|
||||
int fpgaDone(struct ff_fpga *fpga) {
|
||||
|
@ -23,90 +23,90 @@ int fpgaDone(struct ff_fpga *fpga) {
|
|||
}
|
||||
|
||||
int fpgaResetSlave(struct ff_fpga *fpga) {
|
||||
// Put the FPGA into reset
|
||||
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
||||
gpioWrite(fpga->pins.reset, 0);
|
||||
// Put the FPGA into reset
|
||||
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
||||
gpioWrite(fpga->pins.reset, 0);
|
||||
|
||||
// Set the CS pin to a GPIO, which will let us control it
|
||||
gpioSetMode(fpga->pins.cs, PI_OUTPUT);
|
||||
// Set the CS pin to a GPIO, which will let us control it
|
||||
gpioSetMode(fpga->pins.cs, PI_OUTPUT);
|
||||
|
||||
// Set CS to 0, which will put the FPGA into slave mode
|
||||
gpioWrite(fpga->pins.cs, 0);
|
||||
// Set CS to 0, which will put the FPGA into slave mode
|
||||
gpioWrite(fpga->pins.cs, 0);
|
||||
|
||||
usleep(10000); // XXX figure out correct sleep length here
|
||||
usleep(10000); // XXX figure out correct sleep length here
|
||||
|
||||
// Bring the FPGA out of reset
|
||||
gpioWrite(fpga->pins.reset, 1);
|
||||
// Bring the FPGA out of reset
|
||||
gpioWrite(fpga->pins.reset, 1);
|
||||
|
||||
usleep(1200); // 13.2.SPI Slave Configuration Process
|
||||
usleep(1200); // 13.2.SPI Slave Configuration Process
|
||||
|
||||
// Release the CS pin
|
||||
gpioWrite(fpga->pins.cs, 1);
|
||||
// Release the CS pin
|
||||
gpioWrite(fpga->pins.cs, 1);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fpgaResetMaster(struct ff_fpga *fpga) {
|
||||
|
||||
// Put the FPGA into reset
|
||||
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
||||
gpioWrite(fpga->pins.reset, 0);
|
||||
// Put the FPGA into reset
|
||||
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
||||
gpioWrite(fpga->pins.reset, 0);
|
||||
|
||||
// Set the CS pin to a GPIO, which will let us control it
|
||||
gpioSetMode(fpga->pins.cs, PI_OUTPUT);
|
||||
// Set the CS pin to a GPIO, which will let us control it
|
||||
gpioSetMode(fpga->pins.cs, PI_OUTPUT);
|
||||
|
||||
// Set CS to 1, which will put the FPGA into "self boot" mode
|
||||
gpioWrite(fpga->pins.cs, 1);
|
||||
// Set CS to 1, which will put the FPGA into "self boot" mode
|
||||
gpioWrite(fpga->pins.cs, 1);
|
||||
|
||||
usleep(10000); // XXX figure out correct sleep length here
|
||||
usleep(10000); // XXX figure out correct sleep length here
|
||||
|
||||
// Bring the FPGA out of reset
|
||||
gpioWrite(fpga->pins.reset, 1);
|
||||
// Bring the FPGA out of reset
|
||||
gpioWrite(fpga->pins.reset, 1);
|
||||
|
||||
usleep(1200); // 13.2.SPI Slave Configuration Process
|
||||
usleep(1200); // 13.2.SPI Slave Configuration Process
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fpgaReset(struct ff_fpga *fpga) {
|
||||
// Put the FPGA into reset
|
||||
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
||||
gpioWrite(fpga->pins.reset, 0);
|
||||
return 0;
|
||||
// Put the FPGA into reset
|
||||
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
||||
gpioWrite(fpga->pins.reset, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fpgaInit(struct ff_fpga *fpga) {
|
||||
// Put the FPGA into reset
|
||||
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
||||
gpioWrite(fpga->pins.reset, 0);
|
||||
// Put the FPGA into reset
|
||||
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
||||
gpioWrite(fpga->pins.reset, 0);
|
||||
|
||||
// Also monitor the C_DONE pin
|
||||
gpioSetMode(fpga->pins.done, PI_INPUT);
|
||||
// Also monitor the C_DONE pin
|
||||
gpioSetMode(fpga->pins.done, PI_INPUT);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ff_fpga *fpgaAlloc(void) {
|
||||
struct ff_fpga *fpga = (struct ff_fpga *)malloc(sizeof(struct ff_fpga));
|
||||
memset(fpga, 0, sizeof(*fpga));
|
||||
return fpga;
|
||||
struct ff_fpga *fpga = (struct ff_fpga *)malloc(sizeof(struct ff_fpga));
|
||||
memset(fpga, 0, sizeof(*fpga));
|
||||
return fpga;
|
||||
}
|
||||
|
||||
void fpgaSetPin(struct ff_fpga *fpga, enum fpga_pin pin, int val) {
|
||||
switch (pin) {
|
||||
case FP_RESET: fpga->pins.reset = val; break;
|
||||
case FP_DONE: fpga->pins.done = val; break;
|
||||
case FP_CS: fpga->pins.cs = val; break;
|
||||
default: fprintf(stderr, "unrecognized pin: %d\n", pin); break;
|
||||
}
|
||||
switch (pin) {
|
||||
case FP_RESET: fpga->pins.reset = val; break;
|
||||
case FP_DONE: fpga->pins.done = val; break;
|
||||
case FP_CS: fpga->pins.cs = val; break;
|
||||
default: fprintf(stderr, "unrecognized pin: %d\n", pin); break;
|
||||
}
|
||||
}
|
||||
|
||||
void fpgaFree(struct ff_fpga **fpga) {
|
||||
if (!fpga)
|
||||
return;
|
||||
if (!*fpga)
|
||||
return;
|
||||
if (!fpga)
|
||||
return;
|
||||
if (!*fpga)
|
||||
return;
|
||||
|
||||
free(*fpga);
|
||||
*fpga = NULL;
|
||||
free(*fpga);
|
||||
*fpga = NULL;
|
||||
}
|
||||
|
|
56
ice40.h
56
ice40.h
|
@ -1,28 +1,28 @@
|
|||
#ifndef _ICE40_H
|
||||
#define _ICE40_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct irw_file
|
||||
{
|
||||
FILE *f;
|
||||
uint16_t crc;
|
||||
uint32_t offset;
|
||||
void *hook_data;
|
||||
int (*read_hook)(void *data);
|
||||
int (*write_hook)(void *data, uint8_t b);
|
||||
} IRW_FILE;
|
||||
|
||||
struct irw_file *irw_open(const char *filename, const char *mode);
|
||||
struct irw_file *irw_open_fake(void *hook_data,
|
||||
int (*read_hook)(void *data),
|
||||
int (*write_hook)(void *data, uint8_t b));
|
||||
int irw_readb(struct irw_file *f);
|
||||
int irw_writeb(struct irw_file *f, int c);
|
||||
void irw_close(struct irw_file **f);
|
||||
|
||||
int ice40_patch(struct irw_file *f, struct irw_file *rom,
|
||||
struct irw_file *o, uint32_t byte_count);
|
||||
|
||||
#endif /* _ICE40_H */
|
||||
#ifndef _ICE40_H
|
||||
#define _ICE40_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct irw_file
|
||||
{
|
||||
FILE *f;
|
||||
uint16_t crc;
|
||||
uint32_t offset;
|
||||
void *hook_data;
|
||||
int (*read_hook)(void *data);
|
||||
int (*write_hook)(void *data, uint8_t b);
|
||||
} IRW_FILE;
|
||||
|
||||
struct irw_file *irw_open(const char *filename, const char *mode);
|
||||
struct irw_file *irw_open_fake(void *hook_data,
|
||||
int (*read_hook)(void *data),
|
||||
int (*write_hook)(void *data, uint8_t b));
|
||||
int irw_readb(struct irw_file *f);
|
||||
int irw_writeb(struct irw_file *f, int c);
|
||||
void irw_close(struct irw_file **f);
|
||||
|
||||
int ice40_patch(struct irw_file *f, struct irw_file *rom,
|
||||
struct irw_file *o, uint32_t byte_count);
|
||||
|
||||
#endif /* _ICE40_H */
|
||||
|
|
Loading…
Reference in New Issue