/*************************************************************************** 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 #include #include #include #include #include /*************************************************************************** * * * 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; }