[Armadeus-commitlog] SF.net SVN: armadeus:[1112] trunk/target/linux/modules/fpga/dev_tools/ fpga_de
Brought to you by:
sszy
|
From: <ar...@us...> - 2009-03-04 18:34:12
|
Revision: 1112
http://armadeus.svn.sourceforge.net/armadeus/?rev=1112&view=rev
Author: artemys
Date: 2009-03-04 18:34:02 +0000 (Wed, 04 Mar 2009)
Log Message:
-----------
[LINUX] Add APF27 support to fpgaloader (part1)
Modified Paths:
--------------
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/Makefile
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.c
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.h
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.c
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.h
Added Paths:
-----------
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/apf27-fpga-loader.c
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/apf9328-fpga-loader.c
Removed Paths:
-------------
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.c
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.h
Modified: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/Makefile 2009-03-04 09:51:13 UTC (rev 1111)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/Makefile 2009-03-04 18:34:02 UTC (rev 1112)
@@ -1,17 +1,16 @@
#
# Makefile for the Armadeus FPGA loader driver
-# PATH=$HOME/nico/test/buildroot/build_arm_nofpu/staging_dir/bin:$PATH
-# make ARCH=arm
-# tftp -gr fpgaloader.ko -l /lib/modules/drivers/fpgaloader.ko 192.168.0.3
-# tftp -gr fpga_test.bit 192.168.0.3
-# insmod /lib/modules/drivers/fpgaloader.ko
-# dd if=fpga_test.bit of=/dev/fpga/loader
+#
-
ifneq ($(KERNELRELEASE),)
obj-$(CONFIG_ARMADEUS_FPGA_TOOL_DRIVER) += fpgaloader.o
-fpgaloader-objs := target-fpga-loader.o xilinx-fpga-loader.o fpga-loader.o
+ifneq ($(CONFIG_MACH_APF27),)
+fpgaloader-objs := apf27-fpga-loader.o xilinx-fpga-loader.o fpga-loader.o
+endif
+ifneq ($(CONFIG_MACH_APF9328),)
+fpgaloader-objs := apf9328-fpga-loader.o xilinx-fpga-loader.o fpga-loader.o
+endif
else
@@ -25,8 +24,8 @@
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
- rm -f *.*o \
- rm -f Module.symvers
+ $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
+ rm -f modules.order Module.markers
endif
Added: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/apf27-fpga-loader.c
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/apf27-fpga-loader.c (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/apf27-fpga-loader.c 2009-03-04 18:34:02 UTC (rev 1112)
@@ -0,0 +1,186 @@
+/*
+ * APF27 Xilinx FPGA download support
+ * Copyright (C) 2009 Nicolas Colombain <nic...@ar...>
+ * Armadeus Project / Armadeus systems
+ *
+ * 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, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/version.h>
+#include <mach/iomux-mx1-mx2.h>
+#include <mach/gpio.h>
+#include <asm/io.h>
+#include <linux/kernel.h>
+#include <mach/hardware.h>
+
+#include "xilinx-fpga-loader.h"
+
+#define FPGA_BASE_ADDR CS5_BASE_ADDR
+#define FPGA_VIRT_ADDR (IO_ADDRESS(FPGA_BASE_ADDR) + 0x0)
+
+#define CFG_FPGA_PWR (GPIO_PORTF | 19) /* FPGA prog pin */
+#define CFG_FPGA_PRG (GPIO_PORTF | 11) /* FPGA prog pin */
+#define CFG_FPGA_CLK (GPIO_PORTF | 15) /* FPGA clk pin */
+#define CFG_FPGA_RDATA 0xD6000000 /* FPGA data addr */
+#define CFG_FPGA_WDATA 0xD6000000 /* FPGA data addr */
+#define CFG_FPGA_INIT (GPIO_PORTF | 12) /* FPGA init pin */
+#define CFG_FPGA_DONE (GPIO_PORTF | 9) /* FPGA done pin */
+#define CFG_FPGA_RW (GPIO_PORTF | 21) /* FPGA done pin */
+#define CFG_FPGA_CS (GPIO_PORTF | 22) /* FPGA done pin */
+#define CFG_FPGA_SUSPEND (GPIO_PORTF | 10) /* FPGA done pin */
+#define CFG_FPGA_RESET (GPIO_PORTF | 7) /* FPGA done pin */
+
+#define NB_TARGET_DESC 2
+
+
+/* Initialize GPIO port before download */
+int fpga_pre_fn (void)
+{
+ gpio_set_value(CFG_FPGA_PWR, 1);
+ gpio_set_value(CFG_FPGA_PRG, 1);
+ gpio_set_value(CFG_FPGA_CLK, 1);
+ gpio_set_value(CFG_FPGA_RW, 1);
+ gpio_set_value(CFG_FPGA_CS, 1);
+ gpio_set_value(CFG_FPGA_SUSPEND, 0);
+ gpio_set_value(CFG_FPGA_RESET, 0);
+
+ /* Initialize GPIO pins */
+ mxc_gpio_mode(CFG_FPGA_PWR | GPIO_OUT | GPIO_PUEN | GPIO_GPIO);
+ mxc_gpio_mode(CFG_FPGA_INIT | GPIO_IN | GPIO_PUEN | GPIO_GPIO);
+ mxc_gpio_mode(CFG_FPGA_DONE | GPIO_IN | GPIO_PUEN | GPIO_GPIO);
+ mxc_gpio_mode(CFG_FPGA_PRG | GPIO_OUT | GPIO_PUEN | GPIO_GPIO);
+ mxc_gpio_mode(CFG_FPGA_CLK | GPIO_OUT | GPIO_PUEN | GPIO_GPIO);
+ mxc_gpio_mode(CFG_FPGA_RW | GPIO_OUT | GPIO_PUEN | GPIO_GPIO);
+ mxc_gpio_mode(CFG_FPGA_CS | GPIO_OUT | GPIO_PUEN | GPIO_GPIO);
+ mxc_gpio_mode(CFG_FPGA_SUSPEND | GPIO_OUT | GPIO_PUEN | GPIO_GPIO);
+ mxc_gpio_mode(CFG_FPGA_RESET | GPIO_OUT | GPIO_PUEN | GPIO_GPIO);
+
+ gpio_set_value(CFG_FPGA_PWR, 0);
+ return 1;
+}
+
+/*
+ * Set the FPGA's active-low program line to the specified level
+ */
+int fpga_pgm_fn (int assert)
+{
+ gpio_set_value( CFG_FPGA_PRG, !assert);
+ return assert;
+}
+
+/*
+ * Set the FPGA's active-high clock line to the specified level
+ */
+int fpga_clk_fn (int assert_clk)
+{
+ gpio_set_value( CFG_FPGA_CLK, !assert_clk);
+ return assert_clk;
+}
+
+/*
+ * Test the state of the active-low FPGA INIT line. Return 1 on INIT
+ * asserted (low).
+ */
+int fpga_init_fn (void)
+{
+ int value;
+ value = gpio_get_value(CFG_FPGA_INIT);
+ return !value;
+}
+
+/*
+ * Test the state of the active-high FPGA DONE pin
+ */
+int fpga_done_fn (void)
+{
+ return(gpio_get_value(CFG_FPGA_DONE));
+}
+
+/*
+ * Set the FPGA's wr line to the specified level
+ */
+int fpga_wr_fn (int assert_write)
+{
+ gpio_set_value( CFG_FPGA_RW, !assert_write);
+ return assert_write;
+}
+
+int fpga_cs_fn (int assert_cs)
+{
+ gpio_set_value( CFG_FPGA_CS, !assert_cs);
+ return assert_cs;
+}
+
+int fpga_wdata_fn ( unsigned char data )
+{
+ __raw_writew(data, FPGA_VIRT_ADDR);
+ return data;
+}
+
+int fpga_busy_fn (void)
+{
+ return 0;
+}
+
+int fpga_post_fn (void)
+{
+ mxc_gpio_mode (CFG_FPGA_RW | GPIO_PF | GPIO_PUEN);
+ mxc_gpio_mode (CFG_FPGA_CS | GPIO_PF | GPIO_PUEN);
+ mxc_gpio_mode (CFG_FPGA_CLK | GPIO_PF | GPIO_PUEN);
+ gpio_set_value(CFG_FPGA_PRG, 1);
+ return 1;
+}
+
+int fpga_abort_fn (void)
+{
+ fpga_post_fn();
+ gpio_set_value(CFG_FPGA_PWR, 1);
+ return 1;
+}
+
+/* Note that these are pointers to code that is in Flash. They will be
+ * relocated at runtime.
+ * Spartan2 code is used to download our Spartan 3 :) code is compatible.
+ * Just take care about the file size
+ */
+Xilinx_Spartan3_Slave_Parallel_fns fpga_fns = {
+ fpga_pre_fn,
+ fpga_pgm_fn,
+ fpga_clk_fn,
+ fpga_init_fn,
+ fpga_done_fn,
+ fpga_wr_fn,
+ fpga_cs_fn,
+ fpga_wdata_fn,
+ fpga_busy_fn,
+ fpga_abort_fn,
+ fpga_post_fn,
+};
+
+Xilinx_desc target_fpga_desc[NB_TARGET_DESC] = {
+ {
+ Xilinx_Spartan,
+ slave_parallel,
+ 1196128l/8,
+ (void *) &fpga_fns
+ },
+ {
+ Xilinx_Spartan,
+ slave_parallel,
+ 1887216l/8,
+ (void *) &fpga_fns
+ },
+};
Added: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/apf9328-fpga-loader.c
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/apf9328-fpga-loader.c (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/apf9328-fpga-loader.c 2009-03-04 18:34:02 UTC (rev 1112)
@@ -0,0 +1,124 @@
+/*
+ * APF9328 Xilinx FPGA download support
+ * Copyright (C) 2006-2009 Nicolas Colombain <nic...@ar...>
+ * Copyright (C) 2006-2009 Eric Jarrige <eri...@ar...>
+ * Armadeus Project / Armadeus systems
+ *
+ * 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, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+#include <asm/arch/hardware.h>
+#else
+#include <mach/hardware.h>
+#endif
+#include <asm/io.h>
+
+#include "xilinx-fpga-loader.h"
+
+#define FPGA_INIT (GPIO_PORTB | 15) /* FPGA init pin (SSI input) */
+#define FPGA_DONE (GPIO_PORTB | 16) /* FPGA done pin (SSI input) */
+#define FPGA_DIN (GPIO_PORTB | 17) /* FPGA data pin (SSI output) */
+#define FPGA_PROGRAM (GPIO_PORTB | 18) /* FPGA prog pin (SSI output) */
+#define FPGA_CLOCK (GPIO_PORTB | 19) /* FPGA clk pin (SSI output) */
+
+#define GPIO_PORT(x) ((x >> 5) & 3)
+#define GPIO_SET(x) (DR(GPIO_PORT(x)) |= (1<<(x & GPIO_PIN_MASK)))
+#define GPIO_CLEAR(x) (DR(GPIO_PORT(x)) &= ~(1<<(x & GPIO_PIN_MASK)))
+#define GPIO_WRITE(x,y) ( y ? GPIO_SET(x) : GPIO_CLEAR(x) )
+#define GPIO_READ(x) ((SSR (GPIO_PORT(x)) & (1<<(x & GPIO_PIN_MASK))))
+
+/*
+ * Set the FPGA's active-low program line to the specified level
+ */
+int fpga_pgm_fn( int assert )
+{
+ GPIO_WRITE( FPGA_PROGRAM, !assert);
+ return assert;
+}
+
+/*
+ * Set the FPGA's active-high clock line to the specified level
+ */
+int fpga_clk_fn( int assert_clk )
+{
+ GPIO_WRITE( FPGA_CLOCK, assert_clk);
+ return assert_clk;
+}
+
+/*
+ * Test the state of the active-low FPGA INIT line. Return 1 on INIT
+ * asserted (low).
+ */
+int fpga_init_fn( void )
+{
+ return(!GPIO_READ(FPGA_INIT));
+}
+
+/*
+ * Test the state of the active-high FPGA DONE pin
+ */
+int fpga_done_fn( void )
+{
+ return(GPIO_READ(FPGA_DONE));
+}
+
+/*
+ * Set the FPGA's data line to the specified level
+ */
+int fpga_wr_fn( int assert_write )
+{
+ GPIO_WRITE( FPGA_DIN, assert_write);
+ return assert_write;
+}
+
+int fpga_pre_fn( void )
+{
+ /* Initialize GPIO pins */
+ imx_gpio_mode (FPGA_INIT | GPIO_GIUS | GPIO_DR | GPIO_IN );
+ imx_gpio_mode (FPGA_DONE | GPIO_GIUS | GPIO_DR | GPIO_IN );
+ imx_gpio_mode (FPGA_DIN | GPIO_GIUS | GPIO_DR | GPIO_OUT );
+ imx_gpio_mode (FPGA_PROGRAM | GPIO_GIUS | GPIO_DR | GPIO_OUT );
+ imx_gpio_mode (FPGA_CLOCK | GPIO_GIUS | GPIO_DR | GPIO_OUT );
+ return 1;
+}
+
+
+Xilinx_Spartan_Slave_Serial_fns fpga_fns = {
+ fpga_pre_fn,
+ fpga_pgm_fn,
+ fpga_clk_fn,
+ fpga_init_fn,
+ fpga_done_fn,
+ fpga_wr_fn,
+};
+
+Xilinx_desc target_fpga_desc[/*NB_TARGET_DESC*/] = {
+
+ { /* first supported configuration (default) */
+ Xilinx_Spartan,
+ slave_serial,
+ XILINX_XC3S200_SIZE,
+ (void *) &fpga_fns
+ },
+ { /* second one */
+ Xilinx_Spartan,
+ slave_serial,
+ XILINX_XC3S400_SIZE,
+ (void *) &fpga_fns
+ },
+};
Modified: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.c
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.c 2009-03-04 09:51:13 UTC (rev 1111)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.c 2009-03-04 18:34:02 UTC (rev 1112)
@@ -1,10 +1,9 @@
/*
- ***********************************************************************
+ * Generic Xilinx FPGA loader
*
- * (c) Copyright 2006 Armadeus project
- * Julien Boibessot <jul...@ar...>
- * Nicolas Colombain <nic...@ar...>
- * Generic Xilinx FPGA loader
+ * Copyright (C) 2006-2009 Julien Boibessot <jul...@ar...>
+ * Nicolas Colombain <nic...@ar...>
+ * Armadeus Project / Armadeus systems
*
* 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
@@ -19,20 +18,14 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- **********************************************************************
*/
+
+// #define DEBUG
+
#include <linux/version.h>
#include "fpga-loader.h"
#include "xilinx-fpga-loader.h"
#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
-#include <asm/arch/imx-regs.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-#include <linux/config.h>
-#endif
-#else
-#include <mach/imx-regs.h>
-#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
@@ -61,9 +54,7 @@
static unsigned char g_nb_users = 0;
-void __exit armadeus_fpga_cleanup(void);
-
//------------------------------------------------
//
// Handles write() done on /dev/fpgaxx
@@ -71,7 +62,7 @@
static ssize_t armadeus_fpga_write(struct file *file, const char* pData, size_t count, loff_t *f_pos)
{
ssize_t ret = 0;
-
+
// Get exclusive access
if (down_interruptible(&fpga_sema))
return -ERESTARTSYS;
@@ -92,22 +83,33 @@
out:
// Release exclusive access
up(&fpga_sema);
-
+
return( ret );
}
static int armadeus_fpga_open(struct inode *inode, struct file *file)
{
int ret;
-
- // Only one access at a time is permitted
+
+ /* Get exclusive access */
+ if (down_interruptible(&fpga_sema))
+ return -ERESTARTSYS;
+
+ /* Only one access at a time is permitted */
if( g_nb_users > 0 )
return( -EBUSY );
- g_nb_users++;
- ret = xilinx_init_load( g_current_desc );
+ ret = xilinx_init_load( g_current_desc );
+ if(!ret) {
+ printk("Starting FPGA download\n");
+ g_nb_users++;
+ }
- PRINTF("Opening /dev/fpga/loader%d file, %d %d\n", MINOR(inode->i_rdev), fpga_descriptor, ret);
+ pr_debug("Opening /dev/fpga/loader%d file, %d %d\n", MINOR(inode->i_rdev), fpga_descriptor, ret);
+
+ /* Release exclusive access */
+ up(&fpga_sema);
+
return ret;
}
@@ -116,13 +118,16 @@
if( g_nb_users > 0 )
g_nb_users--;
- PRINTF("Closing access to /dev/fpga/loader%d\n", MINOR(inode->i_rdev));
+ if( xilinx_finish_load(g_current_desc) )
+ printk("Failed to load FPGA !\n");
+
+ pr_debug("Closing access to /dev/fpga/loader%d\n", MINOR(inode->i_rdev));
return 0;
}
-//------------------------------------------------
-// PROC file
-//
+
+/* PROC file */
+
static int procfile_fpga_read( char *buffer, __attribute__ ((unused)) char **start, off_t offset, int buffer_length, int *eof, __attribute__ ((unused)) void* data)
{
int ret;
@@ -134,10 +139,9 @@
/* we have finished to read, return 0 */
ret = 0;
} else {
- if ( data == NULL ){
+ if ( data == NULL ) {
ret = xilinx_get_descriptor_info( -1, buffer );
- }
- else {
+ } else {
ret = xilinx_get_descriptor_info( *((unsigned char*)data), buffer );
}
}
@@ -145,15 +149,12 @@
return ret;
}
-
static int procfile_fpga_write( __attribute__ ((unused)) struct file *file, const char *buf, unsigned long count, void *data)
{
- return count;
+ return count;
}
-//------------------------------------------------
-// Handling of IOCTL calls
-//
+/* Handling of IOCTL calls */
int armadeus_fpga_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg )
{
int err = 0; int ret = 0;
@@ -182,8 +183,8 @@
printk("Minor outside range: %d !\n", minor);
return -EFAULT;
}
-
- switch(cmd)
+
+ switch(cmd)
{
default:
return -ENOTTY;
@@ -195,96 +196,82 @@
return ret;
}
-//
-// Create /proc entries for direct access (with echo/cat) to GPIOs config
-//
+/* Create /proc entries for direct access to FPGA config */
static int createProcEntries( void )
{
static struct proc_dir_entry *fpga_Proc_File;
- // Create main directory
+
+ /* Create main directory */
proc_mkdir(FPGA_PROC_DIRNAME, NULL);
- // Create proc file to handle GPIO values
- fpga_Proc_File = create_proc_entry( FPGA_PROC_FILENAME, S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, NULL );
- if( fpga_Proc_File == NULL )
- {
+ /* Create proc file */
+ fpga_Proc_File = create_proc_entry( FPGA_PROC_FILENAME, S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, NULL );
+ if( fpga_Proc_File == NULL ) {
printk(FPGA_DRIVER_NAME ": Could not register a" FPGA_PROC_FILENAME ". Terminating\n");
- armadeus_fpga_cleanup();
- return -ENOMEM;
- }
- else
- {
- fpga_Proc_File->read_proc = procfile_fpga_read;
+ goto error;
+ } else {
+ fpga_Proc_File->read_proc = procfile_fpga_read;
fpga_Proc_File->write_proc = procfile_fpga_write;
}
-
- return(0);
+
+ return 0;
+error:
+ remove_proc_entry(FPGA_PROC_DIRNAME, NULL);
+ return -ENOMEM;
}
static struct file_operations fpga_fops = {
.owner = THIS_MODULE,
.write = armadeus_fpga_write,
-// .read = armadeus_fpga_read,
+/* .read = armadeus_fpga_read, Configuration saving not supported yet */
.open = armadeus_fpga_open,
.release = armadeus_fpga_release,
.ioctl = armadeus_fpga_ioctl,
};
-//
-// Module's initialization function
-//
int __init armadeus_fpga_init(void)
{
static int result;
- // Register the driver by getting a major number
+ /* Register the driver by getting a major number */
result = register_chrdev(fpga_major, FPGA_DRIVER_NAME, &fpga_fops);
if (result < 0)
{
printk(KERN_WARNING FPGA_DRIVER_NAME ": can't get major %d\n", fpga_major);
return result;
}
- if( fpga_major == 0 ) fpga_major = result; // dynamic Major allocation
+ if( fpga_major == 0 ) fpga_major = result; /* dynamic MAJOR allocation */
- // Creating /proc entries
result = createProcEntries();
if( result < 0 ) return( result );
- // Initialise FPGA semaphore
sema_init(&fpga_sema, 1);
- // initialize the current fpga descriptor with the one by default
+ /* initialize the current fpga descriptor with the one by default */
g_current_desc = xilinx_get_descriptor(fpga_descriptor);
if( g_current_desc == NULL ){
return -EINVAL;
}
- printk(FPGA_DRIVER_NAME " module " FPGA_DRIVER_VERSION " successfully loaded !\n");
+ printk(FPGA_DRIVER_NAME " v" FPGA_DRIVER_VERSION " successfully loaded !\n");
return(0);
}
-//
-// Module's cleanup function
-//
void __exit armadeus_fpga_cleanup(void)
{
- PRINTF("Removing " FPGA_DRIVER_NAME " module: ");
+ pr_debug("Removing " FPGA_DRIVER_NAME ": ");
- // Remove /proc entries
remove_proc_entry(FPGA_PROC_FILENAME, NULL);
- // Remove /proc directory entry
remove_proc_entry(FPGA_PROC_DIRNAME, NULL);
- // De-register /dev interface
unregister_chrdev(fpga_major, FPGA_DRIVER_NAME);
- PRINTF("Ok !\n");
+ pr_debug("Ok !\n");
}
-//------------------------------------------------
-
module_init(armadeus_fpga_init);
module_exit(armadeus_fpga_cleanup);
-MODULE_AUTHOR("JB / NC");
-MODULE_DESCRIPTION("Armadeus fpga's loading driver");
+MODULE_AUTHOR("Julien Boibessot / Nicolas Colombain");
+MODULE_DESCRIPTION("Armadeus FPGA loading driver");
MODULE_LICENSE("GPL");
+
Modified: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.h
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.h 2009-03-04 09:51:13 UTC (rev 1111)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.h 2009-03-04 18:34:02 UTC (rev 1112)
@@ -28,7 +28,7 @@
#define FPGA_PROC_DIRNAME "driver/fpga"
#define FPGA_PROC_FILENAME FPGA_PROC_DIRNAME "/loader"
-#define FPGA_DRIVER_VERSION "v0.0.6"
+#define FPGA_DRIVER_VERSION "0.8"
#define FPGA_DRIVER_NAME "fpgaloader"
// By default, we use dynamic allocation of major numbers
Deleted: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.c
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.c 2009-03-04 09:51:13 UTC (rev 1111)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.c 2009-03-04 18:34:02 UTC (rev 1112)
@@ -1,121 +0,0 @@
-/*
- **********************************************************************
- * 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- **********************************************************************
-
- (c) Copyright 2006 Armadeus project
- Eric Jarrige <eri...@ar...>
- Nicolas Colombain <nic...@ar...>
- Target Xilinx FPGA support
-*/
-
-#include "target-fpga-loader.h"
-#include "xilinx-fpga-loader.h"
-#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
-#include <asm/arch/hardware.h>
-#else
-#include <mach/hardware.h>
-#endif
-#include <asm/io.h>
-
-#define GPIO_PORT(x) ((x >> 5) & 3)
-#define GPIO_SET(x) (DR(GPIO_PORT(x)) |= (1<<(x & GPIO_PIN_MASK)))
-#define GPIO_CLEAR(x) (DR(GPIO_PORT(x)) &= ~(1<<(x & GPIO_PIN_MASK)))
-#define GPIO_WRITE(x,y) ( y ? GPIO_SET(x) : GPIO_CLEAR(x) )
-#define GPIO_READ(x) ((SSR (GPIO_PORT(x)) & (1<<(x & GPIO_PIN_MASK))))
-
-/*
- * Set the FPGA's active-low program line to the specified level
- */
-int fpga_pgm_fn( int assert )
-{
- GPIO_WRITE( FPGA_PROGRAM, !assert);
- return assert;
-}
-
-/*
- * Set the FPGA's active-high clock line to the specified level
- */
-int fpga_clk_fn( int assert_clk )
-{
- GPIO_WRITE( FPGA_CLOCK, assert_clk);
- return assert_clk;
-}
-
-/*
- * Test the state of the active-low FPGA INIT line. Return 1 on INIT
- * asserted (low).
- */
-int fpga_init_fn( void )
-{
- return(!GPIO_READ(FPGA_INIT));
-}
-
-/*
- * Test the state of the active-high FPGA DONE pin
- */
-int fpga_done_fn( void )
-{
- return(GPIO_READ(FPGA_DONE));
-}
-
-/*
- * Set the FPGA's data line to the specified level
- */
-int fpga_wr_fn( int assert_write )
-{
- GPIO_WRITE( FPGA_DIN, assert_write);
- return assert_write;
-}
-
-int fpga_pre_fn( void )
-{
- // Initialize GPIO pins
- imx_gpio_mode (FPGA_INIT | GPIO_GIUS | GPIO_DR | GPIO_IN );
- imx_gpio_mode (FPGA_DONE | GPIO_GIUS | GPIO_DR | GPIO_IN );
- imx_gpio_mode (FPGA_DIN | GPIO_GIUS | GPIO_DR | GPIO_OUT );
- imx_gpio_mode (FPGA_PROGRAM | GPIO_GIUS | GPIO_DR | GPIO_OUT );
- imx_gpio_mode (FPGA_CLOCK | GPIO_GIUS | GPIO_DR | GPIO_OUT );
- return 1;
-}
-
-
-Xilinx_Spartan_Slave_Serial_fns fpga_fns = {
- fpga_pre_fn,
- fpga_pgm_fn,
- fpga_clk_fn,
- fpga_init_fn,
- fpga_done_fn,
- fpga_wr_fn,
-};
-
-Xilinx_desc target_fpga_desc[NB_TARGET_DESC] = {
-
- { // first supported configuration (default)
- Xilinx_Spartan,
- slave_serial,
- XILINX_XC3S200_SIZE,
- (void *) &fpga_fns
- },
-
- { // second one
- Xilinx_Spartan,
- slave_serial,
- XILINX_XC3S400_SIZE,
- (void *) &fpga_fns
- }
-};
-
Deleted: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.h
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.h 2009-03-04 09:51:13 UTC (rev 1111)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.h 2009-03-04 18:34:02 UTC (rev 1112)
@@ -1,45 +0,0 @@
-/*
- **********************************************************************
- * 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- **********************************************************************
-
- (c) Copyright 2006 Armadeus project
- Eric Jarrige <eri...@ar...>
- Nicolas Colombain <nic...@ar...>
- Target Xilinx FPGA support
-
-*/
-#ifndef __TARGET_FPGA_LOADER_H__
-#define __TARGET_FPGA_LOADER_H__
-
-
-#include "xilinx-fpga-loader.h"
-#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
-#include <asm/arch/imx-regs.h>
-#else
-#include <mach/imx-regs.h>
-#endif
-#include <asm/io.h>
-
-#define FPGA_INIT (GPIO_PORTB | 15) /* FPGA init pin (SSI input) */
-#define FPGA_DONE (GPIO_PORTB | 16) /* FPGA done pin (SSI input) */
-#define FPGA_DIN (GPIO_PORTB | 17) /* FPGA data pin (SSI output) */
-#define FPGA_PROGRAM (GPIO_PORTB | 18) /* FPGA prog pin (SSI output) */
-#define FPGA_CLOCK (GPIO_PORTB | 19) /* FPGA clk pin (SSI output) */
-
-#define NB_TARGET_DESC 2
-
-#endif // __TARGET_FPGA_LOADER_H__
Modified: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.c
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.c 2009-03-04 09:51:13 UTC (rev 1111)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.c 2009-03-04 18:34:02 UTC (rev 1112)
@@ -1,9 +1,9 @@
/*
- * (c) Copyright 2006 Armadeus project
- * Nicolas Colombain <nic...@ar...>
- * Xilinx FPGA support
+ * Xilinx FPGAs download support
+ * Copyright (C) 2006-2009 Nicolas Colombain <nic...@ar...>
+ * Armadeus Project / Armadeus systems
*
- * Based on the implementation(uBoot) of:
+ * Based on the implementation (U-Boot) of:
* Rich Ireland, Enterasys Networks, rir...@en....
* Keith Outwater, kei...@mv...
*
@@ -27,21 +27,19 @@
*
*/
-#include "xilinx-fpga-loader.h"
-#include "target-fpga-loader.h"
#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
-#include <asm/arch/imx-regs.h>
-#else
-#include <mach/imx-regs.h>
-#endif
#include <asm/io.h>
#include <linux/time.h>
+#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <asm/irqflags.h>
+#include <asm/delay.h>
+#include "xilinx-fpga-loader.h"
+
#define CONFIG_FPGA_DELAY()
-#define CFG_FPGA_WAIT 4000 // uS
+#define CFG_FPGA_WAIT 20000 // uS
size_t bytecount = 0; // total bytes received
extern Xilinx_desc target_fpga_desc[]; // target descriptor table
@@ -66,40 +64,36 @@
{
int len;
len = sprintf( buffer, "%s %s %u\n",
- (desc->family == Xilinx_Spartan) ? "spartan":"unknown",
- (desc->iface == slave_serial) ? "slave serial":"unknown",
+ (desc->family == Xilinx_Spartan) ? "spartan":"unknown",
+ (desc->iface == slave_serial) ? "slave serial":"slave parallel",
desc->size );
return len;
}
/**
- * program the FPGA.
+ * program the FPGA (serial mode).
* return 0 if success, >0 while programming, <0 if error detected
*/
static size_t spartan_serial_load (Xilinx_desc *desc, const char* buf, size_t bsize)
{
Xilinx_Spartan_Slave_Serial_fns *fn = desc->iface_fns;
+
if (fn) {
- unsigned long ts; /* timestamp */
-
- /* Load the data */
- if( bytecount<=desc->size ) {
int i;
unsigned char val;
size_t nbbyte = 0; // init local counter
while (nbbyte < bsize) {
-
- /* Xilinx detects an error if INIT goes low (active)
+ /* Spartan signals an error if INIT goes low (active)
while DONE is low (inactive) */
if ((*fn->done)() == 0 && (*fn->init)()) {
- PRINTF ("** CRC error during FPGA load.\n");
+ printk("** CRC error during FPGA load.\n");
return -ETIMEDOUT;
}
val = buf[nbbyte ++];
- bytecount++;
+ bytecount++;
i = 8;
- do {
+ do {
/* Deassert the clock */
(*fn->clk)(0);
CONFIG_FPGA_DELAY ();
@@ -111,38 +105,19 @@
CONFIG_FPGA_DELAY ();
val <<= 1;
i --;
- } while (i > 0);
- }
- }
- if( bytecount>=desc->size )
- {
- CONFIG_FPGA_DELAY ();
+ } while (i > 0);
+ }
- /* now check for done signal */
- ts = get_timer(0); /* get current time */
- (*fn->wr)(1);
-
- while (! (*fn->done)()) {
- CONFIG_FPGA_DELAY ();
- (*fn->clk)(0); /* Deassert the clock pin */
- CONFIG_FPGA_DELAY ();
- (*fn->clk)(1); /* Assert the clock pin */
-
- if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */
- PRINTF ("** Timeout waiting for DONE.\n");
- return -ETIMEDOUT;
- }
- }
- }
- return bsize;
- }
+ if(bytecount%4096 == 0) printk(".");
+ return bsize;
+ }
return -EINVAL;
}
/**
- * initialize the FPGA programming interface.
+ * initialize the FPGA programming interface.
* return 0 if success, <0 if error detected
- */
+ */
static int spartan_serial_init (Xilinx_desc *desc)
{
Xilinx_Spartan_Slave_Serial_fns *fn = desc->iface_fns;
@@ -158,7 +133,7 @@
/* Wait for INIT state (init low) */
ts = get_timer(0); /* get current time */
- do {
+ do {
CONFIG_FPGA_DELAY ();
if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */
PRINTF ("** Timeout waiting for INIT to start.\n");
@@ -171,7 +146,7 @@
(*fn->pgm)(0); /* Deassert the program, commit */
ts = get_timer(0); /* get current time */
- /* Now wait for INIT to go high */
+ /* Now wait for INIT to go high */
do {
CONFIG_FPGA_DELAY ();
if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */
@@ -186,22 +161,170 @@
return -EINVAL;
}
+/* terminate the FPGA load (serial mode) */
+static int spartan_serial_finish(Xilinx_desc *desc)
+{
+ unsigned long timestamp;
+ Xilinx_Spartan_Slave_Serial_fns *fn = desc->iface_fns;
+
+ if (fn) {
+ CONFIG_FPGA_DELAY ();
+
+ /* now check for done signal */
+ timestamp = get_timer(0); /* get current time */
+ (*fn->wr)(1);
+
+ while (! (*fn->done)()) {
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk)(0); /* Deassert the clock pin */
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk)(1); /* Assert the clock pin */
+
+ if (get_timer(timestamp) > CFG_FPGA_WAIT) {
+ pr_debug("** Timeout waiting for DONE.\n");
+ return -ETIMEDOUT;
+ }
+ }
+ }
+ return 0;
+}
+
+
/**
- * program the FPGA.
+ * initialize the FPGA programming interface.
+ * return 0 if success, <0 if error detected
+ */
+static int spartan_parallel_init (Xilinx_desc *desc)
+{
+ Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns;
+ if (fn) {
+ unsigned long ts; /* timestamp */
+ /*
+ * Run the pre configuration function if there is one.
+ */
+ if (*fn->pre) {
+ (*fn->pre) ();
+ }
+ mdelay(100);
+
+ /* Establish the initial state */
+ (*fn->pgm) (1); /* Assert the program, commit */
+ ts = get_timer (0); /* get current time */
+ /* Now wait for INIT to go down */
+ do {
+ CONFIG_FPGA_DELAY ();
+ if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */
+ PRINTF ("** Timeout waiting for INIT to set.\n");
+ (*fn->abort) (); /* abort the burn */
+ return -ETIMEDOUT;
+ }
+ } while (!(*fn->init) () );
+
+
+ /* Get ready for the burn */
+ CONFIG_FPGA_DELAY ();
+ (*fn->pgm) (0); /* Deassert the program, commit */
+
+ ts = get_timer (0); /* get current time */
+ /* Now wait for INIT and BUSY to go high */
+ do {
+ CONFIG_FPGA_DELAY ();
+ if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */
+ PRINTF ("** Timeout waiting for INIT to clear.\n");
+ (*fn->abort) (); /* abort the burn */
+ return -ETIMEDOUT;
+ }
+ } while ((*fn->init) ());
+ (*fn->wr) (1); /* Assert write, commit */
+ (*fn->cs) (1); /* Assert chip select, commit */
+ (*fn->clk) (1); /* Assert the clock pin */
+ bytecount = 0; // reset byte count
+ }
+ return 0;
+}
+
+/**
+ * program the FPGA (parallel mode).
* return 0 if success, >0 while programming, <0 if error detected
*/
+static size_t spartan_parallel_load (Xilinx_desc *desc, const char* buf, size_t bsize)
+{
+ unsigned long flags;
+ Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns;
+
+ if (fn) {
+ /* Load the data */
+ size_t nbbyte = 0; // init local counter
+
+ raw_local_irq_save(flags);
+
+ while (nbbyte < bsize) {
+ (*fn->clk) (1); /* Assert the clock pin */
+ CONFIG_FPGA_DELAY ();
+ (*fn->wdata) (buf[nbbyte++]); /* write the data */
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk) (0); /* Deassert the clock pin */
+ bytecount++;
+ }
+ raw_local_irq_restore(flags);
+
+ return bsize;
+ }
+ return -EINVAL;
+}
+
+/* terminate the FPGA load (parallel mode) */
+static int spartan_parallel_finish(Xilinx_desc *desc)
+{
+ Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns;
+ unsigned long timestamp;
+
+ if (fn) {
+ /* now check for done signal */
+ timestamp = get_timer(0); /* get current time */
+ while (!(*fn->done) ()) {
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk) (0); /* Deassert the clock pin */
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk) (1); /* Assert the clock pin */
+
+ if (get_timer(timestamp) > CFG_FPGA_WAIT) {
+ printk("** Timeout waiting for DONE to clear. %d \n", bytecount);
+ (*fn->abort) (); /* abort the burn */
+ return -ETIMEDOUT;
+ }
+ }
+ /* Spartan signals an error if INIT goes low (active) */
+ if (!(*fn->init)()) {
+ printk("** CRC error during FPGA load.\n");
+ (*fn->abort) (); /* abort the burn */
+ return -ETIMEDOUT;
+ }
+
+ (*fn->cs) (0); /* Deassert the chip select */
+ (*fn->wr) (0); /* Deassert the write pin */
+ }
+
+ return 0;
+}
+
+/**
+ * program the FPGA.
+ * return 0 if success, >0 while programming, <0 if error detected
+ */
size_t xilinx_load( Xilinx_desc *desc, const char *buf, size_t bsize )
{
int ret = 0;
if( desc ) {
- switch( desc->family ) // check family
+ switch( desc->family ) /* check family */
{
case Xilinx_Spartan:
{
- switch( desc->iface ) // check donwload hardware interface
+ switch( desc->iface ) /* check donwload hardware interface */
{
case slave_serial: ret = spartan_serial_load( desc, buf, bsize ); break;
+ case slave_parallel: ret = spartan_parallel_load (desc, buf, bsize); break;
default: PRINTF("interface not supported!\n"); ret = -ENOSYS; break;
}
}
@@ -217,9 +340,9 @@
}
/**
- * initialize the FPGA programming interface.
+ * initialize the FPGA programming interface.
* return 0 if success, <0 if error detected
- */
+ */
int xilinx_init_load( Xilinx_desc *desc )
{
int ret = 0;
@@ -232,6 +355,7 @@
switch( desc->iface ) // check donwload hardware interface
{
case slave_serial: ret = spartan_serial_init( desc ); break;
+ case slave_parallel: ret = spartan_parallel_init( desc ); break;
default: PRINTF("interface not supported!\n"); ret = -ENOSYS; break;
}
}
@@ -246,10 +370,49 @@
return ret;
}
-/**
+int xilinx_finish_load( Xilinx_desc *desc )
+{
+ int ret = 0;
+
+ if( desc ) {
+ switch( desc->family )
+ {
+ case Xilinx_Spartan:
+ {
+ switch( desc->iface ) /* check donwload hardware interface */
+ {
+ case slave_serial:
+ ret = spartan_serial_finish( desc );
+ break;
+ case slave_parallel:
+ ret = spartan_parallel_finish( desc );
+ break;
+ default:
+ PRINTF("interface not supported!\n");
+ ret = -ENOSYS;
+ break;
+ }
+ }
+ break;
+ default:
+ PRINTF("family not supported!\n");
+ ret = -ENOSYS;
+ break;
+ }
+ } else {
+ PRINTF("invalid FPGA descriptor!\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/**
* get the descriptor corresponding to desc_id
* return NULL if error
*/
+#define NB_TARGET_DESC 2
+
Xilinx_desc * xilinx_get_descriptor( unsigned char desc_id )
{
if( desc_id < NB_TARGET_DESC ){
@@ -258,7 +421,7 @@
return NULL;
}
-/**
+/**
* get the descriptor infos
*/
int xilinx_get_descriptor_info( int desc_id, char* buffer )
@@ -277,6 +440,3 @@
return len;
}
-
-
-
Modified: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.h
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.h 2009-03-04 09:51:13 UTC (rev 1111)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.h 2009-03-04 18:34:02 UTC (rev 1112)
@@ -1,9 +1,9 @@
/*
- * (c) Copyright 2006 Armadeus project
- * Nicolas Colombain <nic...@ar...>
- * Xilinx FPGA support
+ * Xilinx FPGAs download support
+ * Copyright (C) 2006-2009 Nicolas Colombain <nic...@ar...>
+ * Armadeus Project / Armadeus systems
*
- * Based on the implementation(uBoot) of:
+ * Based on the implementation (U-Boot) of:
* Rich Ireland, Enterasys Networks, rir...@en....
* Keith Outwater, kei...@mv...
*
@@ -31,8 +31,8 @@
#include <linux/types.h>
-//#define FPGA_DEBUG
-#undef FPGA_DEBUG
+#define FPGA_DEBUG
+//#undef FPGA_DEBUG
#ifdef FPGA_DEBUG
#define PRINTF(fmt,args...) printk (fmt ,##args)
@@ -56,6 +56,7 @@
typedef enum { /* typedef Xilinx_iface */
min_xilinx_iface_type, /* low range check value */
slave_serial, /* serial data and external clock */
+ slave_parallel, /* parallel data and external clock */
max_xilinx_iface_type /* insert all new types before this */
} Xilinx_iface; /* end, typedef Xilinx_iface */
@@ -81,6 +82,12 @@
typedef int (*Xilinx_wr_fn)( int assert_write );
typedef int (*Xilinx_pre_fn)(void);
+typedef int (*Xilinx_cs_fn)( int assert_cs);
+typedef int (*Xilinx_wdata_fn)( unsigned char data );
+typedef int (*Xilinx_busy_fn)(void);
+typedef int (*Xilinx_abort_fn)(void);
+typedef int (*Xilinx_post_fn)(void);
+
/** struct of target specific low level functions */
typedef struct {
Xilinx_pre_fn pre;
@@ -91,6 +98,22 @@
Xilinx_wr_fn wr;
} Xilinx_Spartan_Slave_Serial_fns;
+/* Slave Parallel Implementation function table */
+typedef struct {
+ Xilinx_pre_fn pre;
+ Xilinx_pgm_fn pgm;
+ Xilinx_clk_fn clk;
+ Xilinx_init_fn init;
+ Xilinx_done_fn done;
+ Xilinx_wr_fn wr;
+ Xilinx_cs_fn cs;
+ Xilinx_wdata_fn wdata;
+ Xilinx_busy_fn busy;
+ Xilinx_abort_fn abort;
+ Xilinx_post_fn post;
+} Xilinx_Spartan3_Slave_Parallel_fns;
+
+
/**
* program the FPGA.
* return 0 if success, >0 while programming, <0 if error detected
@@ -98,11 +121,14 @@
size_t xilinx_load( Xilinx_desc *desc, const char *buf, size_t bsize );
/**
- * initialize the FPGA programming interface.
+ * initialize the FPGA programming interface.
* return 0 if success, <0 if error detected
*/
int xilinx_init_load( Xilinx_desc *desc );
+/* terminate FGPA loading */
+int xilinx_finish_load( Xilinx_desc *desc );
+
/**
* get the descriptor infos, return the number of char placed in the buffer
*/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|