Skip to content

Instantly share code, notes, and snippets.

@daveshah1
Created March 20, 2019 18:44
Show Gist options
  • Save daveshah1/2fcf18c9d9bc5104175276afc1c3a5b4 to your computer and use it in GitHub Desktop.
Save daveshah1/2fcf18c9d9bc5104175276afc1c3a5b4 to your computer and use it in GitHub Desktop.
Simple bitbang iCE40 programmer
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
// FIXME: This will break once we have a real MMU ;)
volatile uint32_t *gpio = (uint32_t*)0xe000f000; //FIXME
#define CRESET 1U
#define CSN 2U
#define SCLK 4U
#define MOSI 8U
void set_gpio(int p, int v) {
if (v)
*gpio |= p;
else
*gpio &= ~p;
}
void write_byte(int b) {
for (int i = 7; i >= 0; i--) {
set_gpio(MOSI, b & (1 << i));
//usleep(2);
set_gpio(SCLK, 1);
//usleep(2);
set_gpio(SCLK, 0);
//usleep(2);
}
}
int main(int argc, char *argv[]) {
if (argc <= 1) {
printf("Expected bitstream\n");
exit(1);
}
FILE *fp = fopen(argv[1], "r");
printf("Entering SSPI mode...\n");
// Enter programming mode
set_gpio(CSN, 0);
set_gpio(SCLK, 1);
set_gpio(MOSI, 0);
set_gpio(CRESET, 0);
usleep(1000);
set_gpio(CRESET, 1);
usleep(1000);
set_gpio(CSN, 1);
set_gpio(SCLK, 0);
for (int i = 0; i < 8; i++) {
set_gpio(SCLK, 1);
set_gpio(SCLK, 0);
}
usleep(2);
set_gpio(CSN, 0);
int i = 0;
printf("Loading bitstream...\n");
while(1) {
++i;
int c = fgetc(fp);
if (c == EOF)
break;
if ((i % 10000) == 0)
printf("%d\n", i);
write_byte(c);
}
set_gpio(CSN, 1);
for (int i = 0; i < 49; i++) {
set_gpio(SCLK, 1);
set_gpio(SCLK, 0);
}
printf("Entering user design...\n");
while (1) {
set_gpio(SCLK, 1);
usleep(100000);
set_gpio(SCLK, 0);
usleep(100000);
}
fclose(fp);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment