diff options
Diffstat (limited to 'src/flexloader.c')
-rw-r--r-- | src/flexloader.c | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/src/flexloader.c b/src/flexloader.c new file mode 100644 index 0000000..324fa48 --- /dev/null +++ b/src/flexloader.c @@ -0,0 +1,233 @@ +/*************************************************************************** + flexloader.c - Routines to download code to an Altera FLEX FPGA + --------------------------------------------------------------- + + begin : Sun Jan 09 2004 + copyright : (C) 2005 by Aurelien Jarno + email : aurelien@aurel32.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +/* Application specific includes */ +#include "flexloader.h" +#include "byteblaster.h" +#include "main.h" + +/* Standard includes */ +#include <stdio.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + + +/*************************************************************************** + * * + * Declarations * + * * + ***************************************************************************/ + +#define TIMEOUT 500 /* ms */ + + +/*************************************************************************** + * * + * Private functions * + * * + ***************************************************************************/ + +static int flex_config(int device) +{ + int t; + + set_DCLK(device, 0); + set_DATA0(device, 1); + set_nCONFIG(device, 1); + enable_byteblaster(device, 1); + usleep(100000); + + if (debug) + printf("Configuring FLEX\n"); + + for (t = TIMEOUT / 10 ; t > 0 ; t--) + { + if (get_nSTATUS(device) == 1) + break; + usleep(10000); + } + if (t == 0) + { + if (!quiet) + fprintf(stderr, "nSTATUS != 1\n"); + return -1; + } + + set_nCONFIG(device, 0); + + for (t = TIMEOUT / 10 ; t > 0 ; t--) + { + if (get_nSTATUS(device) == 0) + break; + usleep(10000); + } + if (t == 0) + { + if (!quiet) + fprintf(stderr, "nSTATUS != 0\n"); + return -1; + } + + for (t = TIMEOUT / 10 ; t > 0 ; t--) + { + if (get_CONF_DONE(device) == 0) + break; + usleep(10000); + } + if (t == 0) + { + if (!quiet) + fprintf(stderr, "CONF_DONE != 0\n"); + return -1; + } + + set_nCONFIG(device, 1); + + for (t = TIMEOUT / 10 ; t > 0 ; t--) + { + if (get_nSTATUS(device) == 1) + break; + usleep(10000); + } + if (t == 0) + { + if (!quiet) + fprintf(stderr, "nSTATUS != 1\n"); + return -1; + } + + usleep(40000); + return 0; +} + +static int flex_download(int device, int file) +{ + int byte, bit; + unsigned char data; + + if (debug) + printf("Downloading code\n"); + + for(byte = 0 ; ; byte++) + { + if (debug) + printf("Downloading byte %i\n", byte); + + if (read(file, &data, 1) != 1) + { + if (!quiet) + fprintf(stderr, "Unexpected end of file\n"); + return -1; + } + + for (bit = 0 ; bit < 8 ; bit++) + { + set_DATA0(device, data & 0x01); + set_DCLK(device, 1); + set_DCLK(device, 0); + data >>= 1; + + if (get_nSTATUS(device) == 0) + { + if (!quiet) + fprintf(stderr, "Checksum error\n"); + return -1; + } + + if (get_CONF_DONE(device) == 1) + { + if (!quiet) + printf("%i bytes downloaded\n", byte); + return 0; + } + } + } +} + +static void flex_init(int device) +{ + int i; + + if (debug) + printf("Initializing FLEX\n"); + + /* more clocks required to initialize the device */ + for (i = 0 ; i < 10 ; i++) + { + set_DCLK(device, 1); + set_DCLK(device, 0); + } +} + + +/*************************************************************************** + * * + * Public functions * + * * + ***************************************************************************/ + +int flex_download_program(char *device, char *rbf_file) +{ + int fd; + int byteblaster; + + if (debug) + printf("Opening %s\n", rbf_file); + + fd = open(rbf_file, O_RDONLY); + + if (fd < 0) + { + if (!quiet) + { + perror("open"); + fprintf(stderr, "Can't open %s!\n", rbf_file); + } + return -1; + } + + byteblaster = open_byteblaster(device); + + if (byteblaster < 0) + return -1; + + if (flex_config(byteblaster) < 0) + { + if (!quiet) + fprintf(stderr, "Altera FLEX not found!\n"); + return -1; + } + + if (flex_download(byteblaster, fd) < 0) + { + if (!quiet) + fprintf(stderr, "Download failed\n"); + return -1; + } + + flex_init(byteblaster); + + close_byteblaster(byteblaster); + + close(fd); + return 0; +} + |