Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
63315d9a58 | |||
798a0f167e | |||
9506159380 | |||
89af26047e | |||
9876d92981 | |||
f4297532d0 | |||
4156a37d72 | |||
f2ae56a13e | |||
61151b4618 | |||
d6bff65d0b | |||
ea6c170023 | |||
d2b4ff089d | |||
fb21ad75e2 | |||
5e3ac61921 | |||
|
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.
|
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.
|
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"
|
#include "fpga.h"
|
||||||
|
|
||||||
struct ff_fpga {
|
struct ff_fpga {
|
||||||
struct {
|
struct {
|
||||||
int reset;
|
int reset;
|
||||||
int done;
|
int done;
|
||||||
int cs;
|
int cs;
|
||||||
} pins;
|
} pins;
|
||||||
};
|
};
|
||||||
|
|
||||||
int fpgaDone(struct ff_fpga *fpga) {
|
int fpgaDone(struct ff_fpga *fpga) {
|
||||||
|
@ -23,90 +23,90 @@ int fpgaDone(struct ff_fpga *fpga) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int fpgaResetSlave(struct ff_fpga *fpga) {
|
int fpgaResetSlave(struct ff_fpga *fpga) {
|
||||||
// Put the FPGA into reset
|
// Put the FPGA into reset
|
||||||
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
||||||
gpioWrite(fpga->pins.reset, 0);
|
gpioWrite(fpga->pins.reset, 0);
|
||||||
|
|
||||||
// Set the CS pin to a GPIO, which will let us control it
|
// Set the CS pin to a GPIO, which will let us control it
|
||||||
gpioSetMode(fpga->pins.cs, PI_OUTPUT);
|
gpioSetMode(fpga->pins.cs, PI_OUTPUT);
|
||||||
|
|
||||||
// Set CS to 0, which will put the FPGA into slave mode
|
// Set CS to 0, which will put the FPGA into slave mode
|
||||||
gpioWrite(fpga->pins.cs, 0);
|
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
|
// Bring the FPGA out of reset
|
||||||
gpioWrite(fpga->pins.reset, 1);
|
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
|
// Release the CS pin
|
||||||
gpioWrite(fpga->pins.cs, 1);
|
gpioWrite(fpga->pins.cs, 1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fpgaResetMaster(struct ff_fpga *fpga) {
|
int fpgaResetMaster(struct ff_fpga *fpga) {
|
||||||
|
|
||||||
// Put the FPGA into reset
|
// Put the FPGA into reset
|
||||||
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
||||||
gpioWrite(fpga->pins.reset, 0);
|
gpioWrite(fpga->pins.reset, 0);
|
||||||
|
|
||||||
// Set the CS pin to a GPIO, which will let us control it
|
// Set the CS pin to a GPIO, which will let us control it
|
||||||
gpioSetMode(fpga->pins.cs, PI_OUTPUT);
|
gpioSetMode(fpga->pins.cs, PI_OUTPUT);
|
||||||
|
|
||||||
// Set CS to 1, which will put the FPGA into "self boot" mode
|
// Set CS to 1, which will put the FPGA into "self boot" mode
|
||||||
gpioWrite(fpga->pins.cs, 1);
|
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
|
// Bring the FPGA out of reset
|
||||||
gpioWrite(fpga->pins.reset, 1);
|
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) {
|
int fpgaReset(struct ff_fpga *fpga) {
|
||||||
// Put the FPGA into reset
|
// Put the FPGA into reset
|
||||||
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
||||||
gpioWrite(fpga->pins.reset, 0);
|
gpioWrite(fpga->pins.reset, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fpgaInit(struct ff_fpga *fpga) {
|
int fpgaInit(struct ff_fpga *fpga) {
|
||||||
// Put the FPGA into reset
|
// Put the FPGA into reset
|
||||||
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
gpioSetMode(fpga->pins.reset, PI_OUTPUT);
|
||||||
gpioWrite(fpga->pins.reset, 0);
|
gpioWrite(fpga->pins.reset, 0);
|
||||||
|
|
||||||
// Also monitor the C_DONE pin
|
// Also monitor the C_DONE pin
|
||||||
gpioSetMode(fpga->pins.done, PI_INPUT);
|
gpioSetMode(fpga->pins.done, PI_INPUT);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ff_fpga *fpgaAlloc(void) {
|
struct ff_fpga *fpgaAlloc(void) {
|
||||||
struct ff_fpga *fpga = (struct ff_fpga *)malloc(sizeof(struct ff_fpga));
|
struct ff_fpga *fpga = (struct ff_fpga *)malloc(sizeof(struct ff_fpga));
|
||||||
memset(fpga, 0, sizeof(*fpga));
|
memset(fpga, 0, sizeof(*fpga));
|
||||||
return fpga;
|
return fpga;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fpgaSetPin(struct ff_fpga *fpga, enum fpga_pin pin, int val) {
|
void fpgaSetPin(struct ff_fpga *fpga, enum fpga_pin pin, int val) {
|
||||||
switch (pin) {
|
switch (pin) {
|
||||||
case FP_RESET: fpga->pins.reset = val; break;
|
case FP_RESET: fpga->pins.reset = val; break;
|
||||||
case FP_DONE: fpga->pins.done = val; break;
|
case FP_DONE: fpga->pins.done = val; break;
|
||||||
case FP_CS: fpga->pins.cs = val; break;
|
case FP_CS: fpga->pins.cs = val; break;
|
||||||
default: fprintf(stderr, "unrecognized pin: %d\n", pin); break;
|
default: fprintf(stderr, "unrecognized pin: %d\n", pin); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fpgaFree(struct ff_fpga **fpga) {
|
void fpgaFree(struct ff_fpga **fpga) {
|
||||||
if (!fpga)
|
if (!fpga)
|
||||||
return;
|
return;
|
||||||
if (!*fpga)
|
if (!*fpga)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
free(*fpga);
|
free(*fpga);
|
||||||
*fpga = NULL;
|
*fpga = NULL;
|
||||||
}
|
}
|
||||||
|
|
56
ice40.h
56
ice40.h
|
@ -1,28 +1,28 @@
|
||||||
#ifndef _ICE40_H
|
#ifndef _ICE40_H
|
||||||
#define _ICE40_H
|
#define _ICE40_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct irw_file
|
typedef struct irw_file
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
uint16_t crc;
|
uint16_t crc;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
void *hook_data;
|
void *hook_data;
|
||||||
int (*read_hook)(void *data);
|
int (*read_hook)(void *data);
|
||||||
int (*write_hook)(void *data, uint8_t b);
|
int (*write_hook)(void *data, uint8_t b);
|
||||||
} IRW_FILE;
|
} IRW_FILE;
|
||||||
|
|
||||||
struct irw_file *irw_open(const char *filename, const char *mode);
|
struct irw_file *irw_open(const char *filename, const char *mode);
|
||||||
struct irw_file *irw_open_fake(void *hook_data,
|
struct irw_file *irw_open_fake(void *hook_data,
|
||||||
int (*read_hook)(void *data),
|
int (*read_hook)(void *data),
|
||||||
int (*write_hook)(void *data, uint8_t b));
|
int (*write_hook)(void *data, uint8_t b));
|
||||||
int irw_readb(struct irw_file *f);
|
int irw_readb(struct irw_file *f);
|
||||||
int irw_writeb(struct irw_file *f, int c);
|
int irw_writeb(struct irw_file *f, int c);
|
||||||
void irw_close(struct irw_file **f);
|
void irw_close(struct irw_file **f);
|
||||||
|
|
||||||
int ice40_patch(struct irw_file *f, struct irw_file *rom,
|
int ice40_patch(struct irw_file *f, struct irw_file *rom,
|
||||||
struct irw_file *o, uint32_t byte_count);
|
struct irw_file *o, uint32_t byte_count);
|
||||||
|
|
||||||
#endif /* _ICE40_H */
|
#endif /* _ICE40_H */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user