Compare commits

...

15 Commits
v1.2 ... master

Author SHA1 Message Date
Sean Cross 63315d9a58 fomu-flash: exit nonzero on write error
Signed-off-by: Sean Cross <sean@xobs.io>
2021-04-14 14:11:06 +08:00
Sean Cross 798a0f167e ice40: hardcode ora_ptr
The previous approach of attempting to derive it didn't work.

It turns out that the ora_ptr is 16 * the current offset.

Signed-off-by: Sean Cross <sean@xobs.io>
2019-02-26 15:12:45 +08:00
Sean Cross 9506159380 fomu-flash: disable ICE40_DEBUG_PATCH
Since we've got ice40 working, we don't need to debug it anymore.

Signed-off-by: Sean Cross <sean@xobs.io>
2019-02-26 14:49:11 +08:00
Sean Cross 89af26047e ice40: rewrite matching heuristic to increase reliability
Instead of looping through a small window, figure out the various bit
positions and offsets.  Then, as we scan through, validate that we've
found the proper offsets.

This should get us to 100% reliability.

Signed-off-by: Sean Cross <sean@xobs.io>
2019-02-26 14:48:05 +08:00
Sean Cross 9876d92981 fpga: convert tabs to spaces
Signed-off-by: Sean Cross <sean@xobs.io>
2019-02-26 13:10:19 +08:00
Sean Cross f4297532d0 fomu-flash: make DEBUG_ICE40_PATCH work better
Signed-off-by: Sean Cross <sean@xobs.io>
2019-02-26 13:08:13 +08:00
Sean Cross 4156a37d72 fomu-flash: convert tabs to spaces
Signed-off-by: Sean Cross <sean@xobs.io>
2019-02-26 13:03:09 +08:00
Sean Cross f2ae56a13e ice40: convert tabs to spaces
Signed-off-by: Sean Cross <sean@xobs.io>
2019-02-26 13:02:41 +08:00
Sean Cross 61151b4618 fomu-flash: add debug hack to fix ice40 stuff
This will write data to a file, rather than to SPI.

Signed-off-by: Sean Cross <sean@xobs.io>
2019-02-26 13:01:04 +08:00
Sean Cross d6bff65d0b Merge branch 'master' of github.com:im-tomu/fomu-flash 2019-02-25 22:17:38 +08:00
Sean Cross ea6c170023 ice40: lower fuzz size to improve patcher reliability
The fuzz size should be made smaller, because we're getting too many false positives.

Signed-off-by: Sean Cross <sean@xobs.io>
2019-02-25 22:16:31 +08:00
Sean Cross d2b4ff089d ice40: convert from dos to unix line endings
Signed-off-by: Sean Cross <sean@xobs.io>
2019-02-25 18:38:53 +08:00
Sean Cross fb21ad75e2
Merge pull request #3 from tari/hardware-spi
Document the requirement for hardware SPI
2019-02-25 17:11:10 +08:00
Sean Cross 5e3ac61921
Merge branch 'master' into hardware-spi 2019-02-25 17:10:11 +08:00
Peter Marheine eb328612b2 Document the requirement for hardware SPI
I spent a while fighting with my hardware before working this out- if
SPI is disabled in the kernel reads will return all 1s which is very
confusing and looks more like something is wired up wrong when it's
actually correct.
2019-02-25 14:56:02 +11:00
5 changed files with 1117 additions and 971 deletions

View File

@ -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.

File diff suppressed because it is too large Load Diff

112
fpga.c
View File

@ -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;
}

1000
ice40.c

File diff suppressed because it is too large Load Diff

56
ice40.h
View File

@ -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 */