aboutsummaryrefslogtreecommitdiff
path: root/src/flexloader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/flexloader.c')
-rw-r--r--src/flexloader.c233
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;
+}
+