diff options
author | Sebastian Kuzminsky <seb@highlab.com> | 2008-01-18 17:50:51 +0000 |
---|---|---|
committer | Sebastian Kuzminsky <seb@highlab.com> | 2008-01-18 17:50:51 +0000 |
commit | d040b87071b814944b560fbfb4509a578413d3c0 (patch) | |
tree | 8e15e2df04139b708e0a5799af53ccaeb8e80689 | |
parent | b47fec3eeca48dd9ea1fd507994091b52c7d664c (diff) | |
download | linuxcnc-d040b87071b814944b560fbfb4509a578413d3c0.tar.gz linuxcnc-d040b87071b814944b560fbfb4509a578413d3c0.zip |
Version 0.1 of m7i43_hm2, a driver for the Mesa 7i43 with HostMot2 firmware.
43 files changed, 10710 insertions, 344 deletions
diff --git a/src/hal/drivers/Submakefile b/src/hal/drivers/Submakefile index 482b0fda8..8f193b0a6 100644 --- a/src/hal/drivers/Submakefile +++ b/src/hal/drivers/Submakefile @@ -15,7 +15,7 @@ hal/drivers/m5i20_HM5-4E.h: hal/drivers/m5i20/bit/hostmot5_4.bit ../bin/m5i20cfg ../bin/m5i20cfg $< > $@ -hal/drivers/mesa7i43-firmware/mesa7i43-firmware-eppio8-4.h: hal/drivers/mesa7i43-firmware/eppio8-4.bit hal/drivers/mesa7i43-firmware/to-header.py +hal/drivers/mesa7i43-firmware/mesa7i43-firmware-eppio8-4.h: hal/drivers/mesa7i43-firmware/gpio/eppio8-4.bit hal/drivers/mesa7i43-firmware/to-header.py python hal/drivers/mesa7i43-firmware/to-header.py \ -d \ -c "This is a component of mesa7i43-gpio, a GPIO driver for EMC2" \ @@ -24,7 +24,7 @@ hal/drivers/mesa7i43-firmware/mesa7i43-firmware-eppio8-4.h: hal/drivers/mesa7i43 -c "<http://www.mesanet.com>" \ $< > $@ -hal/drivers/mesa7i43-firmware/mesa7i43-firmware-eppio8-2.h: hal/drivers/mesa7i43-firmware/eppio8-2.bit hal/drivers/mesa7i43-firmware/to-header.py +hal/drivers/mesa7i43-firmware/mesa7i43-firmware-eppio8-2.h: hal/drivers/mesa7i43-firmware/gpio/eppio8-2.bit hal/drivers/mesa7i43-firmware/to-header.py python hal/drivers/mesa7i43-firmware/to-header.py \ -d \ -c "This is a component of mesa7i43-gpio, a GPIO driver for EMC2" \ @@ -33,6 +33,51 @@ hal/drivers/mesa7i43-firmware/mesa7i43-firmware-eppio8-2.h: hal/drivers/mesa7i43 -c "<http://www.mesanet.com>" \ $< > $@ +hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-svst44-4.h: hal/drivers/mesa7i43-firmware/hostmot2/svst44_4.bit hal/drivers/mesa7i43-firmware/to-header.py + python hal/drivers/mesa7i43-firmware/to-header.py \ + -d \ + -c "This is a component of m7i43-hm2, a Servo/Stepper/GPIO driver for EMC2" \ + -c "" \ + -c "Copyright (C) 2007-2008, Peter C. Wallace, Mesa Electronics" \ + -c "<http://www.mesanet.com>" \ + $< > $@ + +hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-svst44-2.h: hal/drivers/mesa7i43-firmware/hostmot2/svst44_2.bit hal/drivers/mesa7i43-firmware/to-header.py + python hal/drivers/mesa7i43-firmware/to-header.py \ + -d \ + -c "This is a component of m7i43-hm2, a Servo/Stepper/GPIO driver for EMC2" \ + -c "" \ + -c "Copyright (C) 2007-2008, Peter C. Wallace, Mesa Electronics" \ + -c "<http://www.mesanet.com>" \ + $< > $@ + +hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-sv8-4.h: hal/drivers/mesa7i43-firmware/hostmot2/sv8_4.bit hal/drivers/mesa7i43-firmware/to-header.py + python hal/drivers/mesa7i43-firmware/to-header.py \ + -d \ + -c "This is a component of m7i43-hm2, a Servo/Stepper/GPIO driver for EMC2" \ + -c "" \ + -c "Copyright (C) 2007-2008, Peter C. Wallace, Mesa Electronics" \ + -c "<http://www.mesanet.com>" \ + $< > $@ + +hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-sv8-2.h: hal/drivers/mesa7i43-firmware/hostmot2/sv8_2.bit hal/drivers/mesa7i43-firmware/to-header.py + python hal/drivers/mesa7i43-firmware/to-header.py \ + -d \ + -c "This is a component of m7i43-hm2, a Servo/Stepper/GPIO driver for EMC2" \ + -c "" \ + -c "Copyright (C) 2007-2008, Peter C. Wallace, Mesa Electronics" \ + -c "<http://www.mesanet.com>" \ + $< > $@ + +hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-svst46-4.h: hal/drivers/mesa7i43-firmware/hostmot2/svst46_4.bit hal/drivers/mesa7i43-firmware/to-header.py + python hal/drivers/mesa7i43-firmware/to-header.py \ + -d \ + -c "This is a component of m7i43-hm2, a Servo/Stepper/GPIO driver for EMC2" \ + -c "" \ + -c "Copyright (C) 2007-2008, Peter C. Wallace, Mesa Electronics" \ + -c "<http://www.mesanet.com>" \ + $< > $@ + clean: pluto_clean pluto_clean: @@ -57,5 +102,15 @@ pluto_clean: # The kernel's build system won't know how to rebuild generated files # so modules must depend on them explicitly ifneq ($(BUILD_SYS),sim) -modules: hal/drivers/pluto_servo_rbf.h hal/drivers/m5i20_HM5-4E.h hal/drivers/pluto_step_rbf.h hal/drivers/mesa7i43-firmware/mesa7i43-firmware-eppio8-4.h hal/drivers/mesa7i43-firmware/mesa7i43-firmware-eppio8-2.h +modules: \ + hal/drivers/pluto_servo_rbf.h \ + hal/drivers/m5i20_HM5-4E.h \ + hal/drivers/pluto_step_rbf.h \ + hal/drivers/mesa7i43-firmware/mesa7i43-firmware-eppio8-4.h \ + hal/drivers/mesa7i43-firmware/mesa7i43-firmware-eppio8-2.h \ + hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-svst44-4.h \ + hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-svst44-2.h \ + hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-sv8-4.h \ + hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-sv8-2.h \ + hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-svst46-4.h endif diff --git a/src/hal/drivers/m7i43_hm2.comp b/src/hal/drivers/m7i43_hm2.comp new file mode 100644 index 000000000..3d1a2a587 --- /dev/null +++ b/src/hal/drivers/m7i43_hm2.comp @@ -0,0 +1,1990 @@ + +// +// Copyright (C) 2007-2008 Sebastian Kuzminsky +// +// 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. +// +// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +// + + +component m7i43_hm2 """RTAI driver for the Mesa Electronics 7i43 EPP Anything IO board with HostMot2 firmware."""; + + +description """ +m7i43_hm2 is an RTAI device driver that interfaces the Mesa 7i43 board with +the HostMot2 firmware to the EMC2 HAL. Both the 200K and the 400K FPGAs +are supported. + +The driver sends the HostMot2 firmware to the board at module load time. +The board should be ready to accept new firmware before loading the +driver, ie both the INIT and DONE lights should be on. + + +.SS Jumper settings + +The board must be configured to get its firmware from the EPP port. To do +this, jumpers W4 and W5 must both be down, ie toward the USB connector. + +The board must be configured to power on whether or not the USB interface +is active. This is done by setting jumper W7 up, ie away from the edge +of the board. + + +.SS Firmware + +The HostMot2 firmware provides encoders, PWM generators, step generators, +and general purpose I/O ports. These things are called "functions". +The firmware is configured, at compile time, to provide zero or more +instances of each of these four functions. + + +.SS Board I/O Pins + +The 7i43 board has 48 I/O pins, 24 on the P3 connector and 24 on the P4 +connector. Each pin can be configured, at driver load time, to serve one +of two purposes: either as a particular I/O pin of a particular function +instance (encoder, pwmgen, or stepgen), or as a general purpose digital +I/O pin. By default all firmware functions are enabled, and all the +board's pins are used by the function instances. + +The user can disable function instances at driver load time, by specifying +the module parameters num_encoders, num_pwmgens, and num_stepgens. +Any pins which belong to function instances that have been disabled, +automatically become digital I/O pins. + + +.SS encoder + +Very basic support + + +.SS pwmgen + +Very basic support + + +.SS stepgen + +** Not implemented yet! ** + + +.SS General Purpose I/O + +Pins which are not used by one of the functions above +are exported to HAL as GPIO pins. GPIO pins have names like +"m7i43_hm2.<BoardNum>.gpio.<PinNum>", where PinNum matches the I/O pin +numbers in the Mesa 7i43 manual. + +Each GPIO has the following pins: + + in & in_not: Like the Canonical Digital Input. + + out: Like the Canonical Digital Output. + +Each GPIO has the following params: + + is_output: If set to 1, the GPIO is an output, and the values of the + "in" and "in_not" HAL pins are undefined. If set to 0, the GPIO + is an input, and writes to the "out" HAL pin have no effect. + + invert_output: if set to 1, the value that will appear on the + board's I/O pin will be the inverse of the value written to HAL's + "out" pin. + +"""; + +pin in bit ignore "ignore this pin, comp needs it"; + + +option singleton; +option extra_setup; +option extra_cleanup; + +function gpio_update nofp "Read & write GPIO pins."; +function encoder_update_counters nofp "Read encoder counts."; +function encoder_capture_position fp "Compute encoder position."; +function pwmgen_update fp "Write pwmgen values."; + + +modparam int ioaddr = 0x378 +"""The base address of the parallel port."""; + +modparam int ioaddr_hi = 0 +"""The secondary address of the parallel port, used to set EPP mode. +0 means to use ioaddr + 0x400."""; + +modparam int epp_wide = 1 +"""Set to zero to disable the "wide EPP mode". "Wide" mode allows a 16- +and 32-bit EPP transfers, which can reduce the time spent in the read +and write functions. However, this may not work on all EPP parallel +ports."""; + +modparam int num_encoders = -1 +"""Defaults to -1, which means "use all the encoder instances the +firmware has". If num_encoders is smaller than the number of encoder +instances present in the firmware, only the first num_encoders instances +are enabled; all later encoder instances are disabled and their I/O pins +become digital I/O pins."""; + +modparam int num_pwmgens = -1 +"""Defaults to -1, which means "use all the pwmgen instances the +firmware has". If num_pwmgens is smaller than the number of pwmgen +instances present in the firmware, only the first num_pwmgens instances +are enabled; all later pwmgen instances are disabled and their I/O pins +become digital I/O pins."""; + +modparam int num_stepgens = -1 +"""Defaults to -1, which means "use all the stepgen instances the +firmware has". If num_stepgens is smaller than the number of stepgen +instances present in the firmware, only the first num_stepgens instances +are enabled; all later stepgen instances are disabled and their I/O pins +become digital I/O pins."""; + + +modparam int debug_epp = 0 +"""Developer/debug use only! Enable debug logging of most EPP +transfers."""; + +modparam int debug_idrom = 0 +"""Developer/debug use only! Enable debug logging of the HostMot2 +IDROM header."""; + +modparam int debug_module_descriptors = 0 +"""Developer/debug use only! Enable debug logging of the HostMot2 +Module Descriptors."""; + +modparam int debug_pin_descriptors = 0 +"""Developer/debug use only! Enable debug logging of the HostMot2 +Pin Descriptors."""; + +modparam int debug_functions = 0 +"""Developer/debug use only! Enable debug logging of the HostMot2 +Functions used."""; + + +license "GPL"; + +;; + + +#include <asm/io.h> + +#include "rtapi_math.h" + +#include "hal/drivers/m7i43_hm2.h" +#include "hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-svst44-2.h" +#include "hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-svst44-4.h" +// #include "hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-sv8-2.h" +// #include "hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-sv8-4.h" +// #include "hal/drivers/mesa7i43-firmware/m7i43-firmware-hm2-svst46-4.h" + + + + +// +// the 7i43 board is tracked by this +// + +m7i43_t board; + + + + +// +// EPP I/O code +// + +static inline void m7i43_epp_addr8(__u8 addr) { + outb(addr, ioaddr + M7I43_EPP_ADDRESS_OFFSET); + DEBUG(debug_epp, "selected address 0x%02X\n", addr); +} + +static inline void m7i43_epp_addr16(__u16 addr) { + outb((addr & 0x00FF), ioaddr + M7I43_EPP_ADDRESS_OFFSET); + outb((addr >> 8), ioaddr + M7I43_EPP_ADDRESS_OFFSET); + DEBUG(debug_epp, "selected address 0x%04X\n", addr); +} + +static inline void m7i43_epp_write(int w) { + outb(w, ioaddr + M7I43_EPP_DATA_OFFSET); + DEBUG(debug_epp, "wrote data 0x%02X\n", w); +} + +static inline int m7i43_epp_read(void) { + int val; + val = inb(ioaddr + M7I43_EPP_DATA_OFFSET); + DEBUG(debug_epp, "read data 0x%02X\n", val); + return val; +} + +static inline __u32 m7i43_epp_read32(void) { + uint32_t data; + + if (epp_wide) { + data = inl(ioaddr + M7I43_EPP_DATA_OFFSET); + DEBUG(debug_epp, "read data 0x%08X\n", data); + } else { + uint8_t a, b, c, d; + a = m7i43_epp_read(); + b = m7i43_epp_read(); + c = m7i43_epp_read(); + d = m7i43_epp_read(); + data = a + (b<<8) + (c<<16) + (d<<24); + } + + return data; +} + +static inline void m7i43_epp_write32(uint32_t w) { + if (epp_wide) { + outl(w, ioaddr + M7I43_EPP_DATA_OFFSET); + DEBUG(debug_epp, "wrote data 0x%08X\n", w); + } else { + m7i43_epp_write((w) & 0xFF); + m7i43_epp_write((w >> 8) & 0xFF); + m7i43_epp_write((w >> 16) & 0xFF); + m7i43_epp_write((w >> 24) & 0xFF); + } +} + +static inline uint8_t m7i43_epp_read_status(void) { + uint8_t val; + val = inb(ioaddr + M7I43_EPP_STATUS_OFFSET); + DEBUG(debug_epp, "read status 0x%02X\n", val); + return val; +} + +static inline void m7i43_epp_write_status(uint8_t status_byte) { + outb(status_byte, ioaddr + M7I43_EPP_DATA_OFFSET); + DEBUG(debug_epp, "wrote status 0x%02X\n", status_byte); +} + +static inline void m7i43_epp_write_control(uint8_t control_byte) { + outb(control_byte, ioaddr + M7I43_EPP_CONTROL_OFFSET); + DEBUG(debug_epp, "wrote control 0x%02X\n", control_byte); +} + +static inline int m7i43_epp_check_for_timeout(void) { + uint8_t byte; + + byte = m7i43_epp_read_status(); + if (byte & 0x01) { + PRINT(RTAPI_MSG_ERR, "EPP Status register reports EPP Timeout!\n"); + } + return (byte & 0x01); +} + +static int m7i43_epp_clear_timeout(void) { + uint8_t status; + + if (!m7i43_epp_check_for_timeout()) { + return 1; + } + + /* To clear timeout some chips require double read */ + (void)m7i43_epp_read_status(); + + // read in the actual status register + status = m7i43_epp_read_status(); + + m7i43_epp_write_status(status | 0x01); // Some reset by writing 1 + m7i43_epp_write_status(status & 0xFE); // Others by writing 0 + + return !m7i43_epp_check_for_timeout(); +} + + + + +// +// misc generic helper functions +// + +static void m7i43_nanosleep(unsigned long int nanoseconds) { + long int max_ns_delay; + + max_ns_delay = rtapi_delay_max(); + + while (nanoseconds > max_ns_delay) { + rtapi_delay(max_ns_delay); + nanoseconds -= max_ns_delay; + } + + rtapi_delay(nanoseconds); +} + + + + +// +// helper functions for dealing with the 7i43 board +// + + +// this function resets the FPGA *only* if it's currently configured with the HostMot2 firmware +static void m7i43_hm2_reset(void) { + m7i43_epp_addr16(0x7F7F); + m7i43_epp_write(0x5A); +} + + +static void m7i43_hm2_print_idrom(int level, m7i43_t *board) { + PRINT(level, "IDRom:\n"); + + if (board->idrom.idrom_type == 2) { + PRINT(level, " IDRom Type: 0x%08X\n", board->idrom.idrom_type); + } else { + PRINT(level, " IDRom Type: 0x%08X ***** Expected 2! Continuing anyway! *****\n", board->idrom.idrom_type); + } + + if (board->idrom.offset_to_modules == 0x40) { + PRINT(level, " Offset to Modules: 0x%08X\n", board->idrom.offset_to_modules); + } else { + PRINT(level, " Offset to Modules: 0x%08X ***** Expected 0x40! Continuing anyway *****\n", board->idrom.offset_to_modules); + } + + if (board->idrom.offset_to_pin_desc == 0x200) { + PRINT(level, " Offset to Pin Description: 0x%08X\n", board->idrom.offset_to_pin_desc); + } else { + PRINT(level, " Offset to Pin Description: 0x%08X ***** Expected 0x200! Continuing anyway! *****\n", board->idrom.offset_to_pin_desc); + } + + PRINT(level, " Board Name: %s\n", board->idrom.board_name); + + if (board->idrom.fpga_size == board->cpld.fpga_size) { + PRINT(level, " FPGA Size: %u\n", board->idrom.fpga_size); + } else { + PRINT(level, " FPGA Size: %u ***** CPLD reported FPGA Size %d! Continuing anyway! *****\n", board->idrom.fpga_size, board->cpld.fpga_size); + } + + PRINT(level, " FPGA Pins: %u\n", board->idrom.fpga_pins); + + PRINT(level, " IO Ports: %u\n", board->idrom.io_ports); + + PRINT(level, " IO Width: %u\n", board->idrom.io_width); + + if (board->idrom.port_width == 24) { + PRINT(level, " Port Width: %u\n", board->idrom.port_width); + } else { + PRINT(level, " Port Width: %u ***** Expected 24! Continuing anyway! *****\n", board->idrom.port_width); + } + + PRINT( + level, + " Clock Low: %d Hz (%d KHz, %d MHz)\n", + board->idrom.clock_low, + (board->idrom.clock_low / 1000), + (board->idrom.clock_low / (1000 * 1000)) + ); + + PRINT( + level, + " Clock High: %d Hz (%d KHz, %d MHz)\n", + board->idrom.clock_high, + (board->idrom.clock_high / 1000), + (board->idrom.clock_high / (1000 * 1000)) + ); + + PRINT(level, " Instance Stride 0: 0x%08X\n", board->idrom.instance_stride_0); + PRINT(level, " Instance Stride 1: 0x%08X\n", board->idrom.instance_stride_1); + + PRINT(level, " Register Stride 0: 0x%08X\n", board->idrom.register_stride_0); + PRINT(level, " Register Stride 1: 0x%08X\n", board->idrom.register_stride_1); +} + + +// +// read the idrom +// use address autoincrement, and just read everything in the correct order +// + +static int m7i43_hm2_read_idrom(m7i43_t *board) { + int i; + int ret_val = 0; + int show_idrom = 0; + + m7i43_epp_addr16(board->idrom_offset + M7I43_HM2_ADDR_AUTOINCREMENT); + + board->idrom.idrom_type = m7i43_epp_read32(); + if (board->idrom.idrom_type != 2) { + PRINT(RTAPI_MSG_WARN, "invalid IDROM type %d, expected 2, aborting load\n", board->idrom.idrom_type); + return -EINVAL; + } + + board->idrom.offset_to_modules = m7i43_epp_read32(); + board->idrom.offset_to_pin_desc = m7i43_epp_read32(); + + for (i = 0; i < 8; i ++) { + board->idrom.board_name[i] = m7i43_epp_read(); + } + board->idrom.board_name[8] = '\0'; + + board->idrom.fpga_size = m7i43_epp_read32(); + if (board->idrom.fpga_size != board->cpld.fpga_size) { + show_idrom = 1; + PRINT( + RTAPI_MSG_WARN, + "IDRom FPGA Size %d disagrees with CPLD FPGA Size %d, oh well\n", + board->idrom.fpga_size, + board->cpld.fpga_size + ); + } + + board->idrom.fpga_pins = m7i43_epp_read32(); + + board->idrom.io_ports = m7i43_epp_read32(); + board->idrom.io_width = m7i43_epp_read32(); + board->idrom.port_width = m7i43_epp_read32(); + if (board->idrom.port_width != 24) { + PRINT(RTAPI_MSG_WARN, "invalid IDROM PortWidth %d, expected 24, aborting load\n", board->idrom.port_width); + ret_val = -EINVAL; + show_idrom = 1; + } + + board->idrom.clock_low = m7i43_epp_read32(); + board->idrom.clock_high = m7i43_epp_read32(); + + board->idrom.instance_stride_0 = m7i43_epp_read32(); + board->idrom.instance_stride_1 = m7i43_epp_read32(); + + board->idrom.register_stride_0 = m7i43_epp_read32(); + board->idrom.register_stride_1 = m7i43_epp_read32(); + + if (show_idrom) { + m7i43_hm2_print_idrom(RTAPI_MSG_WARN, board); + } else if (debug_idrom) { + m7i43_hm2_print_idrom(RTAPI_MSG_INFO, board); + } + + return ret_val; +} + + + + +// +// helper functions for dealing with the Module Descriptions +// + +static const char *hm2_get_general_function_name(int gtag) { + switch (gtag) { + case HM2_GTAG_WATCHDOG: return "Watchdog"; + case HM2_GTAG_IOPORT: return "IOPort"; + case HM2_GTAG_ENCODER: return "Encoder"; + case HM2_GTAG_STEPGEN: return "StepGen"; + case HM2_GTAG_PWMGEN: return "PWMGen"; + case HM2_GTAG_TRANSLATIONRAM: return "TranslationRAM"; + default: { + static char unknown[100]; + rtapi_snprintf(unknown, 100, "(unknown-gtag-%d)", gtag); + return unknown; + } + } +} + + + + +// +// read the modules +// + +static int hm2_md_is_consistent(hm2_module_descriptor_t *m, __u8 version, __u8 num_registers, __u32 instance_stride, __u32 multiple_registers) { + if ( + (m->num_registers == num_registers) + && (m->version == version) + && (m->instance_stride == instance_stride) + && (m->multiple_registers == multiple_registers) + ) { + return 1; + } + + PRINT( + RTAPI_MSG_ERR, + "inconsistent Module Descriptor for %s, not loading driver\n", + hm2_get_general_function_name(m->gtag) + ); + + PRINT( + RTAPI_MSG_ERR, + " Version = %d, expected %d\n", + m->version, + version + ); + + PRINT( + RTAPI_MSG_ERR, + " NumRegisters = %d, expected %d\n", + m->num_registers, + num_registers + ); + + PRINT( + RTAPI_MSG_ERR, + " InstanceStride = 0x%08X, expected 0x%08X\n", + m->instance_stride, + instance_stride + ); + + PRINT( + RTAPI_MSG_ERR, + " MultipleRegisters = 0x%08X, expected 0x%08X\n", + m->multiple_registers, + multiple_registers + ); + + return 0; +} + + +// reads the Module Descriptors +// doesnt do any validation or parsing or anything, that's in hm2_parse_modules(), which comes next +static void m7i43_hm2_read_module_descriptors(m7i43_t *board) { + int addr = board->idrom_offset + board->idrom.offset_to_modules; + + m7i43_epp_addr16(addr + M7I43_HM2_ADDR_AUTOINCREMENT); + + // we keep track of addr just for debugging, the actual board is using address auto-increment + for ( + board->num_mds = 0; + board->num_mds < M7I43_HM2_MAX_MODULE_DESCRIPTORS; + board->num_mds ++, addr += 12 + ) { + __u32 d[3]; + hm2_module_descriptor_t *m = &board->md[board->num_mds]; + + + d[0] = m7i43_epp_read32(); + d[1] = m7i43_epp_read32(); + d[2] = m7i43_epp_read32(); + + m->gtag = d[0] & 0x000000FF; + if (m->gtag == 0) { + return; + } + + m->version = (d[0] >> 8) & 0x000000FF; + m->clock_tag = (d[0] >> 16) & 0x000000FF; + m->instances = (d[0] >> 24) & 0x000000FF; + + m->base_address = (d[1] >> 00) & 0x0000FFFF; + m->num_registers = (d[1] >> 16) & 0x000000FF; + + m->register_stride = (d[1] >> 24) & 0x0000000F; + if (m->register_stride == 0) { + m->register_stride = board->idrom.register_stride_0; + } else { + m->register_stride = board->idrom.register_stride_1; + } + + m->instance_stride = (d[1] >> 28) & 0x0000000F; + if (m->instance_stride == 0) { + m->instance_stride = board->idrom.instance_stride_0; + } else { + m->instance_stride = board->idrom.instance_stride_1; + } + + m->multiple_registers = d[2]; + + if (debug_module_descriptors) { + PRINT(RTAPI_MSG_DBG, "Module Descriptor %d at 0x%04X:\n", board->num_mds, addr); + PRINT(RTAPI_MSG_DBG, " General Function Tag: %d (%s)\n", m->gtag, hm2_get_general_function_name(m->gtag)); + PRINT(RTAPI_MSG_DBG, " Version: %d\n", m->version); + PRINT(RTAPI_MSG_DBG, " Clock Tag: %d\n", m->clock_tag); + PRINT(RTAPI_MSG_DBG, " Instances: %d\n", m->instances); + PRINT(RTAPI_MSG_DBG, " Base Address: 0x%04X\n", m->base_address); + PRINT(RTAPI_MSG_DBG, " -- Num Registers: %d\n", m->num_registers); + PRINT(RTAPI_MSG_DBG, " Register Stride: 0x%08X\n", m->register_stride); + PRINT(RTAPI_MSG_DBG, " -- Instance Stride: 0x%08X\n", m->instance_stride); + PRINT(RTAPI_MSG_DBG, " -- Multiple Registers: 0x%08X\n", m->multiple_registers); + } + } +} + + + + +// +// Here comes the code to "parse" the Module Descriptors, turn them into +// internal-to-the-driver representations, and export those internal +// representations to the HAL. +// +// There's a general function that walks the MD list and tries to parse +// each MD in turn, and there's a special function to parse each GTag +// (aka Function) +// +// The per-Function parsers return the number of instances accepted, which +// may be less than the number of instances available, or even 0, if the +// user has disabled some instances using modparams. The per-Function +// parsers return -1 on error, which causes the module load to fail. +// + +static int hm2_md_parse_encoder(m7i43_t *board, hm2_module_descriptor_t *m) { + if (!hm2_md_is_consistent(m, 2, 4, 4, 0x0003)) { + PRINT(RTAPI_MSG_ERR, "inconsistent Module Descriptor!\n"); + return -1; + } + + if (board->encoder.num_instances != 0) { + PRINT( + RTAPI_MSG_ERR, + "Module Descriptor contains duplicate %s (inconsistent firmware), not loading driver\n", + hm2_get_general_function_name(m->gtag) + ); + return -1; + } + + if (num_encoders == -1) { + board->encoder.num_instances = m->instances; + } else if (num_encoders > m->instances) { + PRINT( + RTAPI_MSG_ERR, + "num_encoders=%d, but only %d are available, not loading driver\n", + num_encoders, + m->instances + ); + return -1; + } else { + board->encoder.num_instances = num_encoders; + } + + board->encoder.instance = (hm2_encoder_instance_t *)hal_malloc(board->encoder.num_instances * sizeof(hm2_encoder_instance_t)); + if (board->encoder.instance == NULL) { + PRINT(RTAPI_MSG_ERR, "out of memory!\n"); + return -1; + } + + if (m->clock_tag == 1) { + board->encoder.clock_frequency = board->idrom.clock_low; + } else { + board->encoder.clock_frequency = board->idrom.clock_high; + } + + board->encoder.version = m->version; + + board->encoder.counter_addr = m->base_address + (0 * m->register_stride); + board->encoder.latch_control_addr = m->base_address + (1 * m->register_stride); + board->encoder.timestamp_div_addr = m->base_address + (2 * m->register_stride); + board->encoder.timestamp_count_addr = m->base_address + (3 * m->register_stride); + + // export the encoders to HAL + { + int i; + int r; + char name[HAL_NAME_LEN + 2]; + + for (i = 0; i < board->encoder.num_instances; i ++) { + // pins + rtapi_snprintf(name, HAL_NAME_LEN, "m7i43_hm2.%d.encoder.%02d.count", 0, i); + r = hal_pin_s32_new(name, HAL_OUT, &(board->encoder.instance[i].hal.pin.count), comp_id); + if (r != HAL_SUCCESS) { + PRINT(RTAPI_MSG_ERR, "error adding pin '%s', aborting\n", name); + return -1; + } + + rtapi_snprintf(name, HAL_NAME_LEN, "m7i43_hm2.%d.encoder.%02d.position", 0, i); + r = hal_pin_float_new(name, HAL_OUT, &(board->encoder.instance[i].hal.pin.position), comp_id); + if (r != HAL_SUCCESS) { + PRINT(RTAPI_MSG_ERR, "error adding pin '%s', aborting\n", name); + return -1; + } + + // parameters + rtapi_snprintf(name, HAL_NAME_LEN, "m7i43_hm2.%d.encoder.%02d.scale", 0, i); + r = hal_param_float_new(name, HAL_RW, &(board->encoder.instance[i].hal.param.scale), comp_id); + if (r != HAL_SUCCESS) { + PRINT(RTAPI_MSG_ERR, "error adding param '%s', aborting\n", name); + return -1; + } + + // init + board->encoder.instance[i].hw.count = 0; + board->encoder.instance[i].hw.timestamp = 0; + board->encoder.instance[i].hw.prev_count = 0; + board->encoder.instance[i].hw.prev_timestamp = 0; + *(board->encoder.instance[i].hal.pin.count) = 0; + *(board->encoder.instance[i].hal.pin.position) = 0.0; + board->encoder.instance[i].hal.param.scale = 1.0; + } + } + + return board->encoder.num_instances; +} + + +static int hm2_md_parse_pwmgen(m7i43_t *board, hm2_module_descriptor_t *m) { + if (!hm2_md_is_consistent(m, 0, 5, 4, 0x0003)) { + PRINT(RTAPI_MSG_ERR, "inconsistent Module Descriptor!\n"); + return -1; + } + + if (board->pwmgen.num_instances != 0) { + PRINT( + RTAPI_MSG_ERR, + "Module Descriptor contains duplicate %s (inconsistent firmware), not loading driver\n", + hm2_get_general_function_name(m->gtag) + ); + return -1; + } + + if (num_pwmgens == -1) { + board->pwmgen.num_instances = m->instances; + } else if (num_pwmgens > m->instances) { + PRINT( + RTAPI_MSG_ERR, + "num_pwmgens=%d, but only %d are available, not loading driver\n", + num_pwmgens, + m->instances + ); + return -1; + } else { + board->pwmgen.num_instances = num_pwmgens; + } + + board->pwmgen.instance = (hm2_pwmgen_instance_t *)hal_malloc(board->pwmgen.num_instances * sizeof(hm2_pwmgen_instance_t)); + if (board->pwmgen.instance == NULL) { + PRINT(RTAPI_MSG_ERR, "out of memory!\n"); + return -1; + } + + if (m->clock_tag == 1) { + board->pwmgen.clock_frequency = board->idrom.clock_low; + } else { + board->pwmgen.clock_frequency = board->idrom.clock_high; + } + + board->pwmgen.version = m->version; + + board->pwmgen.pwm_value_addr = m->base_address + (0 * m->register_stride); + board->pwmgen.pwm_mode_addr = m->base_address + (1 * m->register_stride); + board->pwmgen.pwmgen_master_rate_dds_addr = m->base_address + (2 * m->register_stride); + board->pwmgen.pdmgen_master_rate_dds_addr = m->base_address + (3 * m->register_stride); + board->pwmgen.enable_addr = m->base_address + (4 * m->register_stride); + + // export to HAL + { + int i; + int r; + char name[HAL_NAME_LEN + 2]; + + for (i = 0; i < board->pwmgen.num_instances; i ++) { + // pins + rtapi_snprintf(name, HAL_NAME_LEN, "m7i43_hm2.%d.pwmgen.%02d.value", 0, i); + r = hal_pin_float_new(name, HAL_IN, &(board->pwmgen.instance[i].hal.pin.value), comp_id); + if (r != HAL_SUCCESS) { + PRINT(RTAPI_MSG_ERR, "error adding pin '%s', aborting\n", name); + return -1; + } + + rtapi_snprintf(name, HAL_NAME_LEN, "m7i43_hm2.%d.pwmgen.%02d.enable", 0, i); + r = hal_pin_bit_new(name, HAL_IN, &(board->pwmgen.instance[i].hal.pin.enable), comp_id); + if (r != HAL_SUCCESS) { + PRINT(RTAPI_MSG_ERR, "error adding pin '%s', aborting\n", name); + return -1; + } + + // parameters + rtapi_snprintf(name, HAL_NAME_LEN, "m7i43_hm2.%d.pwmgen.%02d.scale", 0, i); + r = hal_param_float_new(name, HAL_RW, &(board->pwmgen.instance[i].hal.param.scale), comp_id); + if (r != HAL_SUCCESS) { + PRINT(RTAPI_MSG_ERR, "error adding param '%s', aborting\n", name); + return -1; + } + + // init + *(board->pwmgen.instance[i].hal.pin.enable) = 0; + *(board->pwmgen.instance[i].hal.pin.value) = 0.0; + board->pwmgen.instance[i].hal.param.scale = 1.0; + + board->pwmgen.instance[i].hw.pwm_mode = 0x3; // FIXME: let the user choose some of these bits? + } + } + + + // + // write the PWM Mode registers + // + + { + int i; + + m7i43_epp_addr16(board->pwmgen.pwm_mode_addr + M7I43_HM2_ADDR_AUTOINCREMENT); + for (i = 0; i < board->pwmgen.num_instances; i ++) { + m7i43_epp_write32(board->pwmgen.instance[i].hw.pwm_mode); + } + } + + + // + // set the PWM frequency + // FIXME: this is broken and should be exported to HAL + // + // 16 bit PWM gen master rate DDS (PWMCLOCK = CLKHIGH*Rate/65536) + // PWM rate will be PWMCLOCK/(2^PWMBITS) for normal and interleaved PWM + // and PWMCLOCK/(2^(PWMBITS+1)) for symmetrical mode PWM. + // + // ClockHigh = 100 MHz + // 7i30 max PWM rate is 50 KHz + // + // PWMClock = 100 MHz * (val / 65536) + // PWMRate = PWMClock / 2^PWMBits = PWMClock / 2^12 = PWMClock / 4096 + // + // PWMRate = 50 Khz = PWMClock / 4096 + // PWMClock = 205 MHz!? + // + // PWMClock = 100 MHz * 65536 / 65536 = 100 MHz + // PWMRate = 100 MHz / 4096 = 24 KHz + // + // FIXME: maybe use fewer bits? + // + + m7i43_epp_addr16(board->pwmgen.pwmgen_master_rate_dds_addr + M7I43_HM2_ADDR_AUTOINCREMENT); + m7i43_epp_write32(65535); + + return board->pwmgen.num_instances; +} + + +static int hm2_md_parse_ioport(m7i43_t *board, hm2_module_descriptor_t *m) { + if (!hm2_md_is_consistent(m, 0, 5, 4, 0x001F)) { + PRINT(RTAPI_MSG_ERR, "inconsistent Module Descriptor!\n"); + return -1; + } + + if (board->ioport.num_instances != 0) { + PRINT( + RTAPI_MSG_ERR, + "Module Descriptor contains duplicate %s (inconsistent firmware), not loading driver\n", + hm2_get_general_function_name(m->gtag) + ); + return -1; + } + + board->ioport.num_instances = m->instances; + board->ioport.instance = (hm2_ioport_instance_t *)hal_malloc(board->ioport.num_instances * sizeof(hm2_ioport_instance_t)); + if (board->ioport.instance == NULL) { + PRINT(RTAPI_MSG_ERR, "out of memory!\n"); + return -1; + } + + if (m->clock_tag == 1) { + board->ioport.clock_frequency = board->idrom.clock_low; + } else { + board->ioport.clock_frequency = board->idrom.clock_high; + } + + board->ioport.version = m->version; + + board->ioport.data_addr = m->base_address + (0 * m->register_stride); + board->ioport.ddr_addr = m->base_address + (1 * m->register_stride); + board->ioport.alt_source_addr = m->base_address + (2 * m->register_stride); + board->ioport.open_drain_addr = m->base_address + (3 * m->register_stride); + board->ioport.output_invert_addr = m->base_address + (4 * m->register_stride); + + // we can't export this one yet, because some pins may be "allocated" to other modules + + return board->ioport.num_instances; +} + + +static int m7i43_hm2_parse_module_descriptors(m7i43_t *board) { + int i; + + for (i = 0; i < board->num_mds; i ++) { + hm2_module_descriptor_t *m = &board->md[i]; + int md_accepted; + + if (m->gtag == 0) { + return 1; + } + + if ((m->clock_tag != 1) && (m->clock_tag != 2)) { + PRINT( + RTAPI_MSG_ERR, + "Module Descriptor %d (gtag=%d (%s), version=%d) has invalid ClockTag %d, skipping\n", + i, + m->gtag, + hm2_get_general_function_name(m->gtag), + m->version, + m->clock_tag + ); + continue; + } + + md_accepted = 0; // will be set by the switch + + switch (m->gtag) { + + case HM2_GTAG_ENCODER: + md_accepted = hm2_md_parse_encoder(board, m); + break; + + case HM2_GTAG_PWMGEN: + md_accepted = hm2_md_parse_pwmgen(board, m); + break; + + case HM2_GTAG_IOPORT: + md_accepted = hm2_md_parse_ioport(board, m); + break; + + default: + PRINT( + RTAPI_MSG_WARN, + "MD %d: %dx %s v%d: ignored\n", + i, + m->instances, + hm2_get_general_function_name(m->gtag), + m->version + ); + continue; + + } + + if (md_accepted >= 0) { + PRINT( + RTAPI_MSG_INFO, + "MD %d: %dx %s v%d: accepted, using %d\n", + i, + m->instances, + hm2_get_general_function_name(m->gtag), + m->version, + md_accepted + ); + } else { + PRINT(RTAPI_MSG_ERR, "failed to parse Module Descriptor %d\n", i); + return 0; // fail... + } + + } + + return 1; // success! +} + + + + +// +// here come the functions to deal with pins +// + + +static const char* hm2_get_pin_secondary_name(hm2_pin_t *pin) { + static char unknown[100]; + int sec_pin = pin->sec_pin & 0x7F; // turn off the "pin is an output" bit + + switch (pin->sec_tag) { + + case HM2_GTAG_ENCODER: + switch (sec_pin) { + case 1: return "A"; + case 2: return "B"; + case 3: return "Index"; + } + break; + + case HM2_GTAG_PWMGEN: + switch (sec_pin) { + case 1: return "PWM"; + case 2: return "Direction"; + case 3: return "Not-Enable"; + } + break; + + } + + rtapi_snprintf(unknown, sizeof(unknown), "unknown-pin-%d", sec_pin & 0x7F); + return unknown; +} + + +static int m7i43_hm2_read_pin_descriptors(m7i43_t *board) { + int i; + int addr = board->idrom_offset + board->idrom.offset_to_pin_desc; + + m7i43_epp_addr16(addr + M7I43_HM2_ADDR_AUTOINCREMENT); + + i = 0; + + do { + __u32 d; + + d = m7i43_epp_read32(); + + board->pin[i].sec_pin = (d >> 0) & 0x000000FF; + board->pin[i].sec_tag = (d >> 8) & 0x000000FF; + board->pin[i].sec_unit = (d >> 16) & 0x000000FF; + board->pin[i].primary_tag = (d >> 24) & 0x000000FF; + + if (board->pin[i].primary_tag == 0) { + board->num_pins = i; + return 1; + } + + if (board->pin[i].primary_tag != HM2_GTAG_IOPORT) { + PRINT( + RTAPI_MSG_ERR, + "pin %d primary tag is %d (%s), not IOPort!\n", + i, + board->pin[i].primary_tag, + hm2_get_general_function_name(board->pin[i].primary_tag) + ); + return 0; + } + + i++; + addr += 4; // just for debugging, the actual board is using address auto-increment + } while (i < M7I43_HM2_MAX_PIN_DESCRIPTORS); + + return 1; +} + + +static void hm2_print_pin_descriptors(int msg_level, m7i43_t *board) { + int i; + + PRINT(msg_level, "%d HM2 Pin Descriptors:\n", board->num_pins); + + for (i = 0; i < board->num_pins; i ++) { + PRINT(msg_level, " pin %d:\n", i); + PRINT( + msg_level, + " Secondary Pin: 0x%02X (%s, %s)\n", + board->pin[i].sec_pin, + hm2_get_pin_secondary_name(&board->pin[i]), + ((board->pin[i].sec_pin & 0x80) ? "Output" : "Input") + ); + PRINT( + msg_level, + " Secondary Tag: 0x%02X (%s)\n", + board->pin[i].sec_tag, + hm2_get_general_function_name(board->pin[i].sec_tag) + ); + PRINT(msg_level, " Secondary Unit: 0x%02X\n", board->pin[i].sec_unit); + PRINT( + msg_level, + " Primary Tag: 0x%02X (%s)\n", + board->pin[i].primary_tag, + hm2_get_general_function_name(board->pin[i].primary_tag) + ); + } +} + + +static void hm2_set_pin_source(m7i43_t *board, int pin_number, int source) { + int ioport_number; + int bit_number; + + ioport_number = pin_number / 24; + bit_number = pin_number % 24; + + if ((pin_number < 0) || (ioport_number > board->ioport.num_instances)) { + PRINT(RTAPI_MSG_ERR, "invalid pin number %d\n", pin_number); + return; + } + + if (source == HM2_PIN_SOURCE_IS_PRIMARY) { + board->ioport.instance[ioport_number].alt_source &= ~(1 << bit_number); + board->pin[pin_number].gtag = board->pin[pin_number].primary_tag; + } else if (source == HM2_PIN_SOURCE_IS_SECONDARY) { + board->ioport.instance[ioport_number].alt_source |= (1 << bit_number); + board->pin[pin_number].gtag = board->pin[pin_number].sec_tag; + } else { + PRINT(RTAPI_MSG_ERR, "invalid pin source 0x%08X\n", source); + return; + } +} + + +static void hm2_set_pin_direction(m7i43_t *board, int pin_number, int direction) { + int ioport_number; + int bit_number; + + ioport_number = pin_number / 24; + bit_number = pin_number % 24; + + if ((pin_number < 0) || (ioport_number > board->ioport.num_instances)) { + PRINT(RTAPI_MSG_ERR, "invalid pin number %d\n", pin_number); + return; + } + + if (direction == HM2_PIN_DIR_IS_INPUT) { + board->ioport.instance[ioport_number].ddr &= ~(1 << bit_number); + } else if (direction == HM2_PIN_DIR_IS_OUTPUT) { + board->ioport.instance[ioport_number].ddr |= (1 << bit_number); + } else { + PRINT(RTAPI_MSG_ERR, "invalid pin direction 0x%08X\n", direction); + } +} + + +static void hm2_print_pin_usage(int msg_level, m7i43_t *board) { + int i; + + PRINT(msg_level, "%d I/O Pins used:\n", board->num_pins); + + for (i = 0; i < board->num_pins; i ++) { + if (board->pin[i].gtag == board->pin[i].sec_tag) { + + PRINT( + msg_level, + " I/O Pin % 3d: %s #%d, pin %s (%s)\n", + i, + hm2_get_general_function_name(board->pin[i].gtag), + board->pin[i].sec_unit, + hm2_get_pin_secondary_name(&board->pin[i]), + ((board->pin[i].sec_pin & 0x80) ? "Output" : "Input") + ); + + } else { + PRINT( + msg_level, + " I/O Pin % 3d: %s\n", + i, + hm2_get_general_function_name(board->pin[i].gtag) + ); + } + } +} + + +static int m7i43_hm2_configure_pins(m7i43_t *board) { + int i; + + + // + // reset to all gpios, all inputs, not open drain, not output-inverted + // + + for (i = 0; i < board->ioport.num_instances; i ++) { + board->ioport.instance[i].data = 0x000000; // data is delicious + board->ioport.instance[i].ddr = 0x000000; // all are inputs + board->ioport.instance[i].alt_source = 0x000000; // they're all gpios + board->ioport.instance[i].open_drain = 0x000000; // none are open drain + board->ioport.instance[i].output_invert = 0x000000; // none are output-inverted + } + + for (i = 0; i < board->num_pins; i ++) { + board->pin[i].gtag = board->pin[i].primary_tag; + } + + + // + // the bits in the alt_source register of the ioport function say + // whether *output* data comes from the primary source (ioport + // function) (0) or the secondary source (1) + // + // the bits in the data direction register say whether the pins are + // inputs (0) or outputs (1) + // + // if a pin is marked as an input in the ddr, it can be used for its + // function (encoder, say) *and* as a digital input pin without + // conflict, but the driver does not support this + // + // Each function instance that is not disabled by the relevant + // num_<functions> modparam has all its pins marked 1 in the alt_source + // register. The driver uses this to to keep track of which pins are + // "allocated" to functions and which pins are available for use as + // gpios. + // + + + // + // deal with Encoder pins + // + + if (board->encoder.num_instances > 0) { + for (i = 0; i < board->num_pins; i ++) { + if ( + (board->pin[i].sec_tag == HM2_GTAG_ENCODER) + && (board->pin[i].sec_unit < board->encoder.num_instances) + ) { + hm2_set_pin_source(board, i, HM2_PIN_SOURCE_IS_SECONDARY); + if (board->pin[i].sec_pin & 0x80){ + hm2_set_pin_direction(board, i, HM2_PIN_DIR_IS_OUTPUT); + } + } + } + } + + + // + // deal with PWMGen pins + // + + if (board->pwmgen.num_instances > 0) { + for (i = 0; i < board->num_pins; i ++) { + if ( + (board->pin[i].sec_tag == HM2_GTAG_PWMGEN) + && (board->pin[i].sec_unit < board->pwmgen.num_instances) + ) { + hm2_set_pin_source(board, i, HM2_PIN_SOURCE_IS_SECONDARY); + if (board->pin[i].sec_pin & 0x80) { + hm2_set_pin_direction(board, i, HM2_PIN_DIR_IS_OUTPUT); + } + } + } + } + + + // + // any pin not claimed by the secondary function becomes a gpio + // + + for (i = 0; i < board->num_pins; i ++) { + char name[HAL_NAME_LEN + 2]; + int r; + + if (board->pin[i].gtag != HM2_GTAG_IOPORT) { + board->pin[i].hal = NULL; + continue; + } + + board->pin[i].hal = (hal_gpio_t *)hal_malloc(sizeof(hal_gpio_t)); + if (board->pin[i].hal == NULL) { + PRINT(RTAPI_MSG_ERR, "out of memory!\n"); + return -1; + } + + // pins + rtapi_snprintf(name, HAL_NAME_LEN, "m7i43_hm2.%d.gpio.%03d.in", 0, i); + r = hal_pin_bit_new(name, HAL_OUT, &(board->pin[i].hal->pin.in), comp_id); + if (r != HAL_SUCCESS) { + PRINT(RTAPI_MSG_ERR, "error adding pin '%s', aborting\n", name); + return 0; // fail + } + + rtapi_snprintf(name, HAL_NAME_LEN, "m7i43_hm2.%d.gpio.%03d.in_not", 0, i); + r = hal_pin_bit_new(name, HAL_OUT, &(board->pin[i].hal->pin.in_not), comp_id); + if (r != HAL_SUCCESS) { + PRINT(RTAPI_MSG_ERR, "error adding pin '%s', aborting\n", name); + return 0; // fail + } + + rtapi_snprintf(name, HAL_NAME_LEN, "m7i43_hm2.%d.gpio.%03d.out", 0, i); + r = hal_pin_bit_new(name, HAL_IN, &(board->pin[i].hal->pin.out), comp_id); + if (r != HAL_SUCCESS) { + PRINT(RTAPI_MSG_ERR, "error adding pin '%s', aborting\n", name); + return 0; // fail + } + + // parameters + rtapi_snprintf(name, HAL_NAME_LEN, "m7i43_hm2.%d.gpio.%03d.is_output", 0, i); + r = hal_param_bit_new(name, HAL_RW, &(board->pin[i].hal->param.is_output), comp_id); + if (r != HAL_SUCCESS) { + PRINT(RTAPI_MSG_ERR, "error adding param '%s', aborting\n", name); + return 0; // fail + } + + rtapi_snprintf(name, HAL_NAME_LEN, "m7i43_hm2.%d.gpio.%03d.invert_output", 0, i); + r = hal_param_bit_new(name, HAL_RW, &(board->pin[i].hal->param.invert_output), comp_id); + if (r != HAL_SUCCESS) { + PRINT(RTAPI_MSG_ERR, "error adding param '%s', aborting\n", name); + return 0; // fail + } + + + // initialize + hm2_set_pin_direction(board, i, HM2_PIN_DIR_IS_INPUT); + *(board->pin[i].hal->pin.out) = 0; + board->pin[i].hal->param.is_output = 0; + board->pin[i].hal->param.invert_output = 0; + } + + + // + // push settings out to IOPort function + // + + m7i43_epp_addr16(board->ioport.data_addr + M7I43_HM2_ADDR_AUTOINCREMENT); + for (i = 0; i < board->ioport.num_instances; i ++) { + m7i43_epp_write32(board->ioport.instance[i].data); + } + + m7i43_epp_addr16(board->ioport.ddr_addr + M7I43_HM2_ADDR_AUTOINCREMENT); + for (i = 0; i < board->ioport.num_instances; i ++) { + m7i43_epp_write32(board->ioport.instance[i].ddr); + board->ioport.instance[i].written_ddr = board->ioport.instance[i].ddr; + } + + m7i43_epp_addr16(board->ioport.alt_source_addr + M7I43_HM2_ADDR_AUTOINCREMENT); + for (i = 0; i < board->ioport.num_instances; i ++) { + m7i43_epp_write32(board->ioport.instance[i].alt_source); + } + + m7i43_epp_addr16(board->ioport.open_drain_addr + M7I43_HM2_ADDR_AUTOINCREMENT); + for (i = 0; i < board->ioport.num_instances; i ++) { + m7i43_epp_write32(board->ioport.instance[i].open_drain); + } + + m7i43_epp_addr16(board->ioport.output_invert_addr + M7I43_HM2_ADDR_AUTOINCREMENT); + for (i = 0; i < board->ioport.num_instances; i ++) { + m7i43_epp_write32(board->ioport.instance[i].output_invert); + } + + return 1; // success! +} + + + + +// +// some little functions to print out what we got +// + + +static void hm2_print_function_encoder(int msg_level, m7i43_t *board) { + int i; + PRINT(msg_level, "Encoders: %d\n", board->encoder.num_instances); + PRINT(msg_level, " clock_frequency: %d Hz (%d KHz, %d MHz)\n", board->ioport.clock_frequency, (board->ioport.clock_frequency / 1000), (board->ioport.clock_frequency / (1000*1000))); + PRINT(msg_level, " counter_addr: 0x%04X\n", board->encoder.counter_addr); + PRINT(msg_level, " latch_control_addr: 0x%04X\n", board->encoder.latch_control_addr); + PRINT(msg_level, " timestamp_div_addr: 0x%04X\n", board->encoder.timestamp_div_addr); + PRINT(msg_level, " timestamp_count_addr: 0x%04X\n", board->encoder.timestamp_count_addr); + for (i = 0; i < board->encoder.num_instances; i ++) { + PRINT(msg_level, " instance %d:\n", i); + PRINT(msg_level, " hw:\n"); + PRINT(msg_level, " count = %d\n", board->encoder.instance[i].hw.count); + PRINT(msg_level, " timestamp = %d\n", board->encoder.instance[i].hw.timestamp); + } +} + +static void hm2_print_function_ioport(int msg_level, m7i43_t *board) { + int i; + PRINT(msg_level, "IO Ports: %d\n", board->ioport.num_instances); + PRINT(msg_level, " clock_frequency: %d Hz (%d KHz, %d MHz)\n", board->ioport.clock_frequency, (board->ioport.clock_frequency / 1000), (board->ioport.clock_frequency / (1000*1000))); + PRINT(msg_level, " data_addr: 0x%04X\n", board->ioport.data_addr); + PRINT(msg_level, " ddr_addr: 0x%04X\n", board->ioport.ddr_addr); + PRINT(msg_level, " alt_source_addr: 0x%04X\n", board->ioport.alt_source_addr); + PRINT(msg_level, " open_drain_addr: 0x%04X\n", board->ioport.open_drain_addr); + PRINT(msg_level, " output_invert_addr: 0x%04X\n", board->ioport.output_invert_addr); + for (i = 0; i < board->ioport.num_instances; i ++) { + PRINT(msg_level, " instance %d:\n", i); + PRINT(msg_level, " data = 0x%06X\n", board->ioport.instance[i].data); + PRINT(msg_level, " ddr = 0x%06X\n", board->ioport.instance[i].ddr); + PRINT(msg_level, " alt_source = 0x%06X\n", board->ioport.instance[i].alt_source); + PRINT(msg_level, " open_drain = 0x%06X\n", board->ioport.instance[i].open_drain); + PRINT(msg_level, " output_invert = 0x%06X\n", board->ioport.instance[i].output_invert); + } +} + +static void hm2_print_function_pwmgen(int msg_level, m7i43_t *board) { + int i; + PRINT(msg_level, "PWMGen: %d\n", board->pwmgen.num_instances); + PRINT(msg_level, " clock_frequency: %d Hz (%d KHz, %d MHz)\n", board->pwmgen.clock_frequency, (board->pwmgen.clock_frequency / 1000), (board->pwmgen.clock_frequency / (1000*1000))); + PRINT(msg_level, " pwmgen_master_rate_dds: 0x%08X (%d)\n", board->pwmgen.pwmgen_master_rate_dds, board->pwmgen.pwmgen_master_rate_dds); + PRINT(msg_level, " pdmgen_master_rate_dds: 0x%08X (%d)\n", board->pwmgen.pdmgen_master_rate_dds, board->pwmgen.pdmgen_master_rate_dds); + PRINT(msg_level, " enable: 0x%08X\n", board->pwmgen.enable); + PRINT(msg_level, " pwm_value_addr: 0x%04X\n", board->pwmgen.pwm_value_addr); + PRINT(msg_level, " pwm_mode_addr: 0x%04X\n", board->pwmgen.pwm_mode_addr); + PRINT(msg_level, " pwmgen_master_rate_dds_addr: 0x%04X\n", board->pwmgen.pwmgen_master_rate_dds_addr); + PRINT(msg_level, " pdmgen_master_rate_dds_addr: 0x%04X\n", board->pwmgen.pdmgen_master_rate_dds_addr); + PRINT(msg_level, " enable_addr: 0x%04X\n", board->pwmgen.enable_addr); + for (i = 0; i < board->ioport.num_instances; i ++) { + PRINT(msg_level, " instance %d:\n", i); + PRINT(msg_level, " hw:\n"); + PRINT(msg_level, " pwm_val = 0x%08X\n", board->pwmgen.instance[i].hw.pwm_val); + PRINT(msg_level, " pwm_mode = 0x%08X\n", board->pwmgen.instance[i].hw.pwm_mode); + } +} + +static void hm2_print_functions(int msg_level, m7i43_t *board) { + hm2_print_function_encoder(msg_level, board); + hm2_print_function_ioport(msg_level, board); + hm2_print_function_pwmgen(msg_level, board); +} + + + + +// +// functions for talking to the CPLD on the 7i43 +// + +// returns TRUE if the FPGA reset, FALSE on error +static int m7i43_cpld_reset(void) { + uint8_t byte; + + + // select the control register + m7i43_epp_addr8(1); + + // bring the Spartan3's PROG_B line low for 1 us (the specs require 300-500 ns or longer) + m7i43_epp_write(0x00); + m7i43_nanosleep(1 * 1000); + + // bring the Spartan3's PROG_B line high and wait for 2 ms before sending firmware (required by spec) + m7i43_epp_write(0x01); + m7i43_nanosleep(2 * 1000 * 1000); // FIXME: it'd be nice to schedule() here + + // make sure the FPGA is not asserting its DONE bit + byte = m7i43_epp_read(); + if ((byte & 0x01) != 0) { + PRINT(RTAPI_MSG_ERR, "DONE is not low after CPLD reset!\n"); + return 0; + } + + return 1; +} + + +// returns FPGA size in K-gates +static void m7i43_cpld_get_fpga_size(m7i43_t *board) { + uint8_t byte; + + // select data register + m7i43_epp_addr8(0); + + byte = m7i43_epp_read(); + if ((byte & 0x01) == 0x01) { + board->cpld.fpga_size = 400; + } else { + board->cpld.fpga_size = 200; + } +} + + +static int m7i43_cpld_send_firmware(m7i43_t *board) { + void *firmware; + int firmware_size; + + int64_t start_time, end_time; + + int orig_debug_epp = debug_epp; + + + // + // pick a firmware + // FIXME: in time i'd like a nice flexible way for the user to specify which firmware to load on which board + // + + if (board->cpld.fpga_size == 200) { + firmware = m7i43_firmware_svst44_2_bit; + firmware_size = sizeof(m7i43_firmware_svst44_2_bit); + } else if (board->cpld.fpga_size == 400) { + firmware = m7i43_firmware_svst44_4_bit; + firmware_size = sizeof(m7i43_firmware_svst44_4_bit); + } else { + PRINT(RTAPI_MSG_ERR, "unknown FPGA size: %d\n", board->cpld.fpga_size); + return 0; + } + + + // + // send the firmware + // + + debug_epp = 0; + start_time = rtapi_get_time(); + + // select the CPLD's data address + m7i43_epp_addr8(0); + + { + int i; + + for (i = 0; i < (firmware_size & ~0x3); i += 4, firmware += 4) { + m7i43_epp_write32(*(__u32*)firmware); + } + for (; i < firmware_size; i += 1, firmware ++) { + m7i43_epp_write(*(__u8*)firmware); + } + } + + end_time = rtapi_get_time(); + debug_epp = orig_debug_epp; + + + // + // brag about how fast it was + // + + { + uint32_t duration_ns; + + duration_ns = (uint32_t)(end_time - start_time); + + PRINT( + RTAPI_MSG_INFO, + "%d bytes of firmware sent (%u KB/s)\n", + firmware_size, + (uint32_t)(((double)firmware_size / ((double)duration_ns / (double)(1000 * 1000 * 1000))) / 1024) + ); + } + + + if (m7i43_epp_check_for_timeout()) { + PRINT(RTAPI_MSG_ERR, "EPP Timeout after sending firmware!\n"); + return 0; + } + + return 1; +} + + + + +// +// setup and cleanup code +// + + +static void *m7i43_region1 = NULL; +static void *m7i43_region2 = NULL; + + +static void m7i43_cleanup(void) { + PRINT(RTAPI_MSG_INFO, "unloading\n"); + + // NOTE: hal_malloc() doesnt have a matching free + + // if we've initialized the board, reset it now + if (m7i43_region1 && m7i43_region2) { + m7i43_hm2_reset(); + } + + if (m7i43_region1) { + rtapi_release_region(ioaddr, 8); + } + + if (m7i43_region2) { + rtapi_release_region(ioaddr_hi, 4); + } +} + + +static int m7i43_setup(void) { + int r; + + + PRINT(RTAPI_MSG_INFO, "loading Mesa 7i43 HostMot2 driver version %s\n", M7I43_HM2_VERSION); + + // zero the board struct + memset(&board, 0, sizeof(m7i43_t)); + + if (ioaddr_hi == 0) { + ioaddr_hi = ioaddr + 0x400; + } else if (ioaddr_hi < 0) { + PRINT(RTAPI_MSG_ERR, "invalid ioaddr_hi 0x%X\n", ioaddr_hi); + return -EBUSY; + } + + PRINT(RTAPI_MSG_DBG, "ioaddr=0x%04X, ioaddr_hi=0x%04X, wide mode is %s\n", ioaddr, ioaddr_hi, (epp_wide ? "ON" : "OFF")); + + + // + // claim the I/O regions for the parport + // + + m7i43_region1 = rtapi_request_region(ioaddr, 8, "m7i43_hm2"); + if (!m7i43_region1) { + PRINT(RTAPI_MSG_ERR, "request_region(%x) failed\n", ioaddr); + PRINT(RTAPI_MSG_ERR, "(make sure the kernel module 'parport' is unloaded)\n"); + return -EBUSY; + } + + m7i43_region2 = rtapi_request_region(ioaddr_hi, 4, "m7i43_hm2"); + if (!m7i43_region2) { + rtapi_release_region(ioaddr, 8); + PRINT(RTAPI_MSG_ERR, "request_region(%x) failed\n", ioaddr); + PRINT(RTAPI_MSG_ERR, "(make sure the kernel module 'parport' is unloaded)\n"); + return -EBUSY; + } + + + // + // set up the parport for EPP + // + + outb(0x80, ioaddr_hi + M7I43_ECP_CONTROL_HIGH_OFFSET); // select EPP mode in ECR + m7i43_epp_write_control(0x04); // set control lines and input mode + + m7i43_epp_clear_timeout(); + + + // + // command the CPLD to reset the FPGA, then send appropriate firmware + // + // FIXME: This only works if the CPLD is currently in control of the + // EPP connection. When the FPGA is successfully configured, it + // disconnects the CPLD from the EPP lines. If the FPGA is in + // control of the EPP, then this function will not reset it, and + // subsequent programming of the FPGA will fail. + // The only real solution to this problem is to make the CPLD and + // FPGA reset procedures identical (currently they are different). + // + + if (!m7i43_cpld_reset()) { + PRINT(RTAPI_MSG_ERR, "error resetting FPGA, aborting load\n"); + return -EIO; + } + + m7i43_cpld_get_fpga_size(&board); + + if (!m7i43_cpld_send_firmware(&board)) { + PRINT(RTAPI_MSG_ERR, "error sending FPGA firmware, aborting load\n"); + return -EIO; + } + + + // + // verify FPGA firmware IOCookie + // + + { + uint32_t cookie; + + m7i43_epp_addr16(M7I43_HM2_ADDR_IOCOOKIE | M7I43_HM2_ADDR_AUTOINCREMENT); + cookie = m7i43_epp_read32(); + if (cookie != M7I43_HM2_IOCOOKIE) { + PRINT(RTAPI_MSG_ERR, "invalid cookie, got 0x%08X, expected 0x%08X\n", cookie, M7I43_HM2_IOCOOKIE); + PRINT(RTAPI_MSG_ERR, "FPGA failed to initialize, or unexpected firmware?\n"); + return -EINVAL; + } + } + + + // + // verify FPGA firmware ConfigName + // + + { + int i; + + m7i43_epp_addr16(M7I43_HM2_ADDR_CONFIGNAME | M7I43_HM2_ADDR_AUTOINCREMENT); + for (i = 0; i < M7I43_HM2_CONFIGNAME_LENGTH; i ++) { + board.config_name[i] = m7i43_epp_read(); + } + board.config_name[i] = '\0'; + if (strncmp(board.config_name, M7I43_HM2_CONFIGNAME, 9) != 0) { + PRINT(RTAPI_MSG_ERR, "invalid config name, got '%s', expected '%s'\n", board.config_name, M7I43_HM2_CONFIGNAME); + return -EINVAL; + } + } + + + // + // read the IDROM + // + + // get the IDRom offset + m7i43_epp_addr16(M7I43_HM2_ADDR_IDROM_OFFSET | M7I43_HM2_ADDR_AUTOINCREMENT); + board.idrom_offset = m7i43_epp_read32(); + + r = m7i43_hm2_read_idrom(&board); + if (r != 0) { + // a descriptive error has already been logged + return r; + } + + if (m7i43_epp_check_for_timeout()) { + PRINT(RTAPI_MSG_ERR, "EPP Timeout after reading IDRom!\n"); + return -EIO; + } + + + // + // read and then parse the modules, and initialize the functions found + // + + m7i43_hm2_read_module_descriptors(&board); + + if (!m7i43_hm2_parse_module_descriptors(&board)) { + return -EINVAL; + } + + if (board.idrom.io_ports != board.ioport.num_instances) { + PRINT( + RTAPI_MSG_ERR, + "IDROM IOPorts is %d but MD IOPort NumInstances is %d, inconsistent firmware, aborting driver load\n", + board.idrom.io_ports, + board.ioport.num_instances + ); + return -EINVAL; + } + + if (board.idrom.io_width != (board.idrom.io_ports * board.idrom.port_width)) { + PRINT( + RTAPI_MSG_ERR, + "IDROM IOWidth is %d, but IDROM IOPorts is %d and IDROM PortWidth is %d (inconsistent firmware), aborting driver load\n", + board.idrom.io_width, + board.idrom.io_ports, + board.idrom.port_width + ); + return -EINVAL; + } + + if (debug_functions) { + PRINT(RTAPI_MSG_DBG, "HM2 Functions used:\n"); + hm2_print_functions(RTAPI_MSG_DBG, &board); + } + + + // + // read the pins and set IOPorts based on detected functions + // all detected functions get their pins, the other pins are left as GPIOs + // + + if (!m7i43_hm2_read_pin_descriptors(&board)) { + return -EINVAL; + } + + if (board.num_pins != board.idrom.io_width) { + PRINT(RTAPI_MSG_ERR, "there are %d Pin Descriptors but IDROM IO_Width is %d!\n", board.num_pins, board.idrom.io_width); + return -EINVAL; + } + + if (debug_pin_descriptors) { + hm2_print_pin_descriptors(RTAPI_MSG_DBG, &board); + } + + if (!m7i43_hm2_configure_pins(&board)) { + return -EINVAL; + } + + hm2_print_pin_usage(RTAPI_MSG_INFO, &board); + + + + + // + // did it work? + // + + if (m7i43_epp_check_for_timeout()) { + PRINT(RTAPI_MSG_ERR, "EPP Timeout after reading modules!\n"); + return -EIO; + } + + + + + // + // report success! + // + + PRINT( + RTAPI_MSG_INFO, + "configured board '%s' (%d K gates) at EPP 0x%04X with firmware '%s'\n", + board.idrom.board_name, + board.idrom.fpga_size, + ioaddr, + board.config_name + ); + + + return 0; +} + + +EXTRA_SETUP() { + return m7i43_setup(); +} + + +EXTRA_CLEANUP() { + m7i43_cleanup(); +} + + + + +// +// functions exported to EMC +// FIXME: export these manually so they get names with '_' instead of '-' +// + + +FUNCTION(encoder_update_counters) { + int i; + + // read counters & timestamps + m7i43_epp_addr16(board.encoder.counter_addr + M7I43_HM2_ADDR_AUTOINCREMENT); + for (i = 0; i < board.encoder.num_instances; i ++) { + __u32 d; + __s32 count_diff; + + board.encoder.instance[i].hw.prev_count = board.encoder.instance[i].hw.count; + board.encoder.instance[i].hw.prev_timestamp = board.encoder.instance[i].hw.timestamp; + + d = m7i43_epp_read32(); + board.encoder.instance[i].hw.count = d & 0x0000FFFF; + board.encoder.instance[i].hw.timestamp = (d >> 16) & 0x0000FFFF; + + count_diff = (__u32)board.encoder.instance[i].hw.count - (__u32)board.encoder.instance[i].hw.prev_count; + if (count_diff > 32768) count_diff -= 65536; + if (count_diff < -32768) count_diff += 65536; + *(board.encoder.instance[i].hal.pin.count) += count_diff; + } + + if (!m7i43_epp_clear_timeout()) { + PRINT(RTAPI_MSG_ERR, "failed to clean EPP Timeout after reading encoder counts!\n"); + } +} + + +FUNCTION(encoder_capture_position) { + int i; + + for (i = 0; i < board.encoder.num_instances; i ++) { + if (board.encoder.instance[i].hal.param.scale == 0.0) { + PRINT(RTAPI_MSG_WARN, "encoder %d has invalid scale 0.0, setting to 1.0\n", i); + board.encoder.instance[i].hal.param.scale = 1.0; + } + *(board.encoder.instance[i].hal.pin.position) = *(board.encoder.instance[i].hal.pin.count) / board.encoder.instance[i].hal.param.scale; + } +} + + +FUNCTION(pwmgen_update) { + int i; + + if (board.pwmgen.num_instances == 0) return; + + // rewrite enable register? + { + __u32 new_enable = 0; + + for (i = 0; i < board.pwmgen.num_instances; i ++) { + if (*(board.pwmgen.instance[i].hal.pin.enable)) { + new_enable |= (1 << i); + } + } + + if (new_enable != board.pwmgen.enable) { + m7i43_epp_addr16(board.pwmgen.enable_addr + M7I43_HM2_ADDR_AUTOINCREMENT); + m7i43_epp_write32(new_enable); + board.pwmgen.enable = new_enable; + } + } + + // do any of the pwm_value registers need updating? + // if so update them all + { + int need_update_value = 0; + + for (i = 0; i < board.pwmgen.num_instances; i ++) { + if (*(board.pwmgen.instance[i].hal.pin.value) != board.pwmgen.instance[i].hal.pin.written_value) { + float val; + + need_update_value = 1; + val = fabs(*(board.pwmgen.instance[i].hal.pin.value)); + if (val > 1.0) val = 1.0; + board.pwmgen.instance[i].hw.pwm_val = val / board.pwmgen.instance[i].hal.param.scale; + board.pwmgen.instance[i].hw.pwm_val <<= 16; + if (*(board.pwmgen.instance[i].hal.pin.value) < 0) { + board.pwmgen.instance[i].hw.pwm_val |= (1 << 31); + } + board.pwmgen.instance[i].hal.pin.written_value = *(board.pwmgen.instance[i].hal.pin.value); + } + } + + if (need_update_value) { + m7i43_epp_addr16(board.pwmgen.pwm_value_addr + M7I43_HM2_ADDR_AUTOINCREMENT); + for (i = 0; i < board.pwmgen.num_instances; i ++) { + m7i43_epp_write32(board.pwmgen.instance[i].hw.pwm_val); + } + } + + if (!m7i43_epp_clear_timeout()) { + PRINT(RTAPI_MSG_ERR, "failed to clean EPP Timeout after updating pwmgen values!\n"); + } + } +} + + +FUNCTION(gpio_update) { + int port; + int port_pin; + + int io_pin; + + int update_ddr = 0; + + + // + // update ioport variables + // + + for (port = 0; port < board.ioport.num_instances; port ++) { + for (port_pin = 0; port_pin < board.idrom.port_width; port_pin ++) { + io_pin = (port * board.idrom.port_width) + port_pin; + if (board.pin[io_pin].gtag != HM2_GTAG_IOPORT) continue; + + if (board.pin[io_pin].hal->param.is_output) { + hal_bit_t out; + + board.ioport.instance[port].ddr |= (1 << port_pin); // set the bit in the ddr register + + out = *(board.pin[io_pin].hal->pin.out) ^ board.pin[io_pin].hal->param.invert_output; + board.ioport.instance[port].data &= ~(1 << port_pin); // zero the bit + board.ioport.instance[port].data |= (out << port_pin); // and set it as appropriate + } else { + board.ioport.instance[port].ddr &= ~(1 << port_pin); // clear the bit in the ddr register + } + } + } + + + // + // update ddr if needed + // + + for (port = 0; port < board.ioport.num_instances; port ++) { + if (board.ioport.instance[port].written_ddr != board.ioport.instance[port].ddr) { + update_ddr = 1; + break; + } + } + if (update_ddr) { + m7i43_epp_addr16(board.ioport.ddr_addr + M7I43_HM2_ADDR_AUTOINCREMENT); + for (port = 0; port < board.ioport.num_instances; port ++) { + m7i43_epp_write32(board.ioport.instance[port].ddr); + board.ioport.instance[port].written_ddr = board.ioport.instance[port].ddr; + } + } + + + // + // write data ... + // + + m7i43_epp_addr16(board.ioport.data_addr + M7I43_HM2_ADDR_AUTOINCREMENT); + for (port = 0; port < board.ioport.num_instances; port ++) { + m7i43_epp_write32(board.ioport.instance[port].data); + } + + + // + // ... and read data + // + + m7i43_epp_addr16(board.ioport.data_addr + M7I43_HM2_ADDR_AUTOINCREMENT); + for (port = 0; port < board.ioport.num_instances; port ++) { + board.ioport.instance[port].data = m7i43_epp_read32(); + + for (port_pin = 0; port_pin < board.idrom.port_width; port_pin ++) { + io_pin = (port * board.idrom.port_width) + port_pin; + if (board.pin[io_pin].gtag != HM2_GTAG_IOPORT) continue; + + if (!board.pin[io_pin].hal->param.is_output) { + hal_bit_t bit; + + bit = (board.ioport.instance[port].data >> port_pin) & 0x1; + *board.pin[io_pin].hal->pin.in = bit; + *board.pin[io_pin].hal->pin.in_not = !bit; + } + } + } +} + diff --git a/src/hal/drivers/m7i43_hm2.h b/src/hal/drivers/m7i43_hm2.h new file mode 100644 index 000000000..3e8237918 --- /dev/null +++ b/src/hal/drivers/m7i43_hm2.h @@ -0,0 +1,306 @@ +// Copyright (C) 2007-2008 Sebastian Kuzminsky +// +// 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. +// +// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +#ifndef RTAPI +#error This is a realtime component only! +#endif + + +#define M7I43_HM2_VERSION "0.1" + +#define M7I43_HM2_ID "m7i43_hm2: " +#define PRINT(level, fmt, args...) rtapi_print_msg(level, M7I43_HM2_ID fmt, ## args); +#define DEBUG(enable, fmt, args...) if (enable) { rtapi_print_msg(RTAPI_MSG_DBG, fmt, ## args); } + +static void m7i43_nanosleep(unsigned long int nanoseconds); + + +// +// EPP stuff +// + +#define M7I43_EPP_STATUS_OFFSET (1) +#define M7I43_EPP_CONTROL_OFFSET (2) +#define M7I43_EPP_ADDRESS_OFFSET (3) +#define M7I43_EPP_DATA_OFFSET (4) + +#define M7I43_ECP_CONFIG_A_HIGH_OFFSET (0) +#define M7I43_ECP_CONFIG_B_HIGH_OFFSET (1) +#define M7I43_ECP_CONTROL_HIGH_OFFSET (2) + + +// +// Mesa 7i43 HostMot2 stuff +// + +#define M7I43_HM2_ADDR_AUTOINCREMENT (0x8000) + +#define M7I43_HM2_ADDR_IOCOOKIE (0x0100) +#define M7I43_HM2_IOCOOKIE (0x55AACAFE) + +#define M7I43_HM2_ADDR_CONFIGNAME (0x0104) +#define M7I43_HM2_CONFIGNAME "HOSTMOT2" +#define M7I43_HM2_CONFIGNAME_LENGTH (8) + +#define M7I43_HM2_ADDR_IDROM_OFFSET (0x010C) + +#define M7I43_HM2_MAX_MODULE_DESCRIPTORS (48) +#define M7I43_HM2_MAX_PIN_DESCRIPTORS (128) + +#define HM2_PIN_SOURCE_IS_PRIMARY (0x00000000) +#define HM2_PIN_SOURCE_IS_SECONDARY (0x00000001) + +#define HM2_PIN_DIR_IS_INPUT (0x00000002) +#define HM2_PIN_DIR_IS_OUTPUT (0x00000004) + + +#define HM2_GTAG_WATCHDOG (2) +#define HM2_GTAG_IOPORT (3) +#define HM2_GTAG_ENCODER (4) +#define HM2_GTAG_STEPGEN (5) +#define HM2_GTAG_PWMGEN (6) +#define HM2_GTAG_TRANSLATIONRAM (11) + + + + +// +// HostMot2 IDROM structs +// + + +typedef struct { + __u8 gtag; + __u8 version; + __u8 clock_tag; + __u8 instances; + __u16 base_address; + + __u8 num_registers; + __u32 register_stride; + __u32 instance_stride; + __u32 multiple_registers; +} hm2_module_descriptor_t; + + +typedef struct { + __u32 idrom_type; + __u32 offset_to_modules; + __u32 offset_to_pin_desc; + __u8 board_name[9]; // we just read 8 bytes from the IDRom, but then we add a NULL + __u32 board_name_low; + __u32 board_name_high; + __u32 fpga_size; + __u32 fpga_pins; + __u32 io_ports; + __u32 io_width; + __u32 port_width; + __u32 clock_low; + __u32 clock_high; + __u32 register_stride_0; + __u32 register_stride_1; + __u32 instance_stride_0; + __u32 instance_stride_1; +} hm2_idrom_t; + + +typedef struct { + struct { + hal_bit_t *in; + hal_bit_t *in_not; + hal_bit_t *out; + } pin; + + struct { + hal_bit_t is_output; // hm2 calls this "ddr" + hal_bit_t invert_output; + } param; +} hal_gpio_t; + + +typedef struct { + // these are from the Pin Descriptor in the HM2 IDROM + __u8 sec_pin; + __u8 sec_tag; + __u8 sec_unit; + __u8 primary_tag; + + // these are how the driver keeps track of them + int gtag; // the actual function using this pin + + // if the driver decides to make this pin a gpio, it'll allocate the hal struct to manage it + // otherwise hal is NULL + hal_gpio_t *hal; +} hm2_pin_t; + + + + +// +// these structures translate between HostMot2 Functions and HAL objects +// + + +typedef struct { + struct { + __u16 count; + __u16 timestamp; + + __u16 prev_count; + __u16 prev_timestamp; + } hw; + + struct { + + struct { + hal_s32_t *count; + hal_float_t *position; + // hal_float_t *velocity; + // hal_bit_t *reset; + // hal_bit_t *index_enable; + } pin; + + struct { + hal_float_t scale; + // hal_float_t max_index_vel; + // hal_float_t velocity_resolution; + } param; + + } hal; +} hm2_encoder_instance_t; + + +typedef struct { + int num_instances; + hm2_encoder_instance_t *instance; + + __u32 clock_frequency; + __u8 version; + + __u32 counter_addr; + __u32 latch_control_addr; + __u32 timestamp_div_addr; + __u32 timestamp_count_addr; +} hm2_encoder_t; + + + + +typedef struct { + struct { + __u32 pwm_val; + __u32 pwm_mode; + } hw; + + struct { + + struct { + hal_float_t *value; + float written_value; + + hal_bit_t *enable; + } pin; + + struct { + hal_float_t scale; + } param; + + } hal; +} hm2_pwmgen_instance_t; + + +typedef struct { + int num_instances; + hm2_pwmgen_instance_t *instance; + + __u32 clock_frequency; + __u8 version; + + __u32 pwmgen_master_rate_dds; + __u32 pdmgen_master_rate_dds; + + // value currently in the enable register + // we only re-write this register when it changes + __u32 enable; + + __u32 pwm_value_addr; + __u32 pwm_mode_addr; + __u32 pwmgen_master_rate_dds_addr; + __u32 pdmgen_master_rate_dds_addr; + __u32 enable_addr; +} hm2_pwmgen_t; + + + + +typedef struct { + __u32 data; + __u32 ddr; + __u32 alt_source; + __u32 open_drain; + __u32 output_invert; + + __u32 written_ddr; +} hm2_ioport_instance_t; + + +typedef struct { + int num_instances; + hm2_ioport_instance_t *instance; + + __u32 clock_frequency; + __u8 version; + + __u32 data_addr; + __u32 ddr_addr; + __u32 alt_source_addr; + __u32 open_drain_addr; + __u32 output_invert_addr; +} hm2_ioport_t; + + + + +// +// Mesa 7i43 structs +// + + +typedef struct { + int fpga_size; +} cpld_t; + + +typedef struct { + cpld_t cpld; + + char config_name[M7I43_HM2_CONFIGNAME_LENGTH + 1]; + __u16 idrom_offset; + + hm2_idrom_t idrom; + + hm2_module_descriptor_t md[M7I43_HM2_MAX_MODULE_DESCRIPTORS]; + int num_mds; + + hm2_pin_t pin[M7I43_HM2_MAX_PIN_DESCRIPTORS]; + int num_pins; + + // the hostmot2 "Functions" + hm2_encoder_t encoder; + hm2_pwmgen_t pwmgen; + hm2_ioport_t ioport; +} m7i43_t; + diff --git a/src/hal/drivers/mesa7i43-firmware/7i43infc.pin b/src/hal/drivers/mesa7i43-firmware/gpio/7i43infc.pin index 35d6bfc0a..35d6bfc0a 100644 --- a/src/hal/drivers/mesa7i43-firmware/7i43infc.pin +++ b/src/hal/drivers/mesa7i43-firmware/gpio/7i43infc.pin diff --git a/src/hal/drivers/mesa7i43-firmware/7i43io.pin b/src/hal/drivers/mesa7i43-firmware/gpio/7i43io.pin index ea42cd6b6..ea42cd6b6 100644 --- a/src/hal/drivers/mesa7i43-firmware/7i43io.pin +++ b/src/hal/drivers/mesa7i43-firmware/gpio/7i43io.pin diff --git a/src/hal/drivers/mesa7i43-firmware/eppio8-2.bit b/src/hal/drivers/mesa7i43-firmware/gpio/eppio8-2.bit Binary files differindex 5a52a250b..d8b908549 100644 --- a/src/hal/drivers/mesa7i43-firmware/eppio8-2.bit +++ b/src/hal/drivers/mesa7i43-firmware/gpio/eppio8-2.bit diff --git a/src/hal/drivers/mesa7i43-firmware/eppio8-4.bit b/src/hal/drivers/mesa7i43-firmware/gpio/eppio8-4.bit Binary files differindex 5b970632e..4c757868e 100644 --- a/src/hal/drivers/mesa7i43-firmware/eppio8-4.bit +++ b/src/hal/drivers/mesa7i43-firmware/gpio/eppio8-4.bit diff --git a/src/hal/drivers/mesa7i43-firmware/readme b/src/hal/drivers/mesa7i43-firmware/gpio/readme index 50633da2f..50633da2f 100644 --- a/src/hal/drivers/mesa7i43-firmware/readme +++ b/src/hal/drivers/mesa7i43-firmware/gpio/readme diff --git a/src/hal/drivers/mesa7i43-firmware/regmap b/src/hal/drivers/mesa7i43-firmware/gpio/regmap index a84c8f56f..369691c2e 100644 --- a/src/hal/drivers/mesa7i43-firmware/regmap +++ b/src/hal/drivers/mesa7i43-firmware/gpio/regmap @@ -1,45 +1,65 @@ -Simple 6 x 8 bit EPP driven I/O port configuration register map
-
-REGISTER ADDRESS FUNCTION
-
-PORT0 0x10 PORT0 DATA (IOBITS 0..7)
-PORT1 0x11 PORT0 DATA (IOBITS 8..15)
-PORT2 0x12 PORT0 DATA (IOBITS 16..23)
-PORT3 0x13 PORT0 DATA (IOBITS 24..31)
-PORT4 0x14 PORT0 DATA (IOBITS 32..39)
-PORT5 0x15 PORT0 DATA (IOBITS 40..47)
-
-Six byte wide GPIO ports, each I/O bit can be input or output
-depending on cooresponding DDR registers:
-
-PORT0DDR 0x20 PORT0 DATA DIRECTION REGISTER (1 = OUT)
-PORT1DDR 0x21 PORT1 DATA DIRECTION REGISTER (1 = OUT)
-PORT2DDR 0x22 PORT2 DATA DIRECTION REGISTER (1 = OUT)
-PORT3DDR 0x23 PORT3 DATA DIRECTION REGISTER (1 = OUT)
-PORT4DDR 0x24 PORT4 DATA DIRECTION REGISTER (1 = OUT)
-PORT5DDR 0x25 PORT5 DATA DIRECTION REGISTER (1 = OUT)
-
-A '1' bit in a DDR register sets the cooresponding bit in the data port
-to output mode. Inputs always read the I/O pin status even in output mode.
-All pins configured as inputs when FPGA is first configured (DDR registers
-initialized to 0x00)
-
-SPICS 0x7D BIT 0 CONTROLS EEPROM /CS PIN
-SPIDATA 0x7E WRITE SHIFTS 8 BITS TO EEPROM
- READS READ SHIFT REGISTER
-
-RECONFIG 0x7F WRITING 0x5A HERE RESETS FPGA
-
-
-NOTE: Addresses with A7 high enable address autoinc feature.
- I/O devices ignore A7 so for example you can write all 6
- I/O ports with this sequence:
-
- WriteAddress(0x90) ; address of PORT0 with A7 high
- WriteData(Port0Data)
- WriteData(Port1Data)
- WriteData(Port2Data)
- WriteData(Port3Data)
- WriteData(Port4Data)
- WriteData(Port5Data)
-
\ No newline at end of file +Simple 6 x 8 bit EPP driven I/O port configuration register map + + +REGISTER ADDRESS FUNCTION + +IDCOOKIE0 0x00 CHECK CONFIG =0xFE +IDCOOKIE1 0x01 CHECK CONFIG =0xCA +IDCOOKIE2 0x02 CHECK CONFIG =0xAA +IDCOOKIE3 0x03 CHECK CONFIG =0x55 + +CONFIGNAME0 0x04 'E' +CONFIGNAME1 0x05 'P' +CONFIGNAME2 0x06 'P' +CONFIGNAME3 0x07 'I' +CONFIGNAME4 0x08 'O' +CONFIGNAME5 0x09 '8' +CONFIGNAME6 0x0A '-' +CONFIGNAME7 0x0B '2' or '4' depending on FPGA + +VERSION0 0x0C Version +VERSION1 0x0D +VERSION2 0x0E +VERSION3 0x0F + +PORT0 0x10 PORT0 DATA (IOBITS 0..7) +PORT1 0x11 PORT0 DATA (IOBITS 8..15) +PORT2 0x12 PORT0 DATA (IOBITS 16..23) +PORT3 0x13 PORT0 DATA (IOBITS 24..31) +PORT4 0x14 PORT0 DATA (IOBITS 32..39) +PORT5 0x15 PORT0 DATA (IOBITS 40..47) + +Six byte wide GPIO ports, each I/O bit can be input or output +depending on cooresponding DDR registers: + +PORT0DDR 0x20 PORT0 DATA DIRECTION REGISTER (1 = OUT) +PORT1DDR 0x21 PORT1 DATA DIRECTION REGISTER (1 = OUT) +PORT2DDR 0x22 PORT2 DATA DIRECTION REGISTER (1 = OUT) +PORT3DDR 0x23 PORT3 DATA DIRECTION REGISTER (1 = OUT) +PORT4DDR 0x24 PORT4 DATA DIRECTION REGISTER (1 = OUT) +PORT5DDR 0x25 PORT5 DATA DIRECTION REGISTER (1 = OUT) + +A '1' bit in a DDR register sets the cooresponding bit in the data port +to output mode. Inputs always read the I/O pin status even in output mode. +All pins configured as inputs when FPGA is first configured (DDR registers +initialized to 0x00) + +SPICS 0x7D BIT 0 CONTROLS EEPROM /CS PIN +SPIDATA 0x7E WRITE SHIFTS 8 BITS TO EEPROM + READS READ SHIFT REGISTER + +RECONFIG 0x7F WRITING 0x5A HERE RESETS FPGA + + +NOTE: Addresses with A7 high enable address autoinc feature. + I/O devices ignore A7 so for example you can write all 6 + I/O ports with this sequence: + + WriteAddress(0x90) ; address of PORT0 with A7 high + WriteData(Port0Data) + WriteData(Port1Data) + WriteData(Port2Data) + WriteData(Port3Data) + WriteData(Port4Data) + WriteData(Port5Data) +
\ No newline at end of file diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/hostmot2-register-map b/src/hal/drivers/mesa7i43-firmware/hostmot2/hostmot2-register-map new file mode 100644 index 000000000..5f3c74e99 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/hostmot2-register-map @@ -0,0 +1,703 @@ +HostMot2 Register map in offsets from 32 bit memory base address
+
+Note the following addresses are standard but driver should use IDROM info
+instead of this table.
+
+Also, number of special functions (counters, PWMGens etc) is determined
+by configuration.
+Additional registers are always at increasing doubleword boundaries
+with the exception of UART data FIFOs.
+(this difference with UARTS make be fixed by using byte enables later)
+
+First ID stuff
+
+0x0100 Config cookie = 0x55AACAFE
+0x0104 First 4 characters of configuration name
+0x0108 Last 4 characters of configuration name
+0x010C Offset to IDROM location (normally 0x00000400)
+
+0x0400 Normal IDROM location
+
+0x400 IDROMType 2 for this type
+0x404 OffsetToModules 64 for this type
+0x408 OffsetToPindesc 512 for this type
+0x40C BoardNameLow
+0x410 BoardNameHigh
+0x414 FPGA size
+0x418 FPGA pins
+0x41C IOPorts
+0x420 IOWidth
+0x424 PortWidth Normally 24
+0x428 ClockLow In Hz (note:on 5I20/4I65 = PCI clock -- guessed as 33.33 MHz)
+0x42C ClockHigh In Hz
+
+0x440.. Module descriptions 0 through 47
+Each module descriptor is two doublewords with the following record structure:
+
+0x440: (from least to most significant order)
+GTag(0 (byte) = General function tag
+Number(0) (byte) = Number of modules in configuration
+ClockTag(0) (byte) = Whether module uses ClockHigh or ClockLow
+RegisterNum(0) (byte) = Which register in set
+BaseAddress(0) (word) = offset to module. This is also specific register = Tag
+Version(0) (word) = module version
+
+0x448:
+GTag(1) (byte) = General function tag
+Number(1) (byte) = Number of modules in configuration
+ClockTag(1) (byte) = Whether module uses ClockHigh or ClockLow
+RegisterNum(1) (byte) = Which register in set
+BaseAddress(1) (word) = offset to module. This is also specific register = Tag
+Version(1) (word) = module version
+...
+
+0 GTag marks end of module descriptors
+
+
+0x600 Pin descriptors 0 through 127.
+There is one Pin Descriptor for each I/O pin.
+Each pin descriptor is a doubleword with the following record structure:
+
+0x600
+SecPin(0) (byte) = Which pin of secondary function connects here eg: A,B,IDX.
+ Output pins have bit 7 = '1'
+SecTag(0) (byte) = Secondary function type (PWM,QCTR etc). Same as module GTag
+SecUnit(0) (byte) = Which secondary unit or channel connects here
+PrimaryTag(0) (byte) = Primary function tag (normally I/O port)
+
+0x604
+SecPin(1) (byte) = Which pin of secondary function connects here eg: A,B,IDX.
+ Output pins have bit 7 = '1'
+SecTag(1) (byte) = Secondary function type (PWM,QCTR etc). Same as module GTag
+SecUnit(1) (byte) = Which secondary unit or channel connects here
+PrimaryTag(1) (byte) = Primary function tag (normally I/O port)
+
+...
+
+0 primary function tag marks end of pins
+
+0x0800 1 bit IDROM write enable bit: high=Enable writes
+
+0x0900 IRQDiv
+
+16 bit divider of selected PWMreference output bit. Divides by n+2.
+
+0x0A00 IRQStatus
+
+Bit 2..4 Select which PWM reference counter bit is used as IRQ divider source:
+000 = PWMRefcount(MSB-4)
+001 = PWMRefcount(MSB-3)
+010 = PWMRefcount(MSB-2)
+011 = PWMRefcount(MSB-1)
+100 = PWMRefcount(MSB)
+
+Bit 1 = Irq mask: 0 = masked
+
+Bit 0 = IRQ status (R/W)
+
+0x0B00 ClearIRQ: Writes here clear IRQ
+
+
+0x0C00 WatchdogTimer (R/W
+
+32 bit watchdog timer.If MSB is set, watchdog is disabled.
+Timeout is WatchdogTimer+1/CLKLOW. Currently all watchdog does
+is clear GPIO DDR, and OpenDrain registers setting all GPIO to
+inputs (high with pullups)
+
+0x0D00 WatchDogStatus
+
+Bit 0 = Watchdog has bitten status (1 = you been bit)
+
+0x0E00
+
+Watchdog Cookie location
+
+0x5A written to 8 MSbs will reset watchdog to previously written
+timeout value.
+
+
+0x1000 I/O port 0..23
+0x1004 I/O port 24..47
+0x1008 I/O port 48..71
+0x100C I/O port 72..95
+0x1010 I/O port 96..127
+
+Writes write to output register, reads read pin status
+
+0x1100 DDR for I/O port 0..23
+0x1104 DDR for I/O port 24..47
+0x1108 DDR for I/O port 48..71
+0x110C DDR for I/O port 72..95
+
+'1' bit in DDR register makes corresponding GPIO bit an output
+
+0x1200 AltSourceReg for I/O port 0..23
+0x1204 AltSourceReg for I/O port 24..47
+0x1208 AltSourceReg for I/O port 48..71
+0x120C AltSourceReg for I/O port 72..95
+
+'1' bit in AltSource register makes corresponding GPIO bit data source
+come from Alternate source for that bit instead of output register.
+
+0x1300 OpenDrainSelect for I/O port 0..23
+0x1304 OpenDrainSelect for I/O port 24..47
+0x1308 OpenDrainSelect for I/O port 48..71
+0x130C OpenDrainSelect for I/O port 72..95
+
+'1' bit in OpenDrainSelect register makes corresponding GPIO an
+open drain output.
+If OpenDrain is selected for an I/O bit , the DDR register is ignored.
+
+0x1400 OutputInvert for I/O port 0..23
+0x1404 OutputInvert for I/O port 24..47
+0x1408 OutputInvert for I/O port 48..71
+0x140C OutputInvert for I/O port 72..95
+
+A '1' bit in the OutputInv register inverts the cooresponding output bit.
+This may be the output register bit or alternate source. The input is not
+inverted.
+
+
+**************************************************
+Step/dir generators currently 48 bit accum = 16 bits full step,
+32 fractional step/rate
+
+ Step rate registers : Write only
+
+0x2000 32 bit rate register for StepGen 0
+0x2004 32 bit rate register for StepGen 1
+0x2008 32 bit rate register for StepGen 2
+0x200C 32 bit rate register for StepGen 3
+0x2010 32 bit rate register for StepGen 4
+0x2014 32 bit rate register for StepGen 5
+0x2018 32 bit rate register for StepGen 6
+0x201C 32 bit rate register for StepGen 7
+...
+
+ 32 bit top of accumulator = 16.16 fullstep.fractionalstep : Read/write
+
+0x2100 32 bit full.fractional accum for StepGen 0
+0x2104 32 bit full.fractional accum for StepGen 1
+0x2108 32 bit full.fractional accum for StepGen 2
+0x210C 32 bit full.fractional accum for StepGen 3
+0x2110 32 bit full.fractional accum for StepGen 4
+0x2114 32 bit full.fractional accum for StepGen 5
+0x2118 32 bit full.fractional accum for StepGen 6
+0x211C 32 bit full.fractional accum for StepGen 7
+...
+
+Mode registers (2 bits Write only)
+00 = Step/Dir
+01 = Up/Down
+10 = Quadrature
+11 = Table Driven
+
+0x2200 2 bit mode register for StepGen 0
+0x2204 2 bit mode register for StepGen 1
+0x2208 2 bit mode register for StepGen 2
+0x220C 2 bit mode register for StepGen 3
+0x2210 2 bit mode register for StepGen 4
+0x2214 2 bit mode register for StepGen 5
+0x2218 2 bit mode register for StepGen 6
+0x221C 2 bit mode register for StepGen 7
+...
+
+DIR Setup time = how long DIR must be valid before step pulses may be issued
+Max time for 14 bits at ClockLow = 33 MHz = ~480 uS.
+At ClockLow = 50 MHz = ~320 uS
+
+Write only
+
+0x2300 14 bit DIR setup time register for StepGen 0
+0x2304 14 bit DIR setup time register for StepGen 1
+0x2308 14 bit DIR setup time register for StepGen 2
+0x230C 14 bit DIR setup time register for StepGen 3
+0x2310 14 bit DIR setup time register for StepGen 4
+0x2314 14 bit DIR setup time register for StepGen 5
+0x2318 14 bit DIR setup time register for StepGen 6
+0x231C 14 bit DIR setup time register for StepGen 7
+...
+
+DIR Hold time = how long DIR most remain valid after a step pulse has
+been issued
+Max time for 14 bits at ClockLow = 33 MHz = ~480 mS.
+At ClockLow = 50 MHz = ~320 mS
+
+Write only
+
+0x2400 14 bit DIR hold time register for StepGen 0
+0x2404 14 bit DIR hold time register for StepGen 1
+0x2408 14 bit DIR hold time register for StepGen 2
+0x240C 14 bit DIR hold time register for StepGen 3
+0x2410 14 bit DIR hold time register for StepGen 4
+0x2414 14 bit DIR hold time register for StepGen 5
+0x2418 14 bit DIR hold time register for StepGen 6
+0x241C 14 bit DIR hold time register for StepGen 7
+...
+
+Pulse length = Active time of output pulse.
+Max time for 14 bits at ClockLow = 33 MHz = ~480 uS.
+At ClockLow = 50 MHz = ~320 uS
+
+Write only
+
+0x2500 14 bit pulse width register for StepGen 0
+0x2504 14 bit pulse width register for StepGen 1
+0x2508 14 bit pulse width register for StepGen 2
+0x250C 14 bit pulse width register for StepGen 3
+0x2510 14 bit pulse width register for StepGen 4
+0x2514 14 bit pulse width register for StepGen 5
+0x2518 14 bit pulse width register for StepGen 6
+0x251C 14 bit pulse width register for StepGen 7
+...
+
+Pulse Idle = Inactive time of output pulse.
+Max time for 14 bits at ClockLow = 33 MHz = ~480 uS.
+At ClockLow = 50 MHz = ~320 uS
+
+Write only
+
+0x2600 14 bit pulse idle width register for StepGen 0
+0x2604 14 bit pulse idle width register for StepGen 1
+0x2608 14 bit pulse idle width register for StepGen 2
+0x260C 14 bit pulse idle width register for StepGen 3
+0x2610 14 bit pulse idle width register for StepGen 4
+0x2614 14 bit pulse idle width register for StepGen 5
+0x2618 14 bit pulse idle width register for StepGen 6
+0x261C 14 bit pulse idle width register for StepGen 7
+...
+
+Output sequence table. This is a single write location where the
+table sequence data for table driven step generator output is stored.
+Data is written sequentially here from last to first data word in the
+sequence. Default table width is 6 bits.
+Table data is in LSBs of written word.
+
+0x2700 Table sequence data setup register for StepGen 0
+0x2704 Table sequence data setup register for StepGen 1
+0x2708 Table sequence data setup register for StepGen 2
+0x270C Table sequence data setup register for StepGen 3
+0x2710 Table sequence data setup register for StepGen 4
+0x2714 Table sequence data setup register for StepGen 5
+0x2718 Table sequence data setup register for StepGen 6
+0x271c Table sequence data setup register for StepGen 7
+...
+
+TableLength register: 4 bit register that determines table sequence
+length. Sequence length is TableLength+1, Maximum length is 16 steps
+
+
+0x2800 Table sequence length register for StepGen 0
+0x2804 Table sequence length register for StepGen 1
+0x2808 Table sequence length register for StepGen 2
+0x280C Table sequence length register for StepGen 3
+0x2810 Table sequence length register for StepGen 4
+0x2814 Table sequence length register for StepGen 5
+0x2818 Table sequence length register for StepGen 6
+x281c Table sequence length register for StepGen 7
+
+...
+
+0x2900 32 bit master DDS for all stepgens (compile time option,
+may be disabled)
+
+Step generator addition rate is (ClockLow*MasterDDSVal/2^32)
+
+Probably just set to 0xffffffff for playing with
+
+QuadratureCounter Type 2 (with timestamp)
+32 bit register: bottom 16 bits are count,
+top 16 bits are timestamp of last change
+Writes to counter register clear the counter.
+
+0x3000 quad counter 0
+0x3004 quad counter 1
+0x3008 quad counter 2
+0x300C quad counter 3
+0x3010 quad counter 4
+0x3014 quad counter 5
+0x3018 quad counter 6
+0x301c quad counter 7
+...
+
+QuadratureCounter latch/Control register
+32 bit register: top 16 bits are latched (by index) count,
+bottom 16 bits is control register
+
+0x3100 quad counter latch/CCR 0
+0x3104 quad counter latch/CCR 1
+0x3108 quad counter latch/CCR 2
+0x310C quad counter latch/CCR 3
+0x3110 quad counter latch/CCR 4
+0x3114 quad counter latch/CCR 5
+0x3118 quad counter latch/CCR 6
+0x311c quad counter latch/CCR 7
+...
+
+Bit 31..16 = Latched count (Latch on index)
+
+Bit15 Quad Error: set if quadrature sequence error
+Bit14 AB mask polarity: A*B must be high for index gate
+Bit13 xx
+Bit12 xx
+Bit11 Quad filter (0=3 clocks 1=15 clocks)
+Bit10 CounterMode 0 = Quadrature, 1 = up/down
+Bit9 UseIndexMask 1= use mask
+Bit8 IndexMask Polarity 1=active high
+Bit7 ABgateIndex 1=gate index signal with A,B
+Bit6 JustOnce 1= ClearOnIndex or LatchOnIndex happen only once
+Bit5 ClearOnIndex 1=Clear count on index
+Bit4 LatchOnIndex 1=Latch count on index
+Bit3 IndexPol 1 = active high
+Bit2 read = realtime index signal
+Bit1 read only realtime B signal
+Bit0 read only realtime A signal
+
+0x3200 TSSDiv 16 bit time stamp programmable divider (in LSBs) (R\W)
+
+Sets quadrature counter reference clock for timestamp.
+
+Timestamp count rate is ClockLow/(TSDiv+2).
+Any divisor with MSB set = divide by 1
+
+0x3300 TSCount 16 bit time stamp counter (read only)
+
+PWM generators (With FPGA compile time constant PWM width = 13)
+
+0x4000 PWMVal 0 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31
+0x4004 PWMVal 1 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31
+0x4008 PWMVal 2 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31
+0x400C PWMVal 3 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31
+0x4010 PWMVal 4 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31
+0x4014 PWMVal 5 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31
+0x4018 PWMVal 6 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31
+0x401C PWMVal 7 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31
+...
+
+PWM mode registers 6 bits
+
+Bit 1,0 = width select (With FPGA compile time constant PWM width = 13)
+00 = 9 bit PWM
+01 = 10 bit PWM
+10 = 11 bit PWM
+11 = 12 bit PWM
+
+Bit 2 = PWM mode select
+0 = Straight (Sawtooth) PWM
+1 = Symmetrical (Triangle) PWM
+
+Bit 4,3 = PWM output mode select
+00 = Normal Sign Magnitude PWM&DIR outputs normal
+01 = Normal Sign Magnitude PWM&DIR outputs swapped (for locked antiphase)
+10 = Up/down mode
+11 = PDM mode (12 bits)
+
+Bit 5 = Double Buffered mode
+When bit 5 is set, the PWMval register is not updated until the beginning of a
+PWM cycle, avoiding extra transitions in the output PWM waveform. This adds
+an extra delay of 0 to PWMWidth/PWMClock (normal mode) or PWMWidth*2/PWMClock
+(Symmetrical mode) between when the host writes the PWMVal register and the
+PWM output is updated.
+
+
+0x4100 PWM mode select register 0
+0x4104 PWM mode select register 1
+0x4108 PWM mode select register 2
+0x410C PWM mode select register 3
+0x4110 PWM mode select register 4
+0x4114 PWM mode select register 5
+0x4118 PWM mode select register 6
+0x411C PWM mode select register 7
+...
+
+0x4200 16 bit PWM gen master rate DDS (PWMCLOCK = CLKHIGH*Rate/65536)
+ PWM rate will be PWMCLOCK/(2^PWMBITS) for normal and interleaved PWM
+ and PWMCLOCK/(2^(PWMBITS+1)) for symmetrical mode PWM.
+
+0x4300 16 bit PDM gen master rate DDS (PDMCLOCK = CLKHIGH*Rate/65536)
+ PDM rate will be PDMCLOCK/(4096).
+
+0x4400 Enable register for PWM. Doesn't actually change PWM but is used for
+ enabling PWM driven devices (the ENA pin). 1 bit per PWM channel.
+ Active high --> '1' means enabled = '0' output pin level.
+
+Bit 0 PWM channel 0 enable
+Bit 1 PWM channel 1 enable
+Bit 2 PWM channel 2 enable
+
+PWM/PDM Notes:
+
+1. For 7I33 and 7I33T that filter the PWM to generate analog voltages, PDM
+ mode should be used. Optimum PDM rate for best trade-off between ripple
+ and linearity for 7I33 and 7I33T is about 6 MHz (PDM rate register approx 0x0fff)
+
+2. Double buffering should be used where the PWM directly drives an HBridge.
+ Double buffering prevents extra transitions on the PWM output which waste
+ power in switching losses. Double buffering should _not_ be used with PDM
+ output!
+
+
+SPI SREG 32 bits
+
+Writes here load shift register and start frame transmission
+
+0x4200 SPI SREG 0
+0x4204 SPI SREG 1
+0x4208 SPI SREG 2
+0x420C SPI SREG 3
+0x4210 SPI SREG 4
+0x4214 SPI SREG 5
+...
+
+SPI bit count register
+
+Bits 0..5 = bits per SPI frame (bits = N+1) ie 0x1f = 32 bit frame
+Bit 6 = CPOL = Clock polarity ( FreeScale SPI spec compatible definitions)
+Bit 7 = CPHA = Clock Phase
+Bit 31 = DAV = data ready
+Bit 30 = Busy
+
+0x4300 SPI bit count register 0
+0x4304 SPI bit count register 1
+0x4308 SPI bit count register 2
+0x430C SPI bit count register 3
+0x4310 SPI bit count register 4
+0x4314 SPI bit count register 5
+...
+SPI bit rate register
+
+Bits 0..7 = programmable divider, SPI bit rate is (N+1)*2
+Maximum rate (N=0) is 24 MHz (5I22 with 48 MHz clock) or 16.66 (5I20 with 33
+MHz clock
+Minmum rate (N=255) is 93.75 KHz (48 MHz clock) or ~65 KHz (33 MHz clock)
+
+0x4400 SPI bit rate register 0
+0x4404 SPI bit rate register 1
+0x4408 SPI bit rate register 2
+0x440C SPI bit rate register 3
+0x4410 SPI bit rate register 4
+0x4414 SPI bit rate register 5
+...
+
+UART TX data register
+Different offsets push different numbers of bytes on xmit FIFO
+Didn't use byte enables for compatibility with other (non PCI) 32 bit interfaces
+
+0x4500 UART TXdata 0 (push 1 byte)
+0x4504 UART TXData 0 (push 2 bytes)
+0x4508 UART TXData 0 (push 3 bytes)
+0x450C UART TXData 0 (push 4 bytes)
+0x4510 UART TXdata 1 (push 1 byte)
+0x4514 UART TXData 1 (push 2 bytes)
+0x4518 UART TXData 1 (push 3 bytes)
+0x451C UART TXData 1 (push 4 bytes)
+0x4520 UART TXdata 2 (push 1 byte)
+0x4524 UART TXData 2 (push 2 bytes)
+0x4528 UART TXData 2 (push 3 bytes)
+0x452C UART TXData 2 (push 4 bytes)
+0x4530 UART TXdata 3 (push 1 byte)
+0x4534 UART TXData 3 (push 2 bytes)
+0x4538 UART TXData 3 (push 3 bytes)
+0x453C UART TXData 3 (push 4 bytes)
+...
+
+UART TX FIFO count register = number slots used in FIFO,
+pushes less than one 32 bit word use a hole word slot, in other words,
+TX FIFO is 16 32 bit words deep, but 16 one byte pushes will fill,
+so TX FIFO capacity is 16 Bytes for byte pushes, but 64 bytes with
+16 doubleword pushes.
+Writes to the FIFO count register clear the FIFO.
+
+0x4600 UART TXFIFO Count 0
+0x4604 UART TXFIFO Count 1
+0x4608 UART TXFIFO Count 2
+0x460C UART TXFIFO Count 3
+...
+
+TX Bitrate select register. TX bitrate is generated by a 16 bit
+phase accumulator. Bitrate is: TXBitrate/65536*ClockLow
+
+0x4700 UART TX Bitrate Register 0
+0x4704 UART TX Bitrate Register 1
+0x4708 UART TX Bitrate Register 2
+0x470C UART TX Bitrate Register 3
+...
+
+UART TX mode register controls TXEnable and TXEnable timing (for half duplex)
+
+Bit 0..3 are TXEnable delay. TXEnable delay specifies the transmit data
+holdoff time from the TXenable signal valid state. This is used for RS-485
+(half duplex) operaton, to delay transmit data until the driver is enabled,
+allowing for driver enable delays, isolation barrier delays etc.
+Delay is in units of ClockLow period.
+Bit 4 is DriveEnableAuto, When set, enables Drive when any data is in FIFO or
+Xmit Shift register,removes drive when FIFO and Xmit shift register are empty.
+Bit 5 is DriveEnableBit, If DriveEnableAuto is 0, controls Drive (
+for software control of Xmit drive)
+
+0x4800 UART TX Mode register 0
+0x4804 UART TX Mode register 1
+0x4808 UART TX Mode register 2
+0x480c UART TX Mode register 3
+...
+
+UART RX Data register, Different offsets pop different numbers of bytes
+from RX FIFO, data is always right justified. FIFO depth is 16 bytes.
+I may eventually change this to use byte enables.
+
+0x4900 UART RX Data 0 (POP 1 byte)
+0x4904 UART RX Data 0 (POP 2 bytes)
+0x4908 UART RX Data 0 (POP 3 bytes)
+0x490C UART RX Data 0 (POP 4 bytes)
+0x4910 UART RX Data 1 (POP 1 byte)
+0x4914 UART RX Data 1 (POP 2 bytes)
+0x4918 UART RX Data 1 (POP 3 bytes)
+0x491C UART RX Data 1 (POP 4 bytes)
+0x4910 UART RX Data 2 (POP 1 byte)
+0x4914 UART RX Data 2 (POP 2 bytes)
+0x4918 UART RX Data 2 (POP 3 bytes)
+0x491C UART RX Data 2 (POP 4 bytes)
+0x4910 UART RX Data 3 (POP 1 byte)
+0x4914 UART RX Data 3 (POP 2 bytes)
+0x4918 UART RX Data 3 (POP 3 bytes)
+0x491C UART RX Data 4 (POP 4 bytes)
+...
+
+UART RX FIFO count register = number of bytes in RX FIFO
+Writes to the RX FIFO count register clear RX FIFO
+
+0x4A00 UART RXFIFO Count 0
+0x4A04 UART RXFIFO Count 1
+0x4A08 UART RXFIFO Count 2
+0x4A0C UART RXFIFO Count 3
+...
+
+UART RX Bitrate select register. RX bitrate is generated by a 16 bit
+phase accumulator.
+Bitrate is RXBitrate/65536*ClockLow
+
+0x4B00 UART RX Bitrate Register 0
+0x4B04 UART RX Bitrate Register 0
+0x4B08 UART RX Bitrate Register 0
+0x4B0C UART RX Bitrate Register 0
+...
+
+RX MODE/STATUS Register
+
+Bit 0 = FalseStart bit Status, 1 = false start bit detected
+Bit 1 = OverRun Status, 1 = overun condition detected
+Bit 2 = RXMaskEnable, 1= enable RXMask for half duplex operation,
+ 0 = ignore RXMask
+Bit 6 = RXMask, RO RXMASK status
+Bit 7 = FIFO Has Data
+
+0x4C00 UART RX Mode/Status register 0
+0x4C04 UART RX Mode/Status register 1
+0x4C08 UART RX Mode/Status register 2
+0x4C0C UART RX Mode/Status register 3
+...
+
+
+Notes:
+1. RXMaskEnable uses the transmitters TXEN as a mask to the character receive
+ logic. This is so that when 2 wire RS-485 type interfaces are used, the
+ transmit data ia not echoed back to the receiver
+
+
+Address Translation RAM (8 bit interfaces only = EPP and USB)
+The address translation RAM is used to eliminate expensive address cycles
+when addressing hardwired sequences of non-contiguous bytes.
+
+The address RAM give indirect access to all internal registers.
+
+Translation RAM, 256 deep by 16 bit wide address translation RAM
+
+0x7800 Translation RAM byte address 0
+0x7804 Translation RAM byte address 1
+...
+0x7BFC Translation RAM byte address 255
+
+Data in translation RAM is LS 16 bits (MS 16 bits are unused)
+of 32 bit word.
+Bit 15 is StrobeBit. For read sequences, the StrobeBit must be
+OR'ed with the first translation RAM address entry of a read sequence,
+for write sequences, the StrobeBit must be OR'ed with the last
+translation RAM address of the write sequence.
+
+To use address translation, there is a 256 byte window where addresses are translated:
+
+7C00 Translation region byte 0 (controlled by Translation RAM address @ 0x7800
+7C01 Translation region byte 1 (controlled by Translation RAM address @ 0x7804
+...
+7CFF Translation region byte 255 (controlled by Translation RAM address @ 0x7BFC
+
+
+Here is an example of using address translation to write one 24 bit I/O port,
+read the next 24 bit I/O port and read and 4 quadrature counters,
+skipping the timestamp, and update 4 PWM generators.
+
+First initialize the translation RAM (Only done once at program startup)
+
+write32 0x7800 0x1000 First byte of port write
+write32 0x7804 0x1001 Second byte of port write
+write32 0x7808 0x9002 Third byte of port write (Note: OR'ed with StrobeBit)
+write32 0x780C 0x9004 First byte of read (Note OR'ed with StrobeBit)
+write32 0x7810 0x1005 Second byte of read
+write32 0x7814 0x1006 Third byte of read
+write32 0x7818 0xB000 First byte of Qcounter0 (Note: OR'ed with StrobeBit)
+write32 0x781C 0x3001 Second byte of Qcounter0
+write32 0x7820 0xB004 First byte of Qcounter1 (Note: OR'ed with StrobeBit)
+write32 0x7824 0x3005 Second byte of Qcounter1
+write32 0x7828 0xB008 First byte of Qcounter2 (Note: OR'ed with StrobeBit)
+write32 0x782C 0x3009 Second byte of Qcounter2
+write32 0x7830 0xB00C First byte of Qcounter3 (Note: OR'ed with StrobeBit)
+write32 0x7834 0x300D Second byte of Qcounter3
+write32 0x7838 0x4002 First byte of PWMGen0 (in MS word)
+write32 0x783C 0xC003 Second byte of PWMGen0 (in MS word) (Note: OR'ed with StrobeBit)
+write32 0x7838 0x4004 First byte of PWMGen1 (in MS word)
+write32 0x783C 0xC005 Second byte of PWMGen1 (in MS word) (Note: OR'ed with StrobeBit)
+write32 0x7838 0x4008 First byte of PWMGen2 (in MS word)
+write32 0x783C 0xC009 Second byte of PWMGen2 (in MS word) (Note: OR'ed with StrobeBit)
+write32 0x7838 0x400C First byte of PWMGen3 (in MS word)
+write32 0x783C 0xC00D Second byte of PWMGen3 (in MS word) (Note: OR'ed with StrobeBit)
+
+Once these 22 address translation table entries are initialized, the following sequence of
+EPP operations will do all the data transfers:
+
+writeaddr 0x00
+writeaddr 0xFC This sets up the 16 bit EPP address as 0xFC00
+ = translation region (0x7C00) with auto-inc (0x8000)
+
+writedata write port 0 Byte 0
+writedata write port 0 Byte 1
+writedata write port 0 Byte 2
+readdata read Port 1 byte 0
+readdata read Port 1 byte 1
+readdata read Port 1 byte 2
+readdata read Qcounter 0 byte 0
+readdata read Qcounter 0 byte 1
+readdata read Qcounter 1 byte 0
+readdata read Qcounter 1 byte 1
+readdata read Qcounter 2 byte 0
+readdata read Qcounter 2 byte 1
+readdata read Qcounter 3 byte 0
+readdata read Qcounter 3 byte 1
+writedata write PWMVal 0 byte 0
+writedata write PWMVal 0 byte 1
+writedata write PWMVal 1 byte 0
+writedata write PWMVal 1 byte 1
+writedata write PWMVal 2 byte 0
+writedata write PWMVal 2 byte 1
+writedata write PWMVal 3 byte 0
+writedata write PWMVal 3 byte 1
+
+Notes: For compatibility reasons, basic register access is still 32 bits even with address
+translation so a 32 bit write is always done even if only a single byte is written. This is
+usually not important, but does have some subtle side effects. For example if a 24 bit wide I/O
+port is defined with 16 input bits and 8 output bits (say to interface with a 7I37), the 8 output
+bits can be updated in a single byte write thats part of a sequence in the translation RAM.
+The side effect of this is that the 16 unused output bits that coorespond to the input bits on
+the port _will_ be written with random data.
+
+
diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/7i43.ucf b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/7i43.ucf new file mode 100644 index 000000000..01937d6d7 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/7i43.ucf @@ -0,0 +1,84 @@ +#NET "INIT" LOC = "p58" | IOSTANDARD = LVCMOS33
+#PACE: Start of Constraints generated by PACE
+#PACE: Start of PACE I/O Pin Assignments
+NET "CLK" LOC = "p53" | IOSTANDARD = LVCMOS33 ;
+NET "EPP_ASTROBE" LOC = "p80" | IOSTANDARD = LVCMOS33 | PULLUP ;
+NET "EPP_DATABUS<0>" LOC = "p68" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | KEEPER ;
+NET "EPP_DATABUS<1>" LOC = "p63" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | KEEPER ;
+NET "EPP_DATABUS<2>" LOC = "p60" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | KEEPER ;
+NET "EPP_DATABUS<3>" LOC = "p59" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | KEEPER ;
+NET "EPP_DATABUS<4>" LOC = "p51" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | KEEPER ;
+NET "EPP_DATABUS<5>" LOC = "p50" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | KEEPER ;
+NET "EPP_DATABUS<6>" LOC = "p47" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | KEEPER ;
+NET "EPP_DATABUS<7>" LOC = "p46" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | KEEPER ;
+NET "EPP_DSTROBE" LOC = "p79" | IOSTANDARD = LVCMOS33 | PULLUP ;
+NET "EPP_READ" LOC = "p84" | IOSTANDARD = LVCMOS33 | PULLUP ;
+NET "EPP_WAIT" LOC = "p82" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW ;
+NET "IOBITS<0>" LOC = "p127" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<10>" LOC = "p11" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<11>" LOC = "p8" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<12>" LOC = "p6" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<13>" LOC = "p4" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<14>" LOC = "p135" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<15>" LOC = "p131" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<16>" LOC = "p129" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<17>" LOC = "p124" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<18>" LOC = "p122" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<19>" LOC = "p118" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<1>" LOC = "p33" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<20>" LOC = "p98" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<21>" LOC = "p100" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<22>" LOC = "p103" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<23>" LOC = "p105" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<24>" LOC = "p128" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<25>" LOC = "p32" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<26>" LOC = "p30" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<27>" LOC = "p27" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<28>" LOC = "p25" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<29>" LOC = "p23" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<2>" LOC = "p31" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<30>" LOC = "p20" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<31>" LOC = "p17" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<32>" LOC = "p14" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<33>" LOC = "p12" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<34>" LOC = "p10" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<35>" LOC = "p7" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<36>" LOC = "p5" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<37>" LOC = "p137" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<38>" LOC = "p132" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<39>" LOC = "p130" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<3>" LOC = "p28" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<40>" LOC = "p125" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<41>" LOC = "p123" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<42>" LOC = "p119" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<43>" LOC = "p116" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<44>" LOC = "p97" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<45>" LOC = "p99" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<46>" LOC = "p102" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<47>" LOC = "p104" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<4>" LOC = "p26" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<5>" LOC = "p24" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<6>" LOC = "p21" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<7>" LOC = "p18" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<8>" LOC = "p15" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "IOBITS<9>" LOC = "p13" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW | PULLUP ;
+NET "LEDS<0>" LOC = "p96" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW ;
+NET "LEDS<1>" LOC = "p95" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW ;
+NET "LEDS<2>" LOC = "p93" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW ;
+NET "LEDS<3>" LOC = "p92" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW ;
+NET "LEDS<4>" LOC = "p90" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW ;
+NET "LEDS<5>" LOC = "p89" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW ;
+NET "LEDS<6>" LOC = "p87" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW ;
+NET "LEDS<7>" LOC = "p86" | IOSTANDARD = LVCMOS33 | DRIVE = 24 | SLEW = SLOW ;
+NET "PARACONFIG" LOC = "p40" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
+NET "RECONFIG" LOC = "p52" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
+NET "SPICLK" LOC = "p70" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
+NET "SPICS" LOC = "p78" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
+#NET "SPIIN" LOC = "p76" | IOSTANDARD = LVCMOS33 | PULLUP
+NET "SPIOUT" LOC = "p77" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
+#PACE: Start of PACE Area Constraints
+#PACE: Start of PACE Prohibit Constraints
+#PACE: End of Constraints generated by PACE
+NET "CLK" TNM_NET = "CLK";
+TIMESPEC "TS_CLK" = PERIOD "CLK" 19.5 ns HIGH 50 %;
+TIMESPEC "TS_P2P" = FROM "PADS" TO "PADS" 50 ns;
diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/IDParms.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/IDParms.vhd new file mode 100644 index 000000000..3140abb75 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/IDParms.vhd @@ -0,0 +1,836 @@ + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.std_logic_UNSIGNED.ALL; +use IEEE.std_logic_ARITH.ALL; +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +package IDROMParms is + + constant NullAddr : std_logic_vector(7 downto 0) := x"00"; + constant ReadIDAddr : std_logic_vector(7 downto 0) := x"01"; + constant LEDAddr : std_logic_vector(7 downto 0) := x"02";
+ constant LEDNumRegs : std_logic_vector(7 downto 0) := x"01"; + constant LEDMPBitMask : std_logic_vector(31 downto 0) := x"00000000"; + + constant IDROMAddr : std_logic_vector(7 downto 0) := x"04"; + constant Cookie : std_logic_vector(31 downto 0) := x"55AACAFE"; + constant HostMotNameLow : std_logic_vector(31 downto 0) := x"54534F48"; -- HOST + constant HostMotNameHigh : std_logic_vector(31 downto 0) := x"32544F4D"; -- MOT2 + + constant BoardNameMesa : std_logic_vector(31 downto 0) := x"4153454D"; -- MESA + constant BoardName4I65 : std_logic_vector(31 downto 0) := x"35364934"; -- 4I65 + constant BoardName4I68 : std_logic_vector(31 downto 0) := x"38364934"; -- 4I68 + constant BoardName5I20 : std_logic_vector(31 downto 0) := x"30324935"; -- 5I20 + constant BoardName5I22 : std_logic_vector(31 downto 0) := x"32324935"; -- 5I22 + constant BoardName5I23 : std_logic_vector(31 downto 0) := x"33324935"; -- 5I23 + constant BoardName7I43 : std_logic_vector(31 downto 0) := x"33344937"; -- 7I43 + constant BoardName7I60 : std_logic_vector(31 downto 0) := x"30364937"; -- 7I60 + + constant IDROMOffset : std_logic_vector(31 downto 0) := x"0000"&IDROMAddr&x"00"; -- note need to change if pitch changed + constant IDROMWEnAddr : std_logic_vector(7 downto 0) := x"08"; +
+ constant IRQDivAddr : std_logic_vector(7 downto 0) := x"09"; + constant IRQStatusAddr : std_logic_vector(7 downto 0) := x"0A"; + constant ClearIRQAddr : std_logic_vector(7 downto 0) := x"0B"; + constant IRQNumRegs : std_logic_vector(7 downto 0) := x"03"; + constant IRQMPBitMask : std_logic_vector(31 downto 0) := x"00000000"; + + constant WatchdogTimeAddr : std_logic_vector(7 downto 0) := x"0C"; + constant WatchDogStatusAddr : std_logic_vector(7 downto 0) := x"0D"; + constant WatchDogCookieAddr : std_logic_vector(7 downto 0) := x"0E";
+ constant WatchDogNumRegs : std_logic_vector(7 downto 0) := x"03"; + constant WatchDogMPBitMask : std_logic_vector(31 downto 0) := x"00000000"; + + constant PortAddr : std_logic_vector(7 downto 0) := x"10"; + constant DDRAddr : std_logic_vector(7 downto 0) := x"11"; + constant AltDataSrcAddr : std_logic_vector(7 downto 0) := x"12"; + constant OpenDrainModeAddr : std_logic_vector(7 downto 0) := x"13"; + constant OutputInvAddr : std_logic_vector(7 downto 0) := x"14"; + constant IOPortNumRegs : std_logic_vector(7 downto 0) := x"05"; + constant IOPortMPBitMask : std_logic_vector(31 downto 0) := x"0000001F"; + + constant StepGenRateAddr : std_logic_vector(7 downto 0) := x"20"; + constant StepGenAccumAddr : std_logic_vector(7 downto 0) := x"21"; + constant StepGenModeAddr : std_logic_vector(7 downto 0) := x"22"; + constant StepGenDSUTimeAddr : std_logic_vector(7 downto 0) := x"23"; + constant StepGenDHLDTimeAddr : std_logic_vector(7 downto 0) := x"24"; + constant StepGenPulseATimeAddr : std_logic_vector(7 downto 0) := x"25"; + constant StepGenPulseITimeAddr : std_logic_vector(7 downto 0) := x"26"; + constant StepGenTableAddr : std_logic_vector(7 downto 0) := x"27"; + constant StepGenTableMaxAddr : std_logic_vector(7 downto 0) := x"28"; + constant StepGenBasicRateAddr : std_logic_vector(7 downto 0) := x"29"; + constant StepGenNumRegs : std_logic_vector(7 downto 0) := x"0A"; + constant StepGenMPBitMask : std_logic_vector(31 downto 0) := x"000001FF"; + + constant QCounterAddr : std_logic_vector(7 downto 0) := x"30"; + constant QCounterCCRAddr : std_logic_vector(7 downto 0) := x"31"; + constant TSDivAddr : std_logic_vector(7 downto 0) := x"32"; + constant TSAddr : std_logic_vector(7 downto 0) := x"33"; + constant QCounterNumRegs : std_logic_vector(7 downto 0) := x"04"; + constant QCounterMPBitMask : std_logic_vector(31 downto 0) := x"00000003"; + + constant PWMValAddr : std_logic_vector(7 downto 0) := x"40"; + constant PWMCRAddr : std_logic_vector(7 downto 0) := x"41"; + constant PWMRateAddr : std_logic_vector(7 downto 0) := x"42"; + constant PDMRateAddr : std_logic_vector(7 downto 0) := x"43"; + constant PWMEnasAddr : std_logic_vector(7 downto 0) := x"44"; + constant PWMNumRegs : std_logic_vector(7 downto 0) := x"05"; + constant PWMMPBitMask : std_logic_vector(31 downto 0) := x"00000003"; + + constant SPIDataAddr : std_logic_vector(7 downto 0) := x"50"; + constant SPIBitCountAddr : std_logic_vector(7 downto 0) := x"51"; + constant SPIBitrateAddr : std_logic_vector(7 downto 0) := x"52"; + constant SPINumRegs : std_logic_vector(7 downto 0) := x"03"; + constant SPIMPBitMask : std_logic_vector(31 downto 0) := x"00000007"; + + constant UARTXDataAddr : std_logic_vector(7 downto 0) := x"60"; + constant UARTXFIFOCountAddr : std_logic_vector(7 downto 0) := x"61"; + constant UARTXBitrateAddr: std_logic_vector(7 downto 0) := x"62"; + constant UARTXModeRegAddr : std_logic_vector(7 downto 0) := x"63"; + constant UARTXNumRegs : std_logic_vector(7 downto 0) := x"04"; + constant UARTXMPBitMask : std_logic_vector(31 downto 0) := x"0000000F"; + + constant UARTRDataAddr : std_logic_vector(7 downto 0) := x"70"; + constant UARTRFIFOCountAddr : std_logic_vector(7 downto 0) := x"71"; + constant UARTRBitrateAddr : std_logic_vector(7 downto 0) := x"72"; + constant UARTRModeAddr : std_logic_vector(7 downto 0) := x"73"; + constant UARTRNumRegs : std_logic_vector(7 downto 0) := x"04"; + constant UARTRMPBitMask : std_logic_vector(31 downto 0) := x"0000000F"; + + constant TranslateRamAddr : std_logic_vector(7 downto 0) := x"78"; + constant TranslateRegionAddr : std_logic_vector(7 downto 0) := x"7C"; + constant TranslateNumRegs : std_logic_vector(7 downto 0) := x"04"; + constant TranslateMPBitMask : std_logic_vector(31 downto 0) := x"00000000"; + + + + constant ClockLow20: integer := 33333333; -- 5I20/4I65 low speed clock + constant ClockLow22: integer := 50000000; -- 5I22/5I23 low speed clock + constant ClockLow43: integer := 50000000; -- 7I43 low speed clock + constant ClockLow68: integer := 48000000; -- 4I68 low speed clock + + constant ClockHigh20: integer := 100000000; -- 5I20/4I65 high speed clock + constant ClockHigh22: integer := 100000000; -- 5I22/5I23 high speed clock + constant ClockHigh43: integer := 100000000; -- 7I43 high speed clock + constant ClockHigh68: integer := 96000000; -- 4I68 high speed clock + + constant ClockLowTag: std_logic_vector(7 downto 0) := x"01"; + constant ClockHighTag: std_logic_vector(7 downto 0) := x"02"; + + constant NullTag : std_logic_vector(7 downto 0) := x"00"; + constant IRQLogicTag : std_logic_vector(7 downto 0) := x"01"; + constant WatchDogTag : std_logic_vector(7 downto 0) := x"02"; + constant IOPortTag : std_logic_vector(7 downto 0) := x"03"; + constant QCountTag : std_logic_vector(7 downto 0) := x"04"; + constant StepGenTag : std_logic_vector(7 downto 0) := x"05"; + constant PWMTag : std_logic_vector(7 downto 0) := x"06"; + constant SPITag : std_logic_vector(7 downto 0) := x"07"; + constant SSITag : std_logic_vector(7 downto 0) := x"08"; + constant UARTTXTag : std_logic_vector(7 downto 0) := x"09"; + constant UARTRXTag : std_logic_vector(7 downto 0) := x"0A"; + constant AddrXTag : std_logic_vector(7 downto 0) := x"0B";
+ constant LEDTag : std_logic_vector(7 downto 0) := x"80"; + + + constant emptypin : std_logic_vector(31 downto 0) := x"00000000"; + constant empty : std_logic_vector(31 downto 0) := x"00000000"; + constant PadT : std_logic_vector(7 downto 0) := x"00"; + constant MaxModules : integer := 32; -- maximum number of module types + constant MaxPins : integer := 128; -- maximum number of I/O pins + type PinDescType is array(0 to MaxPins -1) of std_logic_vector(31 downto 0); + type ModuleRecord is + record + GTag : std_logic_vector(7 downto 0); + Version : std_logic_vector(7 downto 0); + Clock : std_logic_vector(7 downto 0); + NumInstances : std_logic_vector(7 downto 0); + BaseAddr : std_logic_vector(15 downto 0);
+ NumRegisters : std_logic_vector(7 downto 0);
+ Strides : std_logic_vector(7 downto 0); + MultRegs : std_logic_vector(31 downto 0); + end record; +-- These messy constants must remain until I make a script +-- to generate them based on configuration parameters + + + type ModuleIDType is array(0 to MaxModules-1) of ModuleRecord; + + constant ModuleID_3xi30 : ModuleIDType :=( + (WatchDogTag, x"00", ClockLowTag, x"01", WatchDogTimeAddr&PadT, WatchDogNumRegs, x"00", WatchDogMPBitMask), + (IOPortTag, x"00", ClockLowTag, x"03", PortAddr&PadT, IOPortNumRegs, x"00", IOPortMPBitMask), + (QcountTag, x"02", ClockLowTag, x"0C", QcounterAddr&PadT, QCounterNumRegs, x"00", QCounterMPBitMask), + (PWMTag, x"00", ClockHighTag, x"0C", PWMValAddr&PadT, PWMNumRegs, x"00", PWMMPBitMask), + (LEDTag, x"00", ClockLowTag, x"01", LEDAddr&PadT, LEDNumRegs, x"00", LEDMPBitMask), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000") + ); + + + + constant PinDesc_3xi30 : PinDescType :=( +-- Base func sec unit sec func sec pin + IOPortTag & x"01" & QCountTag & x"02", + IOPortTag & x"01" & QCountTag & x"01", + IOPortTag & x"00" & QCountTag & x"02", + IOPortTag & x"00" & QCountTag & x"01", + IOPortTag & x"01" & QCountTag & x"03", + IOPortTag & x"00" & QCountTag & x"03", + IOPortTag & x"01" & PWMTag & x"81", + IOPortTag & x"00" & PWMTag & x"81", + IOPortTag & x"01" & PWMTag & x"82", + IOPortTag & x"00" & PWMTag & x"82", + IOPortTag & x"01" & PWMTag & x"83", + IOPortTag & x"00" & PWMTag & x"83", + IOPortTag & x"03" & QCountTag & x"02", + IOPortTag & x"03" & QCountTag & x"01", + IOPortTag & x"02" & QCountTag & x"02", + IOPortTag & x"02" & QCountTag & x"01", + IOPortTag & x"03" & QCountTag & x"03", + IOPortTag & x"02" & QCountTag & x"03", + IOPortTag & x"03" & PWMTag & x"81", + IOPortTag & x"02" & PWMTag & x"81", + IOPortTag & x"03" & PWMTag & x"82", + IOPortTag & x"02" & PWMTag & x"82", + IOPortTag & x"03" & PWMTag & x"83", + IOPortTag & x"02" & PWMTag & x"83", + + IOPortTag & x"05" & QCountTag & x"02", + IOPortTag & x"05" & QCountTag & x"01", + IOPortTag & x"04" & QCountTag & x"02", + IOPortTag & x"04" & QCountTag & x"01", + IOPortTag & x"05" & QCountTag & x"03", + IOPortTag & x"04" & QCountTag & x"03", + IOPortTag & x"05" & PWMTag & x"81", + IOPortTag & x"04" & PWMTag & x"81", + IOPortTag & x"05" & PWMTag & x"82", + IOPortTag & x"04" & PWMTag & x"82", + IOPortTag & x"05" & PWMTag & x"83", + IOPortTag & x"04" & PWMTag & x"83", + IOPortTag & x"07" & QCountTag & x"02", + IOPortTag & x"07" & QCountTag & x"01", + IOPortTag & x"06" & QCountTag & x"02", + IOPortTag & x"06" & QCountTag & x"01", + IOPortTag & x"07" & QCountTag & x"03", + IOPortTag & x"06" & QCountTag & x"03", + IOPortTag & x"07" & PWMTag & x"81", + IOPortTag & x"06" & PWMTag & x"81", + IOPortTag & x"07" & PWMTag & x"82", + IOPortTag & x"06" & PWMTag & x"82", + IOPortTag & x"07" & PWMTag & x"83", + IOPortTag & x"06" & PWMTag & x"83", + + IOPortTag & x"09" & QCountTag & x"02", + IOPortTag & x"09" & QCountTag & x"01", + IOPortTag & x"08" & QCountTag & x"02", + IOPortTag & x"08" & QCountTag & x"01", + IOPortTag & x"09" & QCountTag & x"03", + IOPortTag & x"08" & QCountTag & x"03", + IOPortTag & x"09" & PWMTag & x"81", + IOPortTag & x"08" & PWMTag & x"81", + IOPortTag & x"09" & PWMTag & x"82", + IOPortTag & x"08" & PWMTag & x"82", + IOPortTag & x"09" & PWMTag & x"83", + IOPortTag & x"08" & PWMTag & x"83", + IOPortTag & x"0B" & QCountTag & x"02", + IOPortTag & x"0B" & QCountTag & x"01", + IOPortTag & x"0A" & QCountTag & x"02", + IOPortTag & x"0A" & QCountTag & x"01", + IOPortTag & x"0B" & QCountTag & x"03", + IOPortTag & x"0A" & QCountTag & x"03", + IOPortTag & x"0B" & PWMTag & x"81", + IOPortTag & x"0A" & PWMTag & x"81", + IOPortTag & x"0B" & PWMTag & x"82", + IOPortTag & x"0A" & PWMTag & x"82", + IOPortTag & x"0B" & PWMTag & x"83", + IOPortTag & x"0A" & PWMTag & x"83", + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin); + + constant ModuleID_SVST8_4 : ModuleIDType :=( + (WatchDogTag, x"00", ClockLowTag, x"01", WatchDogTimeAddr&PadT, WatchDogNumRegs, x"00", WatchDogMPBitMask), + (IOPortTag, x"00", ClockLowTag, x"03", PortAddr&PadT, IOPortNumRegs, x"00", IOPortMPBitMask), + (QcountTag, x"02", ClockLowTag, x"08", QcounterAddr&PadT, QCounterNumRegs, x"00", QCounterMPBitMask), + (PWMTag, x"00", ClockHighTag, x"08", PWMValAddr&PadT, PWMNumRegs, x"00", PWMMPBitMask), + (StepGenTag, x"00", ClockLowTag, x"04", StepGenRateAddr&PadT, StepGenNumRegs, x"00", StepGenMPBitMask), + (LEDTag, x"00", ClockLowTag, x"01", LEDAddr&PadT, LEDNumRegs, x"00", LEDMPBitMask), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000") + ); + + + + constant PinDesc_SVST8_4 : PinDescType :=( +-- Base func sec unit sec func sec pin + IOPortTag & x"01" & QCountTag & x"02", + IOPortTag & x"01" & QCountTag & x"01", + IOPortTag & x"00" & QCountTag & x"02", + IOPortTag & x"00" & QCountTag & x"01", + IOPortTag & x"01" & QCountTag & x"03", + IOPortTag & x"00" & QCountTag & x"03", + IOPortTag & x"01" & PWMTag & x"81", + IOPortTag & x"00" & PWMTag & x"81", + IOPortTag & x"01" & PWMTag & x"82", + IOPortTag & x"00" & PWMTag & x"82", + IOPortTag & x"01" & PWMTag & x"83", + IOPortTag & x"00" & PWMTag & x"83", + IOPortTag & x"03" & QCountTag & x"02", + IOPortTag & x"03" & QCountTag & x"01", + IOPortTag & x"02" & QCountTag & x"02", + IOPortTag & x"02" & QCountTag & x"01", + IOPortTag & x"03" & QCountTag & x"03", + IOPortTag & x"02" & QCountTag & x"03", + IOPortTag & x"03" & PWMTag & x"81", + IOPortTag & x"02" & PWMTag & x"81", + IOPortTag & x"03" & PWMTag & x"82", + IOPortTag & x"02" & PWMTag & x"82", + IOPortTag & x"03" & PWMTag & x"83", + IOPortTag & x"02" & PWMTag & x"83", + + IOPortTag & x"05" & QCountTag & x"02", + IOPortTag & x"05" & QCountTag & x"01", + IOPortTag & x"04" & QCountTag & x"02", + IOPortTag & x"04" & QCountTag & x"01", + IOPortTag & x"05" & QCountTag & x"03", + IOPortTag & x"04" & QCountTag & x"03", + IOPortTag & x"05" & PWMTag & x"81", + IOPortTag & x"04" & PWMTag & x"81", + IOPortTag & x"05" & PWMTag & x"82", + IOPortTag & x"04" & PWMTag & x"82", + IOPortTag & x"05" & PWMTag & x"83", + IOPortTag & x"04" & PWMTag & x"83", + IOPortTag & x"07" & QCountTag & x"02", + IOPortTag & x"07" & QCountTag & x"01", + IOPortTag & x"06" & QCountTag & x"02", + IOPortTag & x"06" & QCountTag & x"01", + IOPortTag & x"07" & QCountTag & x"03", + IOPortTag & x"06" & QCountTag & x"03", + IOPortTag & x"07" & PWMTag & x"81", + IOPortTag & x"06" & PWMTag & x"81", + IOPortTag & x"07" & PWMTag & x"82", + IOPortTag & x"06" & PWMTag & x"82", + IOPortTag & x"07" & PWMTag & x"83", + IOPortTag & x"06" & PWMTag & x"83", + + IOPortTag & x"00" & StepGenTag & x"81", + IOPortTag & x"00" & StepGenTag & x"82", + IOPortTag & x"00" & StepGenTag & x"83", + IOPortTag & x"00" & StepGenTag & x"84", + IOPortTag & x"00" & StepGenTag & x"85", + IOPortTag & x"00" & StepGenTag & x"86", + IOPortTag & x"01" & StepGenTag & x"81", + IOPortTag & x"01" & StepGenTag & x"82", + IOPortTag & x"01" & StepGenTag & x"83", + IOPortTag & x"01" & StepGenTag & x"84", + IOPortTag & x"01" & StepGenTag & x"85", + IOPortTag & x"01" & StepGenTag & x"86", + IOPortTag & x"02" & StepGenTag & x"81", + IOPortTag & x"02" & StepGenTag & x"82", + IOPortTag & x"02" & StepGenTag & x"83", + IOPortTag & x"02" & StepGenTag & x"84", + IOPortTag & x"02" & StepGenTag & x"85", + IOPortTag & x"02" & StepGenTag & x"86", + IOPortTag & x"03" & StepGenTag & x"81", + IOPortTag & x"03" & StepGenTag & x"82", + IOPortTag & x"03" & StepGenTag & x"83", + IOPortTag & x"03" & StepGenTag & x"84", + IOPortTag & x"03" & StepGenTag & x"85", + IOPortTag & x"03" & StepGenTag & x"86", + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin); + + constant ModuleID_SVST4_4 : ModuleIDType :=( + (WatchDogTag, x"00", ClockLowTag, x"01", WatchDogTimeAddr&PadT, WatchDogNumRegs, x"00", WatchDogMPBitMask), + (IOPortTag, x"00", ClockLowTag, x"03", PortAddr&PadT, IOPortNumRegs, x"00", IOPortMPBitMask), + (QcountTag, x"02", ClockLowTag, x"04", QcounterAddr&PadT, QCounterNumRegs, x"00", QCounterMPBitMask), + (PWMTag, x"00", ClockHighTag, x"04", PWMValAddr&PadT, PWMNumRegs, x"00", PWMMPBitMask), + (StepGenTag, x"00", ClockLowTag, x"04", StepGenRateAddr&PadT, StepGenNumRegs, x"00", StepGenMPBitMask), + (AddrXTag, x"00", ClockLowTag, x"01", TranslateRAMAddr&PadT, TranslateNumRegs, x"00", TranslateMPBitMask), + (LEDTag, x"00", ClockLowTag, x"01", LEDAddr&PadT, LEDNumRegs, x"00", LEDMPBitMask), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000") + ); + + + + constant PinDesc_SVST4_4 : PinDescType :=( +-- Base func sec unit sec func sec pin + IOPortTag & x"01" & QCountTag & x"02", + IOPortTag & x"01" & QCountTag & x"01", + IOPortTag & x"00" & QCountTag & x"02", + IOPortTag & x"00" & QCountTag & x"01", + IOPortTag & x"01" & QCountTag & x"03", + IOPortTag & x"00" & QCountTag & x"03", + IOPortTag & x"01" & PWMTag & x"81", + IOPortTag & x"00" & PWMTag & x"81", + IOPortTag & x"01" & PWMTag & x"82", + IOPortTag & x"00" & PWMTag & x"82", + IOPortTag & x"01" & PWMTag & x"83", + IOPortTag & x"00" & PWMTag & x"83", + IOPortTag & x"03" & QCountTag & x"02", + IOPortTag & x"03" & QCountTag & x"01", + IOPortTag & x"02" & QCountTag & x"02", + IOPortTag & x"02" & QCountTag & x"01", + IOPortTag & x"03" & QCountTag & x"03", + IOPortTag & x"02" & QCountTag & x"03", + IOPortTag & x"03" & PWMTag & x"81", + IOPortTag & x"02" & PWMTag & x"81", + IOPortTag & x"03" & PWMTag & x"82", + IOPortTag & x"02" & PWMTag & x"82", + IOPortTag & x"03" & PWMTag & x"83", + IOPortTag & x"02" & PWMTag & x"83", + + IOPortTag & x"00" & StepGenTag & x"81", + IOPortTag & x"00" & StepGenTag & x"82", + IOPortTag & x"00" & StepGenTag & x"83", + IOPortTag & x"00" & StepGenTag & x"84", + IOPortTag & x"00" & StepGenTag & x"85", + IOPortTag & x"00" & StepGenTag & x"86", + IOPortTag & x"01" & StepGenTag & x"81", + IOPortTag & x"01" & StepGenTag & x"82", + IOPortTag & x"01" & StepGenTag & x"83", + IOPortTag & x"01" & StepGenTag & x"84", + IOPortTag & x"01" & StepGenTag & x"85", + IOPortTag & x"01" & StepGenTag & x"86", + IOPortTag & x"02" & StepGenTag & x"81", + IOPortTag & x"02" & StepGenTag & x"82", + IOPortTag & x"02" & StepGenTag & x"83", + IOPortTag & x"02" & StepGenTag & x"84", + IOPortTag & x"02" & StepGenTag & x"85", + IOPortTag & x"02" & StepGenTag & x"86", + IOPortTag & x"03" & StepGenTag & x"81", + IOPortTag & x"03" & StepGenTag & x"82", + IOPortTag & x"03" & StepGenTag & x"83", + IOPortTag & x"03" & StepGenTag & x"84", + IOPortTag & x"03" & StepGenTag & x"85", + IOPortTag & x"03" & StepGenTag & x"86", + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin); + + + + + + constant ModuleID_4xi30 : ModuleIDType :=( + (WatchDogTag, x"00", ClockLowTag, x"01", WatchDogTimeAddr&PadT, WatchDogNumRegs, x"00", WatchDogMPBitMask), + (IOPortTag, x"00", ClockLowTag, x"03", PortAddr&PadT, IOPortNumRegs, x"00", IOPortMPBitMask), + (QcountTag, x"02", ClockLowTag, x"10", QcounterAddr&PadT, QCounterNumRegs, x"00", QCounterMPBitMask), + (PWMTag, x"00", ClockHighTag, x"10", PWMValAddr&PadT, PWMNumRegs, x"00", PWMMPBitMask), + (LEDTag, x"00", ClockLowTag, x"01", LEDAddr&PadT, LEDNumRegs, x"00", LEDMPBitMask), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000") + ); + + + constant PinDesc_4xi30 : PinDescType :=( +-- Base func sec unit sec func sec pin + IOPortTag & x"01" & QCountTag & x"02", + IOPortTag & x"01" & QCountTag & x"01", + IOPortTag & x"00" & QCountTag & x"02", + IOPortTag & x"00" & QCountTag & x"01", + IOPortTag & x"01" & QCountTag & x"03", + IOPortTag & x"00" & QCountTag & x"03", + IOPortTag & x"01" & PWMTag & x"81", + IOPortTag & x"00" & PWMTag & x"81", + IOPortTag & x"01" & PWMTag & x"82", + IOPortTag & x"00" & PWMTag & x"82", + IOPortTag & x"01" & PWMTag & x"83", + IOPortTag & x"00" & PWMTag & x"83", + IOPortTag & x"03" & QCountTag & x"02", + IOPortTag & x"03" & QCountTag & x"01", + IOPortTag & x"02" & QCountTag & x"02", + IOPortTag & x"02" & QCountTag & x"01", + IOPortTag & x"03" & QCountTag & x"03", + IOPortTag & x"02" & QCountTag & x"03", + IOPortTag & x"03" & PWMTag & x"81", + IOPortTag & x"02" & PWMTag & x"81", + IOPortTag & x"03" & PWMTag & x"82", + IOPortTag & x"02" & PWMTag & x"82", + IOPortTag & x"03" & PWMTag & x"83", + IOPortTag & x"02" & PWMTag & x"83", + + IOPortTag & x"05" & QCountTag & x"02", + IOPortTag & x"05" & QCountTag & x"01", + IOPortTag & x"04" & QCountTag & x"02", + IOPortTag & x"04" & QCountTag & x"01", + IOPortTag & x"05" & QCountTag & x"03", + IOPortTag & x"04" & QCountTag & x"03", + IOPortTag & x"05" & PWMTag & x"81", + IOPortTag & x"04" & PWMTag & x"81", + IOPortTag & x"05" & PWMTag & x"82", + IOPortTag & x"04" & PWMTag & x"82", + IOPortTag & x"05" & PWMTag & x"83", + IOPortTag & x"04" & PWMTag & x"83", + IOPortTag & x"07" & QCountTag & x"02", + IOPortTag & x"07" & QCountTag & x"01", + IOPortTag & x"06" & QCountTag & x"02", + IOPortTag & x"06" & QCountTag & x"01", + IOPortTag & x"07" & QCountTag & x"03", + IOPortTag & x"06" & QCountTag & x"03", + IOPortTag & x"07" & PWMTag & x"81", + IOPortTag & x"06" & PWMTag & x"81", + IOPortTag & x"07" & PWMTag & x"82", + IOPortTag & x"06" & PWMTag & x"82", + IOPortTag & x"07" & PWMTag & x"83", + IOPortTag & x"06" & PWMTag & x"83", + + IOPortTag & x"09" & QCountTag & x"02", + IOPortTag & x"09" & QCountTag & x"01", + IOPortTag & x"08" & QCountTag & x"02", + IOPortTag & x"08" & QCountTag & x"01", + IOPortTag & x"09" & QCountTag & x"03", + IOPortTag & x"08" & QCountTag & x"03", + IOPortTag & x"09" & PWMTag & x"81", + IOPortTag & x"08" & PWMTag & x"81", + IOPortTag & x"09" & PWMTag & x"82", + IOPortTag & x"08" & PWMTag & x"82", + IOPortTag & x"09" & PWMTag & x"83", + IOPortTag & x"08" & PWMTag & x"83", + IOPortTag & x"0B" & QCountTag & x"02", + IOPortTag & x"0B" & QCountTag & x"01", + IOPortTag & x"0A" & QCountTag & x"02", + IOPortTag & x"0A" & QCountTag & x"01", + IOPortTag & x"0B" & QCountTag & x"03", + IOPortTag & x"0A" & QCountTag & x"03", + IOPortTag & x"0B" & PWMTag & x"81", + IOPortTag & x"0A" & PWMTag & x"81", + IOPortTag & x"0B" & PWMTag & x"82", + IOPortTag & x"0A" & PWMTag & x"82", + IOPortTag & x"0B" & PWMTag & x"83", + IOPortTag & x"0A" & PWMTag & x"83", + + IOPortTag & x"0D" & QCountTag & x"02", + IOPortTag & x"0D" & QCountTag & x"01", + IOPortTag & x"0C" & QCountTag & x"02", + IOPortTag & x"0C" & QCountTag & x"01", + IOPortTag & x"0D" & QCountTag & x"03", + IOPortTag & x"0C" & QCountTag & x"03", + IOPortTag & x"0D" & PWMTag & x"81", + IOPortTag & x"0C" & PWMTag & x"81", + IOPortTag & x"0D" & PWMTag & x"82", + IOPortTag & x"0C" & PWMTag & x"82", + IOPortTag & x"0D" & PWMTag & x"83", + IOPortTag & x"0C" & PWMTag & x"83", + IOPortTag & x"0F" & QCountTag & x"02", + IOPortTag & x"0F" & QCountTag & x"01", + IOPortTag & x"0E" & QCountTag & x"02", + IOPortTag & x"0E" & QCountTag & x"01", + IOPortTag & x"0F" & QCountTag & x"03", + IOPortTag & x"0E" & QCountTag & x"03", + IOPortTag & x"0F" & PWMTag & x"81", + IOPortTag & x"0E" & PWMTag & x"81", + IOPortTag & x"0F" & PWMTag & x"82", + IOPortTag & x"0E" & PWMTag & x"82", + IOPortTag & x"0F" & PWMTag & x"83", + IOPortTag & x"0E" & PWMTag & x"83", + + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin); + + constant ModuleID_24xQCtrOnly : ModuleIDType :=( + + (WatchDogTag, x"00", ClockLowTag, x"01", WatchDogTimeAddr&PadT, WatchDogNumRegs, x"00", WatchDogMPBitMask), + (IOPortTag, x"00", ClockLowTag, x"03", PortAddr&PadT, IOPortNumRegs, x"00", IOPortMPBitMask), + (QcountTag, x"02", ClockLowTag, x"10", QcounterAddr&PadT, QCounterNumRegs, x"00", QCounterMPBitMask), + (LEDTag, x"00", ClockLowTag, x"01", LEDAddr&PadT, LEDNumRegs, x"00", LEDMPBitMask), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000"), + (NullTag, x"00", NullTag, x"00", NullAddr&PadT, x"00", x"00", x"00000000") + ); + + constant PinDesc_24xQCtrOnly : PinDescType :=( +-- Base func sec unit sec func sec pin + IOPortTag & x"00" & QCountTag & x"01", + IOPortTag & x"00" & QCountTag & x"02", + IOPortTag & x"00" & QCountTag & x"03", + IOPortTag & x"01" & QCountTag & x"01", + IOPortTag & x"01" & QCountTag & x"02", + IOPortTag & x"01" & QCountTag & x"03", + IOPortTag & x"02" & QCountTag & x"01", + IOPortTag & x"02" & QCountTag & x"02", + IOPortTag & x"02" & QCountTag & x"03", + IOPortTag & x"03" & QCountTag & x"01", + IOPortTag & x"03" & QCountTag & x"02", + IOPortTag & x"03" & QCountTag & x"03", + IOPortTag & x"04" & QCountTag & x"01", + IOPortTag & x"04" & QCountTag & x"02", + IOPortTag & x"04" & QCountTag & x"03", + IOPortTag & x"05" & QCountTag & x"01", + IOPortTag & x"05" & QCountTag & x"02", + IOPortTag & x"05" & QCountTag & x"03", + IOPortTag & x"06" & QCountTag & x"01", + IOPortTag & x"06" & QCountTag & x"02", + IOPortTag & x"06" & QCountTag & x"03", + IOPortTag & x"07" & QCountTag & x"01", + IOPortTag & x"07" & QCountTag & x"02", + IOPortTag & x"07" & QCountTag & x"03", + + IOPortTag & x"08" & QCountTag & x"01", + IOPortTag & x"08" & QCountTag & x"02", + IOPortTag & x"08" & QCountTag & x"03", + IOPortTag & x"09" & QCountTag & x"01", + IOPortTag & x"09" & QCountTag & x"02", + IOPortTag & x"09" & QCountTag & x"03", + IOPortTag & x"0A" & QCountTag & x"01", + IOPortTag & x"0A" & QCountTag & x"02", + IOPortTag & x"0A" & QCountTag & x"03", + IOPortTag & x"0B" & QCountTag & x"01", + IOPortTag & x"0B" & QCountTag & x"02", + IOPortTag & x"0B" & QCountTag & x"03", + IOPortTag & x"0C" & QCountTag & x"01", + IOPortTag & x"0C" & QCountTag & x"02", + IOPortTag & x"0C" & QCountTag & x"03", + IOPortTag & x"0D" & QCountTag & x"01", + IOPortTag & x"0D" & QCountTag & x"02", + IOPortTag & x"0D" & QCountTag & x"03", + IOPortTag & x"0E" & QCountTag & x"01", + IOPortTag & x"0E" & QCountTag & x"02", + IOPortTag & x"0E" & QCountTag & x"03", + IOPortTag & x"0F" & QCountTag & x"01", + IOPortTag & x"0F" & QCountTag & x"02", + IOPortTag & x"0F" & QCountTag & x"03", + + IOPortTag & x"10" & QCountTag & x"01", + IOPortTag & x"10" & QCountTag & x"02", + IOPortTag & x"10" & QCountTag & x"03", + IOPortTag & x"11" & QCountTag & x"01", + IOPortTag & x"11" & QCountTag & x"02", + IOPortTag & x"11" & QCountTag & x"03", + IOPortTag & x"12" & QCountTag & x"01", + IOPortTag & x"12" & QCountTag & x"02", + IOPortTag & x"12" & QCountTag & x"03", + IOPortTag & x"13" & QCountTag & x"01", + IOPortTag & x"13" & QCountTag & x"02", + IOPortTag & x"13" & QCountTag & x"03", + IOPortTag & x"14" & QCountTag & x"01", + IOPortTag & x"14" & QCountTag & x"02", + IOPortTag & x"14" & QCountTag & x"03", + IOPortTag & x"15" & QCountTag & x"01", + IOPortTag & x"15" & QCountTag & x"02", + IOPortTag & x"15" & QCountTag & x"03", + IOPortTag & x"16" & QCountTag & x"01", + IOPortTag & x"16" & QCountTag & x"02", + IOPortTag & x"16" & QCountTag & x"03", + IOPortTag & x"17" & QCountTag & x"01", + IOPortTag & x"17" & QCountTag & x"02", + IOPortTag & x"17" & QCountTag & x"03", + + + + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin, + emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin,emptypin); + + + +end package IDROMParms; +
\ No newline at end of file diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/atrans.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/atrans.vhd new file mode 100644 index 000000000..587eea016 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/atrans.vhd @@ -0,0 +1,59 @@ + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity atrans is + generic ( + width : integer; + depth: integer ); + port ( + clk : in std_logic; + wea : in std_logic; + rea : in std_logic;
+ reb : in std_logic; + adda : in std_logic_vector(depth-1 downto 0); + addb : in std_logic_vector(depth-1 downto 0); + din : in std_logic_vector(width-1 downto 0); + douta : out std_logic_vector(width-1 downto 0);
+ doutb: out std_logic_vector(width-1 downto 0) + ); +end atrans; + + architecture syn of atrans is + type ram_type is array (0 to 2**depth-1) of std_logic_vector(width-1 downto 0); + signal RAM : ram_type; + + + signal dadda : std_logic_vector(depth-1 downto 0);
+ signal daddb : std_logic_vector(depth-1 downto 0); + signal outa : std_logic_vector(width-1 downto 0); + signal outb : std_logic_vector(width-1 downto 0); + + begin + process (clk) + begin + if (clk'event and clk = '1') then + if (wea = '1') then + RAM(conv_integer(adda)) <= din; + end if; + dadda <= adda;
+ daddb <= addb; + end if; + outa <= RAM(conv_integer(dadda)); + outb <= RAM(conv_integer(daddb)); + douta <= (others => 'Z'); + if rea = '1' then + douta <= outa; + end if;
+ doutb <= (others => 'Z'); + if reb = '1' then + doutb <= outb; + end if; + + end process; + +end; + + diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/boutreg.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/boutreg.vhd new file mode 100644 index 000000000..3df51df5e --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/boutreg.vhd @@ -0,0 +1,115 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +entity boutreg is + generic ( + size : integer; + buswidth : integer; + invert : boolean + ); + port ( + clk : in std_logic; + ibus : in std_logic_vector(buswidth-1 downto 0); + obus : out std_logic_vector(buswidth-1 downto 0); + load : in std_logic; + read : in std_logic; + clear : in std_logic; + dout : out std_logic_vector(size -1 downto 0) + ); +end boutreg; + +architecture Behavioral of boutreg is +signal oreg : std_logic_vector(size -1 downto 0); + + +begin + + a_basic_out_reg: process (clk,read,oreg) + + begin + if clk'event and clk = '1' then + if load = '1' then + oreg <= ibus (size -1 downto 0); + end if; + if clear = '1' then + oreg <= (others => '0'); + end if; + end if; -- clk + obus <= (others => 'Z'); + if read = '1' then + obus(size -1 downto 0) <= oreg; + obus(buswidth -1 downto size) <= (others => '0'); + end if; + if not invert then + dout <= oreg; + else + dout <= not oreg; + end if; + end process; +end Behavioral; diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/hostmot2.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/hostmot2.vhd new file mode 100644 index 000000000..c4b2dec52 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/hostmot2.vhd @@ -0,0 +1,1406 @@ +library IEEE; +use IEEE.std_logic_1164.all; -- defines std_logic types +use IEEE.std_logic_ARITH.ALL; +use IEEE.std_logic_UNSIGNED.ALL; +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +use work.IDROMParms.all; +library UNISIM; +use UNISIM.VComponents.all; + +entity HostMot2 is + generic + ( + STEPGENs: integer; + QCOUNTERS: integer; + PWMGens: integer; + SPIs: integer; + SSIs: integer; + UARTs: integer; + PWMRefWidth: integer; + StepGenTableWidth: integer; + IDROMType: integer; + SepClocks: boolean; + OneWS: boolean; + I30Pinout: boolean; + I44pinout: boolean; + QCtrOnlyPinout: boolean; + QCtrOnlyPinoutWithIMask: boolean; + SVST8_4Pinout: boolean; + SVST4_4Pinout: boolean; + ConnsWithI30: integer; + ConnsWithI44: integer; + UseStepGenPrescaler : boolean; + UseIRQLogic: boolean; + UseWatchDog: boolean; + OffsetToModules: integer; + OffsetToPinDesc: integer; + ClockHigh: integer; + ClockLow: integer; + BoardNameLow : std_Logic_Vector(31 downto 0); + BoardNameHigh : std_Logic_Vector(31 downto 0); + FPGASize: integer; + FPGAPins: integer; + IOPorts: integer; + IOWidth: integer; + PortWidth: integer; + BusWidth: integer; + AddrWidth: integer;
+ InstStride0: integer;
+ InstStride1: integer;
+ RegStride0: integer;
+ RegStride1: integer; + LEDCount: integer + ); + port + ( + -- Generic 32 bit bus interface signals -- + + ibus: in std_logic_vector(buswidth -1 downto 0); + obus: out std_logic_vector(buswidth -1 downto 0); + addr: in std_logic_vector(addrwidth -1 downto 2); + read: in std_logic; + write: in std_logic; + clklow: in std_logic; + clkhigh: in std_logic; + int: out std_logic; + iobits: inout std_logic_vector (iowidth -1 downto 0); + leds: out std_logic_vector(ledcount-1 downto 0) + ); +end HostMot2; + +architecture dataflow of HostMot2 is + + + +-- decodes -- +-- IDROM related signals + signal A : std_logic_vector(addrwidth -1 downto 2); + signal LoadIDROM: std_logic; + signal ReadIDROM: std_logic; + + signal LoadIDROMWEn: std_logic; + signal ReadIDROMWEn: std_logic; + + signal IDROMWEn: std_logic_vector(0 downto 0); + signal ROMAdd: std_logic_vector(7 downto 0); + +-- I/O port related signals + + signal AltData : std_logic_vector(IOWidth-1 downto 0); + signal PortSel: std_logic; + signal LoadPortCmd: std_logic_vector(IOPorts -1 downto 0); + signal ReadPortCmd: std_logic_vector(IOPorts -1 downto 0); + + signal DDRSel: std_logic; + signal LoadDDRCmd: std_logic_vector(IOPorts -1 downto 0); + signal ReadDDRCmd: std_logic_vector(IOPorts -1 downto 0); + signal AltDataSrcSel: std_logic; + signal LoadAltDataSrcCmd: std_logic_vector(IOPorts -1 downto 0); + signal OpenDrainModeSel: std_logic; + signal LoadOpenDrainModeCmd: std_logic_vector(IOPorts -1 downto 0); + signal OutputInvSel: std_logic; + signal LoadOutputInvCmd: std_logic_vector(IOPorts -1 downto 0); + + +-- Step generator related signals + + signal StepGenRateSel: std_logic; + signal LoadStepGenRate: std_logic_vector(StepGens -1 downto 0); + signal ReadStepGenRate: std_logic_vector(StepGens -1 downto 0); + + signal StepGenAccumSel: std_logic; + signal LoadStepGenAccum: std_logic_vector(StepGens -1 downto 0); + signal ReadStepGenAccum: std_logic_vector(StepGens -1 downto 0); + + signal StepGenModeSel: std_logic; + signal LoadStepGenMode: std_logic_vector(StepGens -1 downto 0); + signal ReadStepGenMode: std_logic_vector(StepGens -1 downto 0); + + signal StepGenDSUTimeSel: std_logic; + signal LoadStepGenDSUTime: std_logic_vector(StepGens -1 downto 0); + signal ReadStepGenDSUTime: std_logic_vector(StepGens -1 downto 0); + + signal StepGenDHLDTimeSel: std_logic; + signal LoadStepGenDHLDTime: std_logic_vector(StepGens -1 downto 0); + signal ReadStepGenDHLDTime: std_logic_vector(StepGens -1 downto 0); + + signal StepGenPulseATimeSel: std_logic; + signal LoadStepGenPulseATime: std_logic_vector(StepGens -1 downto 0); + signal ReadStepGenPulseATime: std_logic_vector(StepGens -1 downto 0); + + signal StepGenPulseITimeSel: std_logic; + signal LoadStepGenPulseITime: std_logic_vector(StepGens -1 downto 0); + signal ReadStepGenPulseITime: std_logic_vector(StepGens -1 downto 0); + + signal StepGenTableMaxSel: std_logic; + signal LoadStepGenTableMax: std_logic_vector(StepGens -1 downto 0); + signal ReadStepGenTableMax: std_logic_vector(StepGens -1 downto 0); + + signal StepGenTableSel: std_logic; + signal LoadStepGenTable: std_logic_vector(StepGens -1 downto 0); + signal ReadStepGenTable: std_logic_vector(StepGens -1 downto 0); + + type StepGenOutType is array(StepGens-1 downto 0) of std_logic_vector(StepGenTableWidth-1 downto 0); + signal StepGenOut : StepGenOutType; + +-- Step generators master rate related signals + + signal LoadStepGenBasicRate: std_logic; + signal ReadStepGenBasicRate: std_logic; + + signal StepGenBasicRate: std_logic; + +-- Quadrature counter related signals + + signal QCounterSel : std_logic; + signal LoadQCounter: std_logic_vector(QCOUNTERs-1 downto 0); + signal ReadQCounter: std_logic_vector(QCOUNTERs-1 downto 0); + + signal QCounterCCRSel : std_logic; + signal LoadQCounterCCR: std_logic_vector(QCOUNTERs-1 downto 0); + signal ReadQCounterCCR: std_logic_vector(QCOUNTERs-1 downto 0); + +-- Quadrature counter timestamp reference counter + + signal LoadTSDiv : std_logic; + signal ReadTSDiv : std_logic; + signal ReadTS : std_logic; + + + signal TimeStampBus: std_logic_vector(15 downto 0); + + signal QuadA: std_logic_vector(QCounters-1 downto 0); + signal QuadB: std_logic_vector(QCounters-1 downto 0); + signal Index: std_logic_vector(QCounters -1 downto 0); + signal IndexMask: std_logic_vector(QCounters -1 downto 0); + +-- PWM generator related signals + signal PWMGenOutA: std_logic_vector(PWMGens -1 downto 0); + signal PWMGenOutB: std_logic_vector(PWMGens -1 downto 0); + signal PWMGenOutC: std_logic_vector(PWMGens -1 downto 0); + signal LoadPWMRate : std_logic; + signal LoadPDMRate : std_logic; + signal RefCountBus : std_logic_vector(PWMRefWidth-1 downto 0); + signal PDMRate : std_logic; + signal PWMValSel : std_logic; + signal PWMCRSel : std_logic; + signal LoadPWMVal: std_logic_vector(PWMGens -1 downto 0); + signal LoadPWMCR: std_logic_vector(PWMGens -1 downto 0); + signal LoadPWMEnas: std_logic; + signal ReadPWMEnas: std_logic; + +--- SPI interface related signals + signal SPIBitCountSel : std_logic; + signal SPIBitrateSel : std_logic; + signal SPIDataSel : std_logic; + signal LoadSPIBitCount: std_logic_vector(SPIs -1 downto 0); + signal LoadSPIBitRate: std_logic_vector(SPIs -1 downto 0); + signal LoadSPIData: std_logic_vector(SPIs -1 downto 0); + signal ReadSPIData: std_logic_vector(SPIs -1 downto 0); + signal ReadSPIBitCOunt: std_logic_vector(SPIs -1 downto 0); + signal ReadSPIBitRate: std_logic_vector(SPIs -1 downto 0); + signal SPIClk: std_logic_vector(SPIs -1 downto 0); + signal SPIIn: std_logic_vector(SPIs -1 downto 0); + signal SPIOut: std_logic_vector(SPIs -1 downto 0); + signal SPIFrame: std_logic_vector(SPIs -1 downto 0); + signal SPIDAV: std_logic_vector(SPIs -1 downto 0); + +--- UARTX interface related signals + signal UARTXDataSel : std_logic; + signal UARTXBitrateSel : std_logic; + signal UARTXFIFOCountSel : std_logic; + signal UARTXModeRegSel : std_logic; + + signal LoadUARTXData: std_logic_vector(UARTs -1 downto 0); + signal LoadUARTXBitRate: std_logic_vector(UARTs -1 downto 0); + signal LoadUARTXModeReg: std_logic_vector(UARTs -1 downto 0); + signal CLearUARTXFIFO: std_logic_vector(UARTs -1 downto 0); + signal ReadUARTXFIFOCount: std_logic_vector(UARTs -1 downto 0); + signal ReadUARTXBitrate: std_logic_vector(UARTs -1 downto 0); + signal ReadUARTXModeReg: std_logic_vector(UARTs -1 downto 0); + signal UARTXFIFOEmpty: std_logic_vector(UARTs -1 downto 0); + signal UTDrvEn: std_logic_vector(UARTs -1 downto 0); + signal UTXData: std_logic_vector(UARTs -1 downto 0); + +--- UARTR interface related signals + signal UARTRDataSel : std_logic; + signal UARTRBitrateSel : std_logic; + signal UARTRFIFOCountSel : std_logic; + signal UARTRModeSel : std_logic; + + signal LoadUARTRData: std_logic_vector(UARTs -1 downto 0); + signal LoadUARTRBitRate: std_logic_vector(UARTs -1 downto 0); + signal ReadUARTRBitrate: std_logic_vector(UARTs -1 downto 0); + signal ClearUARTRFIFO: std_logic_vector(UARTs -1 downto 0); + signal ReadUARTRFIFOCount: std_logic_vector(UARTs -1 downto 0); + signal ReadUARTRMode: std_logic_vector(UARTs -1 downto 0); + signal LoadUARTRMode: std_logic_vector(UARTs -1 downto 0); + signal UARTRFIFOHasData: std_logic_vector(UARTs -1 downto 0); + signal UTRData: std_logic_vector(UARTs -1 downto 0); + +--- Watchdog related signals + signal LoadWDTime : std_logic; + signal ReadWDTime : std_logic; + signal LoadWDStatus : std_logic; + signal ReadWDStatus : std_logic; + signal WDCookie: std_logic; + signal WDBite : std_logic; + signal WDLatchedBite : std_logic; + +--- IRQ related signals + signal LoadIRQDiv : std_logic; + signal ReadIRQDiv : std_logic; + signal LoadIRQStatus : std_logic; + signal ReadIrqStatus : std_logic; + signal ClearIRQ : std_logic; + +--- ID related signals + signal ReadID : std_logic; + +--- LED related signals + signal LoadLEDS : std_logic; + + function OneOfNdecode(width : integer;ena1 : std_logic;ena2 : std_logic; dec : std_logic_vector) return std_logic_vector is + variable result : std_logic_vector(width-1 downto 0); + begin + if ena1 = '1' and ena2 = '1' then + for i in 0 to width -1 loop + if CONV_INTEGER(dec) = i then + result(i) := '1'; + else + result(i) := '0'; + end if; + end loop; + else + result := (others => '0'); + end if; + return result; + end OneOfNDecode; + + function bitreverse(v: in std_logic_vector) -- Thanks: J. Bromley + return std_logic_vector is + variable result: std_logic_vector(v'RANGE); + alias tv: std_logic_vector(v'REVERSE_RANGE) is v; + begin + for i in tv'RANGE loop + result(i) := tv(i); + end loop; + return result; + end; + + begin + + ahosmotid : entity hostmotid + generic map ( + buswidth => BusWidth, + cookie => Cookie, + namelow => HostMotNameLow , + namehigh => HostMotNameHigh, + idromoffset => IDROMOffset + ) + port map ( + readid => ReadID, + addr => A(3 downto 2), + obus => obus + ); + + + makeoports: for i in 0 to IOPorts -1 generate + oportx: entity WordPR + generic map ( + size => PortWidth, + buswidth => BusWidth + ) + port map ( + clear => WDBite, + clk => clklow, + ibus => ibus, + obus => obus, + loadport => LoadPortCmd(i), + loadddr => LoadDDRCmd(i), + loadaltdatasrc => LoadAltDataSrcCmd(i), + loadopendrainmode => LoadOpenDrainModeCmd(i), + loadinvert => LoadOutputInvCmd(i), + readddr => ReadDDRCmd(i), + portdata => IOBits((((i+1)*PortWidth) -1) downto (i*PortWidth)), + altdata => Altdata((((i+1)*PortWidth) -1) downto (i*PortWidth)) + ); + end generate; + + makeiports: for i in 0 to IOPorts -1 generate + iportx: entity WordRB + generic map (size => PortWidth, + buswidth => BusWidth) + port map ( + obus => obus, + readport => ReadPortCmd(i), + portdata => IOBits((((i+1)*PortWidth) -1) downto (i*PortWidth)) + ); + end generate; + + makewatchdog: if UseWatchDog generate + wdogabittus: entity watchdog + generic map ( buswidth => BusWidth) + + port map ( + clk => clklow, + ibus => ibus, + obus => obus, + loadtime => LoadWDTime, + readtime => ReadWDTime, + loadstatus=> LoadWDStatus, + readstatus=> ReadWDStatus, + cookie => WDCookie, + wdbite => WDBite, + wdlatchedbite => WDLatchedBite + ); + end generate; + + makeirqlogic: if UseIRQlogic generate + somoldirqlogic: entity irqlogic + generic map( + buswidth => BusWidth, + dividerwidth => 16 + ) + port map ( + clk => clklow, + ibus => ibus, + obus => obus, + loaddiv => LoadIRQDiv, + readdiv => ReadIRQDiv, + loadstatus => LoadIRQStatus, + readstatus => ReadIrqStatus, + clear => ClearIRQ, + ratesource => RefCountBus(PWMRefWidth-1 downto PWMRefWidth-5), + int => INT); + end generate; + + makeStepGenPreScaler: if UseStepGenPreScaler generate + StepRategen : entity RateGen port map( + ibus => ibus, + obus => obus, + loadbasicrate => LoadStepGenBasicRate, + readbasicrate => ReadStepGenBasicRate, + hold => '0', + basicrate => StepGenBasicRate, + clk => clklow); + end generate; + + makestepgens: for i in 0 to StepGens-1 generate + usg: if UseStepGenPreScaler generate + stepgenx: entity stepgen + generic map ( + buswidth => BusWidth, + timersize => 14, -- = ~480 usec at 33 MHz, ~320 at 50 Mhz + asize => 48, + rsize => 32 + ) + port map ( + clk => clklow, + ibus => ibus, + obus => obus, + loadsteprate => LoadStepGenRate(i), + loadaccum => LoadStepGenAccum(i), + loadstepmode => LoadStepGenMode(i), + loaddirsetuptime => LoadStepGenDSUTime(i), + loaddirholdtime => LoadStepGenDHLDTime(i), + loadpulseactivetime => LoadStepGenPulseATime(i), + loadpulseidletime => LoadStepGenPulseITime(i), + loadtable => LoadStepGenTable(i), + loadtablemax => LoadStepGenTableMax(i), + readsteprate => ReadStepGenRate(i), + readaccum => ReadStepGenAccum(i), + readstepmode => ReadStepGenMode(i), + readdirsetuptime => ReadStepGenDSUTime(i), + readdirholdtime => ReadStepGenDHLDTime(i), + readpulseactivetime => ReadStepGenPulseATime(i), + readpulseidletime => ReadStepGenPulseITime(i), + readtable => ReadStepGenTable(i), + readtablemax => ReadStepGenTableMax(i), + basicrate => StepGenBasicRate, + hold => '0', + stout => StepGenOut(i) + ); + end generate usg; + + nusg: if not UseStepGenPreScaler generate + stepgenx: entity stepgen + generic map ( + buswidth => BusWidth, + timersize => 14, -- = ~480 usec at 33 MHz, ~320 at 50 Mhz + asize => 48, + rsize => 32 + ) + port map ( + clk => clklow, + ibus => ibus, + obus => obus, + loadsteprate => LoadStepGenRate(i), + loadaccum => LoadStepGenAccum(i), + loadstepmode => LoadStepGenMode(i), + loaddirsetuptime => LoadStepGenDSUTime(i), + loaddirholdtime => LoadStepGenDHLDTime(i), + loadpulseactivetime => LoadStepGenPulseATime(i), + loadpulseidletime => LoadStepGenPulseITime(i), + loadtable => LoadStepGenTable(i), + loadtablemax => LoadStepGenTableMax(i), + readsteprate => ReadStepGenRate(i), + readaccum => ReadStepGenAccum(i), + readstepmode => ReadStepGenMode(i), + readdirsetuptime => ReadStepGenDSUTime(i), + readdirholdtime => ReadStepGenDHLDTime(i), + readpulseactivetime => ReadStepGenPulseATime(i), + readpulseidletime => ReadStepGenPulseITime(i), + readtable => ReadStepGenTable(i), + readtablemax => ReadStepGenTableMax(i), + basicrate => '1', + hold => '0', + stout => StepGenOut(i) -- densely packed starting with I/O bit 0 + ); + end generate nusg; + + end generate makestepgens; + + makequadcounters: for i in 0 to QCounters-1 generate + qcounterx: entity qcounter + generic map ( + buswidth => BusWidth + ) + port map ( + obus => obus, + ibus => ibus, + quada => QuadA(i), + quadb => QuadB(i), + index => Index(i), + loadccr => LoadQcounterCCR(i), + readccr => ReadQcounterCCR(i), + readcount => ReadQcounter(i), + countclear => LoadQcounter(i), + timestamp => TimeStampBus, + indexmask => IndexMask(i), + clk => clklow + ); + end generate makequadcounters; + + maketimestamp: if (QCounters >0) generate + timestampx: entity timestamp + port map( + ibus => ibus(15 downto 0), + obus => obus(15 downto 0), + loadtsdiv => LoadTSDiv , + readts => ReadTS, + readtsdiv =>ReadTSDiv, + tscount => TimeStampBus, + clk => clklow + ); + end generate; + + + makepwmref: if ((PWMGens > 0) or UseIRQLogic) generate + pwmref : entity pwmrefh + generic map ( + buswidth => 16, + refwidth => PWMRefWidth -- Normally 13 for 12,11,10, and 9 bit PWM resolutions = 25KHz,50KHz,100KHz,200KHz max. Freq + ) + port map ( + clk => clklow, + hclk => clkhigh, + refcount => RefCountBus, + ibus => ibus(15 downto 0), + pdmrate => PDMRate, + pwmrateload => LoadPWMRate, + pdmrateload => LoadPDMRate + ); + end generate; + + makepwmgens : for i in 0 to PWMGens-1 generate + pwmgenx: entity pwmpdmgenh + generic map ( + buswidth => BusWidth, + refwidth => PWMRefWidth -- Normally 13 for 12,11,10, and 9 bit PWM resolutions = 25KHz,50KHz,100KHz,200KHz max. Freq + ) + port map ( + clk => clklow, + hclk => clkhigh, + refcount => RefCountBus, + ibus => ibus, + loadpwmval => LoadPWMVal(i), + pcrloadcmd => LoadPWMCR(i), + pdmrate => PDMRate, + pwmouta => PWMGenOutA(i), + pwmoutb => PWMGenOutB(i) + ); + end generate; + + makePWMEna: if (PWMGens >0) generate + PWMEnaReg : entity boutreg + generic map ( + size => PWMGens, + buswidth => BusWidth, + invert => false + ) + port map ( + clk => clklow, + ibus => ibus, + obus => obus, + load => LoadPWMEnas, + read => ReadPWMEnas, + clear => '0', + dout => PWMGenOutC + ); + + end generate; + + makespis: for i in 0 to SPIs -1 generate + aspi: entity SimpleSPI + generic map ( + buswidth => BusWidth) + port map ( + clk => clklow, + ibus => ibus, + obus => obus, + loadbitcount => LoadSPIBitCount(i), + loadbitrate => LoadSPIBitRate(i), + loaddata => LoadSPIData(i), + readdata => ReadSPIData(i), + readbitcount => ReadSPIBitCOunt(i), + readbitrate => ReadSPIBitRate(i), + spiclk => SPIClk(i), + spiin => SPIIn(i), + spiout => SPIOut(i), + spiframe => SPIFrame(i), + davout => SPIDAV(i) + ); + end generate; + + makeUARTRs: for i in 0 to UARTs -1 generate + auarrx: entity uartr + port map ( + clk => clklow, + ibus => ibus, + obus => obus, + addr => A(3 downto 2), + popfifo => LoadUARTRData(i), + loadbitrate => LoadUARTRBitRate(i), + readbitrate => ReadUARTRBitrate(i), + clrfifo => ClearUARTRFIFO(i), + readfifocount => ReadUARTRFIFOCount(i), + loadmode => LoadUARTRMode(i), + readmode => ReadUARTRMode(i), + fifohasdata => UARTRFIFOHasData(i), + rxmask => UTDrvEn(i), -- for half duplex rx mask + rxdata => UTRData(i) + ); + end generate; + + makeUARTTXs: for i in 0 to UARTs -1 generate + auartx: entity uartx + port map ( + clk => clklow, + ibus => ibus, + obus => obus, + addr => A(3 downto 2), + pushfifo => LoadUARTXData(i), + loadbitrate => LoadUARTXBitRate(i), + readbitrate => ReadUARTXBitrate(i), + clrfifo => ClearUARTXFIFO(i), + readfifocount => ReadUARTXFIFOCount(i), + loadmode => LoadUARTXModeReg(i), + readmode => ReadUARTXModeReg(i), + fifoempty => UARTXFIFOEmpty(i), + txen => '1', + drven => UTDrvEn(i), + txdata => UTXData(i) + ); + end generate; + + LEDReg : entity boutreg + generic map ( + size => LEDCount, + buswidth => LEDCount, + invert => true) + port map ( + clk => clklow, + ibus => ibus(BusWidth-1 downto BusWidth-LEDCount), + obus => obus(BusWidth-1 downto BusWidth-LEDCount), + load => LoadLEDs, + read => '0', + clear => '0', + dout => LEDS + ); + + + IDROMWP : entity boutreg + generic map ( + size => 1, + buswidth => BusWidth, + invert => false + ) + port map ( + clk => clklow, + ibus => ibus, + obus => obus, + load => LoadIDROMWEn, + read => ReadIDROMWEn, + clear => '0', + dout => IDROMWen + ); + + IDROM_3X_I30s: if I30Pinout and (ConnsWithI30 = 3) generate + IDROM : entity IDROM + generic map ( + idromtype => IDROMType, + offsettomodules => OffsetToModules, + offsettopindesc => OffsetToPinDesc, + boardnamelow => BoardNameLow, + boardnamehigh => BoardNameHigh, + fpgasize => FPGASize, + fpgapins => FPGAPins, + ioports => IOPorts, + iowidth => IOWidth, + portwidth => PortWidth, + clocklow => ClockLow, + clockhigh => ClockHigh, + inststride0 => InstStride0, + inststride1 => InstStride1, + regstride0 => RegStride0, + regstride1 => RegStride1, + pindesc => PinDesc_3xi30, + moduleid => ModuleID_3xi30) + port map ( + clk => clklow, + we => LoadIDROM, + re => ReadIDROM, + radd => addr(9 downto 2), + wadd => A(9 downto 2), + din => ibus, + dout => obus + ); + end generate; + + SVST8_4s: if SVST8_4Pinout generate + IDROM : entity IDROM + generic map ( + idromtype => IDROMType, + offsettomodules => OffsetToModules, + offsettopindesc => OffsetToPinDesc, + boardnamelow => BoardNameLow, + boardnamehigh => BoardNameHigh, + fpgasize => FPGASize, + fpgapins => FPGAPins, + ioports => IOPorts, + iowidth => IOWidth, + portwidth => PortWidth, + clocklow => ClockLow, + clockhigh => ClockHigh,
+ inststride0 => InstStride0, + inststride1 => InstStride1, + regstride0 => RegStride0, + regstride1 => RegStride1, + pindesc => PinDesc_SVST8_4, + moduleid => ModuleID_SVST8_4) + port map ( + clk => clklow, + we => LoadIDROM, + re => ReadIDROM, + radd => addr(9 downto 2), + wadd => A(9 downto 2), + din => ibus, + dout => obus + ); + end generate; + + SVST4_4s: if SVST4_4Pinout generate + IDROM : entity IDROM + generic map ( + idromtype => IDROMType, + offsettomodules => OffsetToModules, + offsettopindesc => OffsetToPinDesc, + boardnamelow => BoardNameLow, + boardnamehigh => BoardNameHigh, + fpgasize => FPGASize, + fpgapins => FPGAPins, + ioports => IOPorts, + iowidth => IOWidth, + portwidth => PortWidth, + clocklow => ClockLow, + clockhigh => ClockHigh, + inststride0 => InstStride0, + inststride1 => InstStride1, + regstride0 => RegStride0, + regstride1 => RegStride1, + pindesc => PinDesc_SVST4_4, + moduleid => ModuleID_SVST4_4) + port map ( + clk => clklow, + we => LoadIDROM, + re => ReadIDROM, + radd => addr(9 downto 2), + wadd => A(9 downto 2), + din => ibus, + dout => obus + ); + end generate; + + IDROM_24X_QCtrsOnly: if QCtrOnlyPinout and (QCOUNTERS = 24) generate + IDROM : entity IDROM + generic map ( + idromtype => IDROMType, + offsettomodules => OffsetToModules, + offsettopindesc => OffsetToPinDesc, + boardnamelow => BoardNameLow, + boardnameHigh => BoardNameHigh, + fpgasize => FPGASize, + fpgapins => FPGAPins, + ioports => IOPorts, + iowidth => IOWidth, + portwidth => PortWidth, + clocklow => ClockLow, + clockhigh => ClockHigh, + inststride0 => InstStride0, + inststride1 => InstStride1, + regstride0 => RegStride0, + regstride1 => RegStride1, + pindesc => PinDesc_24xQCtrOnly, + moduleid => ModuleID_24xQCtrOnly) + port map ( + clk => clklow, + we => LoadIDROM, + re => ReadIDROM, + radd => addr(9 downto 2), + wadd => A(9 downto 2), + din => ibus, + dout => obus + ); + end generate; + + + doi3xpinout: if I30Pinout generate + ConnectAltFuncs3X: process(PWMGenoutA,PWMGenOutB, + QuadA,QuadB,Index,IndexMask) + begin +-- Altdata <= (others => '0'); + + for i in 0 to ConnsWithI30 -1 loop + -- Note for 7I29/7I30/7I33/7I40 -- PWMGenOutA = PWM, PWMGenOutB = DIR, PWMGenOutC = ENA + QuadB(4*i+1) <= IOBits(PortWidth*i+0); + QuadA(4*i+1) <= IOBits(PortWidth*i+1); + QuadB(4*i+0) <= IOBits(PortWidth*i+2); + QuadA(4*i+0) <= IOBits(PortWidth*i+3); + Index(4*i+1) <= IOBits(PortWidth*i+4); + Index(4*i+0) <= IOBits(PortWidth*i+5); + AltData(PortWidth*i+6) <= PWMGenOutA(4*i+1); + AltData(PortWidth*i+7) <= PWMGenOutA(4*i+0); + AltData(PortWidth*i+8) <= PWMGenOutB(4*i+1); + AltData(PortWidth*i+9) <= PWMGenOutB(4*i+0); + AltData(PortWidth*i+10) <= not PWMGenOutC(4*i+1); + AltData(PortWidth*i+11) <= not PWMGenOutC(4*i+0); + QuadB(4*i+3) <= IOBits(PortWidth*i+12); + QuadA(4*i+3) <= IOBits(PortWidth*i+13); + QuadB(4*i+2) <= IOBits(PortWidth*i+14); + QuadA(4*i+2) <= IOBits(PortWidth*i+15); + Index(4*i+3) <= IOBits(PortWidth*i+16); + Index(4*i+2) <= IOBits(PortWidth*i+17); + AltData(PortWidth*i+18) <= PWMGenOutA(4*i+3); + AltData(PortWidth*i+19) <= PWMGenOutA(4*i+2); + AltData(PortWidth*i+20) <= PWMGenOutB(4*i+3); + AltData(PortWidth*i+21) <= PWMGenOutB(4*i+2); + AltData(PortWidth*i+22) <= not PWMGenOutC(4*i+3); + AltData(PortWidth*i+23) <= not PWMGenOutC(4*i+2); + + end loop; + + end process; + end generate; + + + + + doi44pinout: if I44Pinout generate + ConnectAltFuncs44: process(UTXData,UTRData) + begin + Altdata <= (others => '0'); + for i in 0 to ConnsWithI44 -1 loop + -- Note -- for 7I44 + UTRdata(8*i +0) <= IOBits(PortWidth*i+0); + UTRdata(8*i +1) <= IOBits(PortWidth*i+1); + UTRdata(8*i +2) <= IOBits(PortWidth*i+2); + UTRdata(8*i +3) <= IOBits(PortWidth*i+3); + AltData(PortWidth*i+4) <= UTXData(8*i +0); + AltData(PortWidth*i+5) <= UTDrvEn(8*i +0); + AltData(PortWidth*i+6) <= UTXData(8*i +1); + AltData(PortWidth*i+7) <= UTDrvEn(8*i +1); + AltData(PortWidth*i+8) <= UTXData(8*i +2); + AltData(PortWidth*i+9) <= UTDrvEn(8*i +2); + AltData(PortWidth*i+10) <= UTXData(8*i +3); + AltData(PortWidth*i+11) <= UTDrvEn(8*i +3); + UTRdata(8*i +4) <= IOBits(PortWidth*i+12); + UTRdata(8*i +5) <= IOBits(PortWidth*i+13); + UTRdata(8*i +6) <= IOBits(PortWidth*i+14); + UTRdata(8*i +7) <= IOBits(PortWidth*i+15); + AltData(PortWidth*i+16) <= UTXData(8*i +4); + AltData(PortWidth*i+17) <= UTDrvEn(8*i +4); + AltData(PortWidth*i+18) <= UTXData(8*i +5); + AltData(PortWidth*i+19) <= UTDrvEn(8*i +5); + AltData(PortWidth*i+20) <= UTXData(8*i +6); + AltData(PortWidth*i+21) <= UTDrvEn(8*i +6); + AltData(PortWidth*i+22) <= UTXData(8*i +7); + AltData(PortWidth*i+23) <= UTDrvEn(8*i +7); + end loop; + end process; + end generate; + + + + QctrOnlypinoutWithImaskGen: if QCtrOnlyPinoutWithIMask generate + ConnectAltFuncsQC: process(QuadA,QuadB,Index,IndexMask) + begin + for i in 0 to Qcounters-1 loop + QuadA(i) <= IOBits(4*i+0); + QuadB(i) <= IOBits(4*i+1); + Index(i) <= IOBits(4*i+2); + IndexMask(i) <= IOBits(4*i+3); + end loop; + end process; + end generate; + + QctrOnlypinoutGen: if QCtrOnlyPinout generate + ConnectAltFuncsQC: process(QuadA,QuadB,Index) + begin + for i in 0 to Qcounters-1 loop + QuadA(i) <= IOBits(3*i+0); + QuadB(i) <= IOBits(3*i+1); + Index(i) <= IOBits(3*i+2); + end loop; + end process; + end generate; + + SVSTStepGens84: if SVST8_4Pinout generate + ConnectAltFuncsQC: process(StepGenOut) + begin + for i in 0 to StepGens-1 loop + for j in 0 to StepGenTableWidth-1 loop + AltData(6*i+48+j) <= StepGenOut(i)(j); + end loop; + end loop; + end process; + end generate; + + SVSTStepGens44: if SVST4_4Pinout generate + ConnectAltFuncsQC: process(StepGenOut) + begin + for i in 0 to StepGens-1 loop + for j in 0 to StepGenTableWidth-1 loop + AltData(6*i+24+j) <= StepGenOut(i)(j); + end loop; + end loop; + end process; + end generate; + + + LooseEnds: process(A,clklow) + begin +-- DISABLECONF'Z'; -- Dont disable re-conf +-- EnableHS'1'; +-- CCS'1'; + if rising_edge(clklow) then + A <= addr; + end if; + end process; + + + + Decode: process(A) + begin + -- basic multi decodes are at 256 byte increments (64 longs) + -- first decode is 256 x 32 ID ROM + + + if (A(15 downto 10) = IDROMAddr(7 downto 2)) and Write = '1' and IDROMWEn = "1" then -- 400 Hex + LoadIDROM <= '1'; + else + LoadIDROM <= '0'; + end if; + if (A(15 downto 10) = IDROMAddr(7 downto 2)) and Read = '1' then -- + ReadIDROM <= '1'; + else + ReadIDROM <= '0'; + end if; + + if A(15 downto 8) = PortAddr then -- basic I/O port select + PortSel <= '1'; + else + PortSel <= '0'; + end if; + + if A(15 downto 8) = DDRAddr then -- DDR register select + DDRSel <= '1'; + else + DDRSel <= '0'; + end if; + + if A(15 downto 8) = AltDataSrcAddr then -- Alt data source register select + AltDataSrcSel <= '1'; + else + AltDataSrcSel <= '0'; + end if; + + if A(15 downto 8) = OpenDrainModeAddr then -- OpenDrain register select + OpendrainModeSel <= '1'; + else + OpenDrainModeSel <= '0'; + end if; + + if A(15 downto 8) = OutputInvAddr then -- IO invert register select + OutputInvSel <= '1'; + else + OutputInvSel <= '0'; + end if; + + if A(15 downto 8) = StepGenRateAddr then -- stepgen rate register select + StepGenRateSel <= '1'; + else + StepGenRateSel <= '0'; + end if; + + if A(15 downto 8) = StepGenAccumAddr then -- stepgen Accumumlator low select + StepGenAccumSel <= '1'; + else + StepGenAccumSel <= '0'; + end if; + + if A(15 downto 8) = StepGenModeAddr then -- stepgen mode register select + StepGenModeSel <= '1'; + else + StepGenModeSel <= '0'; + end if; + + if A(15 downto 8) = StepGenDSUTimeAddr then -- stepgen Dir setup time register select + StepGenDSUTimeSel <= '1'; + else + StepGenDSUTimeSel <= '0'; + end if; + + if A(15 downto 8) =StepGenDHLDTimeAddr then -- stepgen Dir hold time register select + StepGenDHLDTimeSel <= '1'; + else + StepGenDHLDTimeSel <= '0'; + end if; + + if A(15 downto 8) = StepGenPulseATimeAddr then -- stepgen pulse width register select + StepGenPulseATimeSel <= '1'; + else + StepGenPulseATimeSel <= '0'; + end if; + + if A(15 downto 8) = StepGenPulseITimeAddr then -- stepgen pulse width register select + StepGenPulseITimeSel <= '1'; + else + StepGenPulseITimeSel <= '0'; + end if; + + if A(15 downto 8) = StepGenTableAddr then -- stepgen pulse width register select + StepGenTableSel <= '1'; + else + StepGenTableSel <= '0'; + end if; + + if A(15 downto 8) = StepGenTableMaxAddr then -- stepgen pulse width register select + StepGenTableMaxSel <= '1'; + else + StepGenTableMaxSel <= '0'; + end if; + + if A(15 downto 8) = QCounterAddr then -- QCounter select + QCounterSel <= '1'; + else + QCounterSel <= '0'; + end if; + + if A(15 downto 8) = QCounterCCRAddr then -- QCounter CCR register select + QCounterCCRSel <= '1'; + else + QCounterCCRSel <= '0'; + end if; + + if A(15 downto 8) = PWMValAddr then -- PWMVal select + PWMValSel <= '1'; + else + PWMValSel <= '0'; + end if; + + if A(15 downto 8) = PWMCRAddr then -- PWM mode register select + PWMCRSel <= '1'; + else + PWMCRSel <= '0'; + end if; + + if A(15 downto 8) = SPIDataAddr then -- SPI data register select + SPIDataSel <= '1'; + else + SPIDataSel <= '0'; + end if; + + if A(15 downto 8) = SPIBitCountAddr then -- SPI bit count register select + SPIBitCountSel <= '1'; + else + SPIBitCountSel <= '0'; + end if; + + if A(15 downto 8) = SPIBitrateAddr then -- SPI bit rate register select + SPIBitrateSel <= '1'; + else + SPIBitrateSel <= '0'; + end if; + + if A(15 downto 8) = UARTXDataAddr then -- UART TX data register select + UARTXDataSel <= '1'; + else + UARTXDataSel <= '0'; + end if; + + if A(15 downto 8) = UARTXFIFOCountAddr then -- UART TX FIFO count register select + UARTXFIFOCountSel <= '1'; + else + UARTXFIFOCountSel <= '0'; + end if; + + if A(15 downto 8) = UARTXBitrateAddr then -- UART TX bit rate register select + UARTXBitrateSel <= '1'; + else + UARTXBitrateSel <= '0'; + end if; + + if A(15 downto 8) = UARTXModeRegAddr then -- UART TX bit mode register select + UARTXModeRegSel <= '1'; + else + UARTXModeRegSel <= '0'; + end if; + + + if A(15 downto 8) = UARTRDataAddr then -- UART RX data register select + UARTRDataSel <= '1'; + else + UARTRDataSel <= '0'; + end if; + + if A(15 downto 8) = UARTRFIFOCountAddr then -- UART RX FIFO count register select + UARTRFIFOCountSel <= '1'; + else + UARTRFIFOCountSel <= '0'; + end if; + + if A(15 downto 8) = UARTRBitrateAddr then -- UART RX bit rate register select + UARTRBitrateSel <= '1'; + else + UARTRBitrateSel <= '0'; + end if; + + if A(15 downto 8) = UARTRModeAddr then -- UART RX status register select + UARTRModeSel <= '1'; + else + UARTRModeSel <= '0'; + end if; + + if A(15 downto 8) = ReadIDAddr and Read = '1' then -- + ReadID <= '1'; + else + ReadID <= '0'; + end if; + + if A(15 downto 8) = WatchdogTimeAddr and Read = '1' then -- + ReadWDTime <= '1'; + else + ReadWDTime <= '0'; + end if; + if A(15 downto 8) = WatchdogTimeAddr and Write = '1' then -- + LoadWDTime <= '1'; + else + LoadWDTime <= '0'; + end if; + + if A(15 downto 8) = WatchdogStatusAddr and Read = '1' then -- + ReadWDStatus <= '1'; + else + ReadWDStatus <= '0'; + end if; + if A(15 downto 8) = WatchdogStatusAddr and Write = '1' then -- + LoadWDStatus <= '1'; + else + LoadWDStatus <= '0'; + end if; + + if A(15 downto 8) = WatchdogCookieAddr and Write = '1' then -- + WDCookie <= '1'; + else + WDCookie <= '0'; + end if; + + + if A(15 downto 8) = IRQDivAddr and Write = '1' then -- + LoadIRQDiv <= '1'; + else + LoadIRQDiv <= '0'; + end if; + + if A(15 downto 8) = IRQDivAddr and Read = '1' then -- + ReadIRQDiv <= '1'; + else + ReadIRQDiv <= '0'; + end if; + + if A(15 downto 8) = IRQStatusAddr and Write = '1' then -- + LoadIRQStatus <= '1'; + else + LoadIRQStatus <= '0'; + end if; + + if A(15 downto 8) = IRQStatusAddr and Read = '1' then -- + ReadIrqStatus <= '1'; + else + ReadIrqStatus <= '0'; + end if; + + if A(15 downto 8) = ClearIRQAddr and Write = '1' then -- + ClearIRQ <= '1'; + else + ClearIRQ <= '0'; + end if; + + if A(15 downto 8) = StepGenBasicRateAddr and Write = '1' then -- + LoadStepGenBasicRate <= '1'; + else + LoadStepGenBasicRate <= '0'; + end if; + if A(15 downto 8) = StepGenBasicRateAddr and Read = '1' then -- + ReadStepGenBasicRate <= '1'; + else + ReadStepGenBasicRate <= '0'; + end if; + + if A(15 downto 8) = TSDivAddr and Write = '1' then -- + LoadTSDiv <= '1'; + else + LoadTSDiv <= '0'; + end if; + if A(15 downto 8) = TSDivAddr and Read = '1' then -- + ReadTSDiv <= '1'; + else + ReadTSDiv <= '0'; + end if; + + if A(15 downto 8) = TSAddr and Read = '1' then -- + ReadTS <= '1'; + else + ReadTS <= '0'; + end if; + + if A(15 downto 8) = PWMRateAddr and Write = '1' then -- + LoadPWMRate <= '1'; + else + LoadPWMRate <= '0'; + end if; + + if A(15 downto 8) = PDMRateAddr and Write = '1' then -- + LoadPDMRate <= '1'; + else + LoadPDMRate <= '0'; + end if; + + if A(15 downto 8) = PWMEnasAddr and Write = '1' then -- + LoadPWMEnas <= '1'; + else + LoadPWMEnas <= '0'; + end if; + + if A(15 downto 8) = PWMEnasAddr and Read = '1' then -- + ReadPWMEnas <= '1'; + else + ReadPWMEnas <= '0'; + end if; + + + if A(15 downto 8) = IDROMWEnAddr and Write = '1' then -- + LoadIDROMWEn <= '1'; + else + LoadIDROMWEn <= '0'; + end if; + if A(15 downto 8) = IDROMWEnAddr and Read = '1' then -- + ReadIDROMWEn <= '1'; + else + ReadIDROMWEn <= '0'; + end if; + + if A(15 downto 8) = LEDAddr and Write = '1' then -- + LoadLEDs <= '1'; + else + LoadLEDs <= '0'; + end if; + + end process; + + PortDecode: process (A,Read,Write) + begin + + LoadPortCMD <= OneOfNDecode(IOPorts,PortSel,Write,A(3 downto 2)); + ReadPortCMD <= OneOfNDecode(IOPorts,PortSel,Read,A(3 downto 2)); + LoadDDRCMD <= OneOfNDecode(IOPorts,DDRSel,Write,A(3 downto 2)); + ReadDDRCMD <= OneOfNDecode(IOPorts,DDRSel,Read,A(3 downto 2)); + + LoadAltDataSrcCMD <= OneOfNDecode(IOPorts,AltDataSrcSel,Write,A(3 downto 2)); + LoadOpenDrainModeCMD <= OneOfNDecode(IOPorts,OpenDrainModeSel,Write,A(3 downto 2)); + LoadOutputInvCMD <= OneOfNDecode(IOPorts,OutputInvSel,Write,A(3 downto 2)); + + end process PortDecode; + + StepGenDecode: if (STEPGENs > 0) generate + StepGenDecodeProcess : process (A,Read,write) + begin + LoadStepGenRate <= OneOfNDecode(STEPGENs,StepGenRateSel,Write,A(5 downto 2)); + ReadStepGenRate <= OneOfNDecode(STEPGENs,StepGenRateSel,Read,A(5 downto 2)); + LoadStepGenAccum <= OneOfNDecode(STEPGENs,StepGenAccumSel,Write,A(5 downto 2)); + ReadStepGenAccum <= OneOfNDecode(STEPGENs,StepGenAccumSel,Read,A(5 downto 2)); + LoadStepGenMode <= OneOfNDecode(STEPGENs,StepGenModeSel,Write,A(5 downto 2)); + ReadStepGenMode <= OneOfNDecode(STEPGENs,StepGenModeSel,Read,A(5 downto 2)); + LoadStepGenDSUTime <= OneOfNDecode(STEPGENs,StepGenDSUTimeSel,Write,A(5 downto 2)); + ReadStepGenDSUTime <= OneOfNDecode(STEPGENs,StepGenDSUTimeSel,Read,A(5 downto 2)); + LoadStepGenDHLDTime <= OneOfNDecode(STEPGENs,StepGenDHLDTimeSel,Write,A(5 downto 2)); + ReadStepGenDHLDTime <= OneOfNDecode(STEPGENs,StepGenDHLDTimeSel,Read,A(5 downto 2)); + LoadStepGenPulseATime <= OneOfNDecode(STEPGENs,StepGenPulseATimeSel,Write,A(5 downto 2)); + ReadStepGenPulseATime <= OneOfNDecode(STEPGENs,StepGenPulseATimeSel,Read,A(5 downto 2)); + LoadStepGenPulseITime <= OneOfNDecode(STEPGENs,StepGenPulseITimeSel,Write,A(5 downto 2)); + ReadStepGenPulseITime <= OneOfNDecode(STEPGENs,StepGenPulseITimeSel,Read,A(5 downto 2)); + LoadStepGenTable <= OneOfNDecode(STEPGENs,StepGenTableSel,Write,A(5 downto 2)); + ReadStepGenTable <= OneOfNDecode(STEPGENs,StepGenTableSel,Read,A(5 downto 2)); + LoadStepGenTableMax <= OneOfNDecode(STEPGENs,StepGenTableMaxSel,Write,A(5 downto 2)); + ReadStepGenTableMax <= OneOfNDecode(STEPGENs,StepGenTableMaxSel,Read,A(5 downto 2)); + end process StepGenDecodeProcess; + end generate; + + + QCounterDecode: if (QCOUNTERs > 0) generate + QCounterDecodeProcess : process (A,Read,write) + begin + LoadQCounter <= OneOfNDecode(QCOUNTERs,QCounterSel,Write,A(6 downto 2)); + ReadQCounter <= OneOfNDecode(QCOUNTERs,QCounterSel,Read,A(6 downto 2)); + LoadQCounterCCR <= OneOfNDecode(QCOUNTERs,QCounterCCRSel,Write,A(6 downto 2)); + ReadQCounterCCR <= OneOfNDecode(QCOUNTERs,QCounterCCRSel,Read,A(6 downto 2)); + end process QCounterDecodeProcess; + end generate; + + PWMDecode: if (PWMGENs > 0) generate + PWMDecodeProcess : process (A,Read,write) + begin + LoadPWMVal <= OneOfNDecode(PWMGENs,PWMValSel,Write,A(6 downto 2)); + LoadPWMCR <= OneOfNDecode(PWMGENs, PWMCRSel,Write,A(6 downto 2)); + end process PWMDecodeProcess; + end generate; + + SPIDecode: if (SPIs > 0) generate + SPIDecodeProcess : process (A,Read,write) + begin + LoadSPIData <= OneOfNDecode(SPIs,SPIDataSel,Write,A(5 downto 2)); + ReadSPIData <= OneOfNDecode(SPIs,SPIDataSel,Read,A(5 downto 2)); + LoadSPIBitCount <= OneOfNDecode(SPIs,SPIBitCountSel,Write,A(5 downto 2)); + ReadSPIBitCount <= OneOfNDecode(SPIs,SPIBitCountSel,Read,A(5 downto 2)); + LoadSPIBitRate <= OneOfNDecode(SPIs,SPIBitRateSel,Write,A(5 downto 2)); + ReadSPIBitRate <= OneOfNDecode(SPIs,SPIBitRateSel,Read,A(5 downto 2)); + end process SPIDecodeProcess; + end generate; + + UARTDecode: if (UARTs > 0) generate + UARTDecodeProcess : process (A,Read,write) + begin + LoadUARTXData <= OneOfNDecode(UARTs,UARTXDataSel,Write,A(6 downto 4)); + LoadUARTXBitRate <= OneOfNDecode(UARTs,UARTXBitRateSel,Write,A(4 downto 2)); + ReadUARTXBitrate <= OneOfNDecode(UARTs,UARTXBitRateSel,Read,A(4 downto 2)); + LoadUARTXModeReg <= OneOfNDecode(UARTs,UARTXModeRegSel,Write,A(4 downto 2)); + ReadUARTXModeReg <= OneOfNDecode(UARTs,UARTXModeRegSel,Read,A(4 downto 2)); + ClearUARTXFIFO <= OneOfNDecode(UARTs,UARTXFIFOCountSel,Write,A(4 downto 2)); + ReadUARTXFIFOCount <= OneOfNDecode(UARTs,UARTXFIFOCountSel,Read,A(4 downto 2)); + + LoadUARTRData <= OneOfNDecode(UARTs,UARTRDataSel,Read,A(6 downto 4)); + LoadUARTRBitRate <= OneOfNDecode(UARTs,UARTRBitRateSel,Write,A(4 downto 2)); + ReadUARTRBitrate <= OneOfNDecode(UARTs,UARTRBitRateSel,Read,A(4 downto 2)); + ClearUARTRFIFO <= OneOfNDecode(UARTs,UARTRFIFOCountSel,Write,A(4 downto 2)); + ReadUARTRFIFOCount <= OneOfNDecode(UARTs,UARTRFIFOCountSel,Read,A(4 downto 2)); + LoadUARTRMode <= OneOfNDecode(UARTs,UARTRModeSel,Write,A(4 downto 2)); + ReadUARTRMode <= OneOfNDecode(UARTs,UARTRModeSel,Read,A(4 downto 2)); + end process UARTDecodeProcess; + end generate; + + + dotieupint: if not UseIRQLogic generate + tieupint : process(clklow) + begin + INT <= '1'; + end process; + end generate; + +end dataflow; + +
\ No newline at end of file diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/hostmot2_import.tcl b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/hostmot2_import.tcl new file mode 100644 index 000000000..2b2ce0ea6 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/hostmot2_import.tcl @@ -0,0 +1,1292 @@ +# ProjectNavigator SourceControl recreation script +# +# This script is text version of significant (but possibly not all) +# the information contained in the ISE project file. It is generated +# and used by the ProjectNavigator application's source control +# import feature. +# +# When using this script from the command line to recreate the ISE +# project, it should first be sourced from within an xtclsh shell. +# Next, the import procedure should be called to perform the import. +# When calling the import procedure, pass the new project directory +# and the source directory. If neither are specified, the current +# working directory is assumed for both. +# +# Internally this script has two file lists. One variable (import_files) +# has the set of files to copy into the project directory. The other +# variable (user_files) has the set of files to add into the project. +# +# +# This script is not intended for direct customer editing. +# +# Copyright 2006, Xilinx, Inc. +# + + +# Helper to copy files from the source staging area +# back into the destination work area. +# This proc will be call for each file copied. +# While not supported, one could do interesting things with this +# proc, since each file hits it. +proc CopyIn { srcfile work_area copy_option } { + set staging_area [pwd] + if { [ expr { [ file pathtype $srcfile ] == "absolute" || \ + [string index $srcfile 0 ] == "/" || \ + [string index $srcfile 1 ] == ":" } ] } { + set workfile $srcfile + } else { + set workfile [ file join $work_area $srcfile ] + } + if { $copy_option == "flatten" } { + set stagefile [ file join $staging_area [ file tail $srcfile ] ] + } elseif { [ file pathtype $srcfile ] != "relative" } { + set srcfile [ string map {: _} $srcfile ] + set stagefile [ file join $staging_area absolute $srcfile ] + } elseif { [ expr { $copy_option == "absremote" } && { [string equal -length 2 $srcfile ".." ] } ] } { + set stagefile [ file join $staging_area outside_relative [ string map {.. up} $srcfile ] ] + } else { + set srcfile [ string map {: _} $srcfile ] + set stagefile [ file join $staging_area $srcfile ] + } + + set stagefile [ file normalize $stagefile ] + set workfile [ file normalize $workfile ] + + if { [ file exists $stagefile ] } { + if { $stagefile != $workfile } { + file mkdir [ file dirname $workfile ] + file copy -force $stagefile $workfile + } + } else { WARN "\"$stagefile\" does not exist for import copy." } +} + +proc ERR { msg } { + puts "ERROR: $msg" +} + +proc WARN { msg } { + puts "WARNING: $msg" +} + +proc INFO { msg } { + puts "$msg" +} + +# Helper that returns 1 if the string is blank, otherwise 0. +proc IsBlank { str } { + if { [string length $str] == 0 } { + return 1 + } + return 0 +} + +# Helper for determining whether a value is 'NULL'. +# Returns 1 if the value is 0; returns 0 if the value is anything else. +proc IsNull { val } { + if { $val == 0 } { + return 1 + } + return 0 +} + +proc HandleException { script { msg "" } } { + set catch_result [catch { + uplevel 1 $script + } RESULT] + if {$catch_result} { + if {![IsBlank $msg]} { + ERR $msg + } + INFO "$RESULT" + INFO "$::errorInfo" + } +} + +# These two procs help to load shared libraries in a platform +# independent way. +proc _LoadLibrary {name} { + set libExt [info sharedlibextension] + set libFullName "$name$libExt" + HandleException { + load $libFullName + } "A problem occured loading library $libFullName." +} + +proc _LoadFactoryLibrary {Factory} { + HandleException { + Xilinx::Cit::FactoryLoad $Factory + } "A problem occured loading library $Factory." +} + +_LoadLibrary libCit_CoreStub +_LoadLibrary libPrjrep_CommonStub +_LoadFactoryLibrary libPrjrep_Common +_LoadLibrary libDpm_SupportStub +_LoadLibrary libDpm_PnfStub +_LoadLibrary libDpm_DefnDataStub +_LoadLibrary libDpm_DesignDataStub +_LoadLibrary libDpm_HdlStub +_LoadLibrary libPrjrep_RepositoryStub +_LoadLibrary libCitI_CoreStub +_LoadLibrary libHdcI_HdcHDProjectStub +_LoadLibrary libTcltaskI_TaskStub +_LoadLibrary libCommonI_CommonStub +_LoadFactoryLibrary libTcltask_Helpers +_LoadFactoryLibrary libHdcC_HDProject +_LoadLibrary libHdcI_HdcContainerStub + +# Helper to exectute code only when the (pointer) variable name is valid. +proc OnOkPtr { var_name script } { + if { [ uplevel info exists $var_name ] } { + upvar $var_name var + if { $var != 0 } { return [ uplevel $script ] } + } +} + +# Helper to exectute code only when the (pointer) variable name is 0. +proc OnNullPtr { var_name script } { + if { [ uplevel info exists $var_name ] } { + upvar $var_name var + if { $var == 0 } { return [ uplevel $script ] } + } +} + +# Helper to exectute code only when the value of variable name is 1. +proc OnSuccess { var_name script } { + if { $val != 0 } { return [ uplevel $script ] } +} + +# Helper to exectute code only when the value of variable name is 0. +proc OnFail { val script } { + if { $val != 1 } { return [ uplevel $script ] } +} + +# Helper to get a component interface. +proc GetInterface { iUnk id { name "" } } { + if {$iUnk == 0} { return 0 } + set iIface [ $iUnk GetInterface $id ] + OnNullPtr iIface { + if {![IsBlank $name]} { + ERR " Could not get the \"$name\" interface." + } + } + return $iIface +} + +# Helper to create a component and return one of its interfaces. +proc CreateComponent { compId ifaceId { name "" } } { + set iUnk [ ::Xilinx::Cit::FactoryCreate $compId ] + set iIface [ GetInterface $iUnk $ifaceId ] + OnNullPtr iIface { + if {![IsBlank $name]} { ERR "Could not create a \"$name\" component." } + } + return $iIface +} + +# Helper to release an object +proc Release { args } { + foreach iUnk $args { + set i_refcount [ GetInterface $iUnk $::xilinx::Prjrep::IRefCountID ] + OnNullPtr i_refcount { set i_refcount [ GetInterface $iUnk $::xilinx::CommonI::IRefCountID ] } + OnOkPtr i_refcount { $i_refcount Release } + } +} + +# Helper to loop over IIterator based pointers. +proc ForEachIterEle { _ele_var_name _iter script } { + if {$_iter == 0} { return 0 } + upvar $_ele_var_name ele + for { $_iter First } { ![ $_iter IsEnd ] } { $_iter Next } { + set ele [ $_iter CurrentItem ] + set returned_val [ uplevel $script ] + } +} + +# Helper to get the Tcl Project Manager, if possible. +proc GetTclProjectMgr { } { + set TclProjectMgrId "{7d528480-1196-4635-aba9-639446e4aa59}" + set iUnk [ Xilinx::CitP::CreateComponent $TclProjectMgrId ] + if {$iUnk == 0} { return 0 } + set iTclProjectMgr [ $iUnk GetInterface $::xilinx::TcltaskI::ITclProjectMgrID ] + OnNullPtr iTclProjectMgr { + ERR "Could not create a \"TclProjectMgr\" component." + } + return $iTclProjectMgr +} + +# Helper to get the current Tcl Project, if one is open. +proc GetCurrentTclProject { } { + set iTclProject 0 + set iTclProjectMgr [GetTclProjectMgr] + OnOkPtr iTclProjectMgr { + set errmsg "" + $iTclProjectMgr GetCurrentTclProject iTclProject errmsg + } + return $iTclProject +} + +# Helper to get the current HDProject, if one is open. +proc GetCurrentHDProject { } { + set iHDProject 0 + set iTclProjectMgr [GetTclProjectMgr] + set errmsg "" + OnOkPtr iTclProjectMgr { $iTclProjectMgr GetCurrentHDProject iHDProject errmsg } + OnNullPtr iHDProject { + ERR "Could not get the current HDProject." + } + return $iHDProject +} + +# Helper to create a Project Helper. +proc GetProjectHelper { } { + set ProjectHelperID "{0725c3d2-5e9b-4383-a7b6-a80c932eac21}" + set iProjHelper [CreateComponent $ProjectHelperID $::xilinx::Dpm::IProjectHelperID "Project Helper"] + return $iProjHelper +} + +# Helper to find out if a project is currently open. +# Returns 1 if a project is open, otherwise 0. +proc IsProjectOpen { } { + set iTclProject [GetCurrentTclProject] + set isOpen [expr {$iTclProject != 0}] + Release $iTclProject + return $isOpen +} + +# Helper to return the lock file for the specified project if there is one. +# Returns an empty string if there is no lock file on the specified project, +# or there is no corresponding .ise file +# This assumes that the project_file is in the current directory. +# It also assumes project_file does not have a path. +proc GetProjectLockFile { project_file } { + if { ![ file isfile "$project_file" ] } { + return + } + INFO "Checking for a lock file for \"$project_file\"." + set lock_file "__ISE_repository_${project_file}_.lock" + if { [ file isfile "$lock_file" ] } { + return $lock_file + } + return +} + +# Helper to back up the project file. +# This assumes that the project_file is in the current directory. +proc BackUpProject { project_file backup_file } { + if { ![ file isfile "$project_file" ] } { + WARN "Could not find \"$project_file\"; the project will not be backed up." + return 0 + } else { + INFO "Backing up the project to \"$backup_file\"." + file copy -force "$project_file" "$backup_file" + } + return 1 +} + +# Helper to remove the project file so that a new project can be created +# in its place. Presumably the old project is corrupted and can no longer +# be opened. +proc RemoveProject { project_file } { + file delete -force "$project_file" + # Return failure if the project still exists. + if { [ file isfile "$project_file" ] } { + ERR "Could not remove \"$project_file\"; Unable to restore the project." + return 0 + } + return 1 +} + +# Helper to open a project and return a project facilitator (pointer). +proc OpenFacilProject { project_name } { + # first make sure the tcl project mgr singleton exists + GetTclProjectMgr + # get a Project Helper and open the project. + set iProjHelper [GetProjectHelper] + if {$iProjHelper == 0} { return 0 } + set result [$iProjHelper Open $project_name] + OnFail $result { + if {$result == 576460769483292673} { + ERR "Could not open the project \"$project_name\" because it is locked." + } else { + ERR "Could not open the \"$project_name\" project." + } + Release $iProjHelper + set iProjHelper 0 + } + return $iProjHelper +} + +# Helper to close and release a project. +proc CloseFacilProject { iProjHelper } { + if {$iProjHelper == 0} { return } + $iProjHelper Close + Release $iProjHelper +} + +# Helper to get the Project from the Project Helper. +# Clients must release this. +proc GetProject { iProjHelper } { + if {$iProjHelper == 0} { return 0 } + set dpm_project 0 + $iProjHelper GetDpmProject dpm_project + set iProject [ GetInterface $dpm_project $xilinx::Dpm::IProjectID ] + OnNullPtr iProject { + ERR "Could not get the Project from the Project Helper." + } + return $iProject +} + +# Helper to get the File Manager from the Project Helper. +# Clients must release this. +proc GetFileManager { iProjHelper } { + set iProject [GetProject $iProjHelper] + set iFileMgr [ GetInterface $iProject $xilinx::Dpm::IFileManagerID ] + OnNullPtr iFileMgr { + ERR "Could not get the File Manager from the Project Helper." + } + # Don't release the project here, clients will release it + # when they release its IFileManager interface. + return $iFileMgr +} + +# Helper to get the Source Library Manager from the Project Helper. +# Clients must release this. +proc GetSourceLibraryManager { iProjHelper } { + set iProject [GetProject $iProjHelper] + set iSourceLibraryMgr [ GetInterface $iProject $xilinx::Dpm::ISourceLibraryManagerID ] + OnNullPtr iSourceLibraryMgr { + ERR "Could not get the Source Library Manager from the Project Helper." + } + # Don't release the project here, clients will release it + # when they release its IFileManager interface. + return $iSourceLibraryMgr +} + +# Helper to get the ProjSrcHelper from the Project Helper. +# Clients must NOT release this. +proc GetProjSrcHelper { iProjHelper } { + set iSrcHelper [ GetInterface $iProjHelper $::xilinx::Dpm::IProjSrcHelperID IProjSrcHelper ] + OnNullPtr iSrcHelper { + ERR "Could not get the ProjSrcHelper from the Project Helper." + } + return $iSrcHelper +} + +# Helper to get the ScratchPropertyManager from the Project Helper. +# Clients must NOT release this. +proc GetScratchPropertyManager { iProjHelper } { + set iPropTableFetch [ GetInterface $iProjHelper $xilinx::Dpm::IPropTableFetchID IPropTableFetch ] + set prop_table_comp 0 + OnOkPtr iPropTableFetch { + $iPropTableFetch GetPropTable prop_table_comp + } + set iScratch [ GetInterface $prop_table_comp $xilinx::Dpm::IScratchPropertyManagerID ] + OnNullPtr iScratch { + ERR "Could not get the Scratch Property Manager from the Project Helper." + } + return $iScratch +} + +# Helper to get the Design from the Project Helper. +# Clients must release this. +proc GetDesign { iProjHelper } { + set iProject [GetProject $iProjHelper] + set iDesign 0 + OnOkPtr iProject { $iProject GetDesign iDesign } + OnNullPtr iDesign { + ERR "Could not get the Design from the Project Helper." + } + Release $iProject + return $iDesign +} + +# Helper to get the Data Store from the Project Helper. +# Clients must NOT release this. +proc GetDataStore { iProjHelper } { + set iDesign [ GetDesign $iProjHelper] + set iDataStore 0 + OnOkPtr iDesign { $iDesign GetDataStore iDataStore } + OnNullPtr iDataStore { + ERR "Could not get the Data Store from the Project Helper." + } + Release $iDesign + return $iDataStore +} + +# Helper to get the View Manager from the Project Helper. +# Clients must NOT release this. +proc GetViewManager { iProjHelper } { + set iDesign [ GetDesign $iProjHelper] + set iViewMgr [ GetInterface $iDesign $xilinx::Dpm::IViewManagerID ] + OnNullPtr iViewMgr { + ERR "Could not get the View Manager from the Project Helper." + } + # Don't release the design here, clients will release it + # when they release its IViewManager interface. + return $iViewMgr +} + +# Helper to get the Property Manager from the Project Helper. +# Clients must release this. +proc GetPropertyManager { iProjHelper } { + set iDesign [ GetDesign $iProjHelper] + set iPropMgr 0 + OnOkPtr iDesign { $iDesign GetPropertyManager iPropMgr } + OnNullPtr iPropMgr { + ERR "Could not get the Property Manager from the Project Helper." + } + Release $iDesign + return $iPropMgr +} + +# Helper to find a property template, based on prop_name +# Clients must NOT release this. +proc GetPropertyTemplate { iProjHelper prop_name } { + set iPropTempl 0 + set iUnk 0 + set iDefdataId 0 + set iPropTemplStore 0 + set iDataStore [GetDataStore $iProjHelper] + OnOkPtr iDataStore { $iDataStore GetComponentByName $prop_name iUnk } + OnOkPtr iUnk { set iDefdataId [ GetInterface $iUnk $xilinx::Dpm::IDefDataIdID IDefDataId ] } + OnOkPtr iDefdataId { + set iPropTemplStore [ GetInterface $iDataStore $xilinx::Dpm::IPropertyTemplateStoreID IPropertyTemplateStore ] + } + OnOkPtr iPropTemplStore { $iPropTemplStore GetPropertyTemplate $iDefdataId iPropTempl } + OnNullPtr iPropTempl { + WARN "Could not get the property template for \"$prop_name\"." + } + return $iPropTempl +} + +# Helper to get a component's name. +proc GetName { iUnk } { + set name "" + set iName [ GetInterface $iUnk $xilinx::Prjrep::INameID IName ] + OnOkPtr iName { $iName GetName name } + return $name +} + +# Helper to get the name of a view's type. +proc GetViewTypeName { iView } { + set typeName "" + set iType 0 + set iDefdataType 0 + OnOkPtr iView { $iView GetType iType } + OnOkPtr iType { + set iDefdataType [ GetInterface $iType $xilinx::Dpm::IDefDataIdID IDefDataId ] + } + OnOkPtr iDefdataType { $iDefdataType GetID typeName } + return $typeName +} + +# Helper to find a view and return its context. +# Must clients release this? +proc GetViewContext { iProjHelper view_id view_name } { + # Simply return if the view_id or view_name is empty. + if { [IsBlank $view_id] || [IsBlank $view_name] } { return 0 } + set foundview 0 + set viewiter 0 + set iViewMgr [GetViewManager $iProjHelper] + OnOkPtr iViewMgr { $iViewMgr GetViews viewiter } + ForEachIterEle view $viewiter { + set typeName [GetViewTypeName $view] + set name [GetName $view] + if { [ string equal $name $view_name ] && [ string equal $view_id $typeName ] } { + set foundview $view + } + } + set context [ GetInterface $foundview $xilinx::Dpm::IPropertyContextID ] + OnNullPtr context { + WARN "Could not get the context for view \"$view_id\":\"$view_name\"." + } + return $context +} + +# Helper to get a string property instance from the property manager. +proc GetStringPropertyInstance { iProjHelper simple_id } { + set iPropMgr [GetPropertyManager $iProjHelper] + if {$iPropMgr == 0} { return 0 } + set iPropInst 0 + $iPropMgr GetStringProperty $simple_id iPropInst + OnNullPtr iPropInst { WARN "Could not get the string property instance $simple_id." } + Release $iPropMgr + return $iPropInst +} + +# Helper to get a property instance from the property manager. +proc GetPropertyInstance { iProjHelper view_name view_id prop_name } { + set iPropInst 0 + set iPropTempl [ GetPropertyTemplate $iProjHelper $prop_name ] + if {$iPropTempl == 0} { return 0 } + set context [ GetViewContext $iProjHelper $view_id $view_name ] + set iPropMgr [GetPropertyManager $iProjHelper] + if {$iPropMgr == 0} { return 0 } + $iPropMgr GetPropertyInstance $iPropTempl $context iPropInst + OnNullPtr iPropInst { + if { ![IsBlank $view_id] && ![IsBlank $view_name] } { + WARN "Could not get the context sensitive property instance $prop_name." + } else { + WARN "Could not get the property instance $prop_name." + } + } + Release $iPropMgr + return $iPropInst +} + +# Helper to store properties back into the property manager. +proc RestoreProcessProperties { iProjHelper process_props } { + INFO "Restoring process properties" + foreach { unused view_name view_id simple_id prop_name prop_val } $process_props { + set iPropInst 0 + if {![IsBlank $simple_id]} { + set iPropInst [ GetStringPropertyInstance $iProjHelper $simple_id ] + } else { + set iPropInst [ GetPropertyInstance $iProjHelper $view_name $view_id $prop_name ] + } + OnOkPtr iPropInst { + OnFail [ $iPropInst SetStringValue "$prop_val" ] { + WARN "Could not set the value of the $prop_name property to \"$prop_val\"." + } + } + Release $iPropInst + } +} + +# Helper to recreate partitions from the variable name with +# a list of instance names. +proc RestorePartitions { namelist } { + INFO "Restoring partitions." + set iHDProject [ GetCurrentHDProject ] + OnOkPtr iHDProject { + foreach name $namelist { + set iPartition [ $iHDProject CreatePartition "$name" ] + } + } +} + +# Helper to create and populate a library +# +proc CreateLibrary { iProjHelper libname filelist } { + + set iLibMgr [ GetSourceLibraryManager $iProjHelper ] + set iFileMgr [ GetFileManager $iProjHelper ] + + if {$iLibMgr == 0} { return 0 } + if {$iFileMgr == 0} { return 0 } + + $iLibMgr CreateSourceLibrary "libname" ilib + + OnOkPtr ilib { + foreach filename $filelist { + set argfile [ file normalize "$filename" ] + set found 0 + set fileiter 0 + $iFileMgr GetFiles fileiter + ForEachIterEle ifile $fileiter { + set path "" + set file "" + $ifile getPath path file + set currentfile [ file normalize [ file join "$path" "$file" ] ] + if { $currentfile == $argfile } { + set found 1 + $ilib AddFile ifile + break + } + } + OnNullPtr found { + WARN "Could not add the file \"$filename\" to the library \"$libname\"." + } + } + } +} + +# Helper to create source libraries and populate them. +proc RestoreSourceLibraries { iProjHelper libraries } { + INFO "Restoring source libraries." + foreach { libname filelist } $libraries { + CreateLibrary $iProjHelper "$libname" $filelist + } +} + +# Helper to add user files to the project using the PnF. +proc AddUserFiles { iProjHelper files } { + INFO "Adding User files." + set iconflict 0 + set iSrcHelper [ GetProjSrcHelper $iProjHelper ] + if {$iSrcHelper == 0} { return 0 } + foreach filename $files { + INFO "Adding the file \"$filename\" to the project." + set result [$iSrcHelper AddSourceFile "$filename" iconflict] + OnFail $result { + if {$result == 6} { + INFO "The file \"$filename\" is already in the project." + } else { + ERR "A problem occurred adding the file \"$filename\" to the project." + } + } + } +} + +# Helper to add files to the project and set their origination. +# Valid origination values are: +# 0 - User +# 1 - Generated +# 2 - Imported +# Files of origination "User" are added through the facilitator, +# otherwise they are added directly to the File Manager. +proc AddImportedFiles { iProjHelper files origination } { + switch $origination { + 0 { INFO "Adding User files." } + 1 { INFO "Adding Generated files." } + 2 { INFO "Adding Imported files." } + default { + ERR "Invalid parameter: origination was set to \"$origination\", but may only be 0, 1, or 2." + return 0 + } + } + set iFileMgr [ GetFileManager $iProjHelper ] + if {$iFileMgr == 0} { return 0 } + foreach filename $files { + set file_type 0 + set hdl_file 0 + set result [$iFileMgr AddFile "$filename" $file_type hdl_file] + OnFail $result { + if {$result == 6} { + INFO "The file \"$filename\" is already in the project." + } elseif { $hdl_file == 0 } { + ERR "A problem occurred adding the file \"$filename\" to the project." + } + } + OnOkPtr hdl_file { + set ifile [ GetInterface $hdl_file $xilinx::Dpm::IFileID IFile ] + OnOkPtr ifile { + set result [ $ifile SetOrigination $origination ] + if {$result != 1} { + ERR "A problem occurred setting the origination of \"$filename\" to \"$origination\"." + } + Release $ifile + } + } + } + return 1 +} + +proc RestoreProjectSettings { iProjHelper project_settings } { + INFO "Restoring device settings" + set iScratch [GetScratchPropertyManager $iProjHelper] + set iPropIter 0 + set iPropSet [ GetInterface $iScratch $xilinx::Dpm::IPropertyNodeSetID IPropertyNodeSet ] + OnOkPtr iPropSet { + $iPropSet GetIterator iPropIter + } + set index 0 + set lastindex [llength $project_settings] + ForEachIterEle prop_node $iPropIter { + set prop_instance 0 + $prop_node GetPropertyInstance prop_instance + if { $index < $lastindex } { + set argname [ lindex $project_settings $index ] + set argvalue [ lindex $project_settings [ expr $index + 1 ] ] + } else { + set argname {} + set argvalue {} + } + if { $prop_instance != 0 } { + set name {} + $prop_instance GetName name + if { [string equal $name $argname ] } { + $prop_instance SetStringValue $argvalue + incr index + incr index + } + } + Release $prop_instance + } + $iScratch Commit + # initialize + $iProjHelper Init +} + +# Helper to load a source control configuration from a stream +# and then store it back into an ise file. +proc RestoreSourceControlOptions { prjfile istream } { + INFO "Restoring source control options" + set config_comp [::Xilinx::Cit::FactoryCreate $::xilinx::Dpm::SourceControlConfigurationCompID ] + OnOkPtr config_comp { set ipersist [ $config_comp GetInterface $xilinx::Prjrep::IPersistID ] } + OnOkPtr config_comp { set igetopts [ $config_comp GetInterface $xilinx::Dpm::SrcCtrl::IGetOptionsID ] } + set helper_comp [::Xilinx::Cit::FactoryCreate $::xilinx::Dpm::SourceControlHelpCompID ] + OnOkPtr helper_comp { set ihelper [ $config_comp GetInterface $xilinx::Dpm::SrcCtrl::IHelperID ] } + OnOkPtr ipersist { $ipersist Load istream } + OnOkPtr ihelper { OnOkPtr igetopts { $ihelper SaveOptions $prjfile $igetopts } } + Release $helper_comp $config_comp +} + +proc import { {working_area ""} {staging_area ""} { srcctrl_comp 0 } } { + set project_file "hostmot2.ise" + set old_working_dir [pwd] + # intialize the new project directory (work) and + # source control reference directory (staging) to + # current working directory, when not specified + if { $working_area == "" } { set working_area [pwd] } + if { $staging_area == "" } { set staging_area [pwd] } + set copy_option relative + set import_files { + "7i43.ucf" + "IDParms.vhd" + "atrans.vhd" + "boutreg.vhd" + "hostmot2.vhd" + "hostmotid.vhd" + "i43hostmot2.vhd" + "i43hostmot2_guide.ncd" + "idrom.vhd" + "irqlogic.vhd" + "kubstepgeny.vhd" + "pwmpdmgenh.vhd" + "pwmrefh.vhd" + "qcounters.vhd" + "simplespix.vhd" + "timestamp.vhd" + "uartr.vhd" + "uartx.vhd" + "ubrategen.vhd" + "watchdog.vhd" + "wordpr.vhd" + "wordrb.vhd"} + INFO "Copying files from \"$staging_area\" to \"$working_area\"" + # Must be in the staging directory before calling CopyIn. + cd [file normalize "$staging_area"] + foreach file $import_files { + CopyIn "$file" "$working_area" $copy_option + } + set iProjHelper 0 + # Bail if a project currently open. + if {[IsProjectOpen]} { + ERR "The project must be closed before performing this operation." + return 0 + } + # Must be in the working area (i.e. project directory) before calling recreating the project. + cd [file normalize "$working_area"] + INFO "Recreating project \"$project_file\"." + HandleException { + set iProjHelper [ OpenFacilProject "$project_file"] + } "A problem occurred while creating the project \"$project_file\"." + if {$iProjHelper == 0} { + cd "$old_working_dir" + return 0 + } + set project_settings { + "PROP_DevFamily" "Spartan3" + "PROP_DevDevice" "xc3s200" + "PROP_DevPackage" "tq144" + "PROP_DevSpeed" "-4" + "PROP_Top_Level_Module_Type" "HDL" + "PROP_Synthesis_Tool" "XST (VHDL/Verilog)" + "PROP_Simulator" "ISE Simulator (VHDL/Verilog)" + "PROP_PreferredLanguage" "VHDL" + "PROP_Enable_Message_Capture" "true" + "PROP_Enable_Message_Filtering" "false" + "PROP_Enable_Incremental_Messaging" "false" + } + + HandleException { + RestoreProjectSettings $iProjHelper $project_settings + } "A problem occured while restoring project settings." + + set user_files { + "7i43.ucf" + "IDParms.vhd" + "atrans.vhd" + "boutreg.vhd" + "hostmot2.vhd" + "hostmotid.vhd" + "i43hostmot2.vhd" + "idrom.vhd" + "irqlogic.vhd" + "kubstepgeny.vhd" + "pwmpdmgenh.vhd" + "pwmrefh.vhd" + "qcounters.vhd" + "simplespix.vhd" + "timestamp.vhd" + "uartr.vhd" + "uartx.vhd" + "ubrategen.vhd" + "watchdog.vhd" + "wordpr.vhd" + "wordrb.vhd"} + + HandleException { + AddUserFiles $iProjHelper $user_files + } "A problem occured while restoring user files." + + set imported_files {} + + set origination 2 + + HandleException { + AddImportedFiles $iProjHelper $imported_files $origination + } "A problem occured while restoring imported files." + + set process_props { + "A" "" "" "" "PROPEXT_SynthMultStyle_virtex2" "Auto" + "A" "" "" "" "PROPEXT_xilxBitgCfg_DCIUpdateMode_spartan3" "As Required" + "A" "" "" "" "PROPEXT_xilxBitgCfg_Rate_spartan3" "Default (6)" + "A" "" "" "" "PROPEXT_xilxMapGenInputK_virtex2" "4" + "A" "" "" "" "PROPEXT_xilxSynthAddBufg_spartan3" "8" + "A" "" "" "" "PROPEXT_xilxSynthMaxFanout_virtex2" "500" + "A" "" "" "" "PROP_CPLDFitkeepio" "false" + "A" "" "" "" "PROP_CompxlibAbelLib" "true" + "A" "" "" "" "PROP_CompxlibCPLDDetLib" "true" + "A" "" "" "" "PROP_CompxlibOtherCompxlibOpts" "" + "A" "" "" "" "PROP_CompxlibOutputDir" "$XILINX/<language>/<simulator>" + "A" "" "" "" "PROP_CompxlibOverwriteLib" "Overwrite" + "A" "" "" "" "PROP_CompxlibSimPrimatives" "true" + "A" "" "" "" "PROP_CompxlibXlnxCoreLib" "true" + "A" "" "" "" "PROP_CurrentFloorplanFile" "" + "A" "" "" "" "PROP_DesignName" "hostmot2" + "A" "" "" "" "PROP_Dummy" "dum1" + "A" "" "" "" "PROP_EnableWYSIWYG" "None" + "A" "" "" "" "PROP_Enable_Incremental_Messaging" "false" + "A" "" "" "" "PROP_Enable_Message_Capture" "true" + "A" "" "" "" "PROP_Enable_Message_Filtering" "false" + "A" "" "" "" "PROP_FitterReportFormat" "Text" + "A" "" "" "" "PROP_FlowDebugLevel" "0" + "A" "" "" "" "PROP_FunctionBlockInputLimit" "38" + "A" "" "" "" "PROP_ISimLibSearchOrderFile" "" + "A" "" "" "" "PROP_ISimSDFTimingToBeRead" "Setup Time" + "A" "" "" "" "PROP_ISimUseCustomCompilationOrder" "false" + "A" "" "" "" "PROP_ISimUseCustomSimCmdFile_behav_tb" "false" + "A" "" "" "" "PROP_ISimUseCustomSimCmdFile_behav_tbw" "false" + "A" "" "" "" "PROP_ISimUseCustomSimCmdFile_gen_tbw" "false" + "A" "" "" "" "PROP_ISimUseCustomSimCmdFile_par_tb" "false" + "A" "" "" "" "PROP_ISimUseCustomSimCmdFile_par_tbw" "false" + "A" "" "" "" "PROP_ISimUutInstName" "UUT" + "A" "" "" "" "PROP_ImpactProjectFile" "" + "A" "" "" "" "PROP_Parse_Target" "synthesis" + "A" "" "" "" "PROP_PartitionCreateDelete" "" + "A" "" "" "" "PROP_PartitionForcePlacement" "" + "A" "" "" "" "PROP_PartitionForceSynth" "" + "A" "" "" "" "PROP_PartitionForceTranslate" "" + "A" "" "" "" "PROP_PlsClockEnable" "true" + "A" "" "" "" "PROP_PostTrceFastPath" "false" + "A" "" "" "" "PROP_PreTrceFastPath" "false" + "A" "" "" "" "PROP_SimModelGenerateTestbenchFile" "false" + "A" "" "" "" "PROP_SimModelInsertBuffersPulseSwallow" "false" + "A" "" "" "" "PROP_SimModelOtherNetgenOpts" "" + "A" "" "" "" "PROP_SimModelRetainHierarchy" "true" + "A" "" "" "" "PROP_SynthCaseImplStyle" "None" + "A" "" "" "" "PROP_SynthDecoderExtract" "true" + "A" "" "" "" "PROP_SynthEncoderExtract" "Yes" + "A" "" "" "" "PROP_SynthExtractMux" "Yes" + "A" "" "" "" "PROP_SynthExtractRAM" "true" + "A" "" "" "" "PROP_SynthExtractROM" "true" + "A" "" "" "" "PROP_SynthFsmEncode" "Auto" + "A" "" "" "" "PROP_SynthLogicalShifterExtract" "true" + "A" "" "" "" "PROP_SynthMultStyle" "LUT" + "A" "" "" "" "PROP_SynthOpt" "Speed" + "A" "" "" "" "PROP_SynthOptEffort" "Normal" + "A" "" "" "" "PROP_SynthResSharing" "true" + "A" "" "" "" "PROP_SynthShiftRegExtract" "true" + "A" "" "" "" "PROP_SynthXORCollapse" "true" + "A" "" "" "" "PROP_Top_Level_Module_Type" "HDL" + "A" "" "" "" "PROP_UseDataGate" "true" + "A" "" "" "" "PROP_UserConstraintEditorPreference" "Constraints Editor" + "A" "" "" "" "PROP_UserEditorCustomSetting" "" + "A" "" "" "" "PROP_UserEditorPreference" "ISE Text Editor" + "A" "" "" "" "PROP_XPowerOptInputTclScript" "" + "A" "" "" "" "PROP_XPowerOptLoadPCFFile" "Default" + "A" "" "" "" "PROP_XPowerOptLoadVCDFile" "Default" + "A" "" "" "" "PROP_XPowerOptLoadXMLFile" "Default" + "A" "" "" "" "PROP_XPowerOptOutputFile" "Default" + "A" "" "" "" "PROP_XPowerOptVerboseRpt" "false" + "A" "" "" "" "PROP_XPowerOtherXPowerOpts" "" + "A" "" "" "" "PROP_XplorerMode" "Off" + "A" "" "" "" "PROP_bitgen_otherCmdLineOptions" "" + "A" "" "" "" "PROP_cpldBestFit" "false" + "A" "" "" "" "PROP_cpldfitHDLeqStyle" "Source" + "A" "" "" "" "PROP_cpldfit_otherCmdLineOptions" "" + "A" "" "" "" "PROP_fitGenSimModel" "false" + "A" "" "" "" "PROP_hprep6_autosig" "false" + "A" "" "" "" "PROP_hprep6_otherCmdLineOptions" "" + "A" "" "" "" "PROP_ibiswriterShowAllModels" "false" + "A" "" "" "" "PROP_impactConfigFileName_CPLD" "" + "A" "" "" "" "PROP_mapUseRLOCConstraints" "true" + "A" "" "" "" "PROP_map_otherCmdLineOptions" "" + "A" "" "" "" "PROP_mpprRsltToCopy" "" + "A" "" "" "" "PROP_mpprViewPadRptsForAllRslt" "true" + "A" "" "" "" "PROP_mpprViewParRptsForAllRslt" "true" + "A" "" "" "" "PROP_ngdbuildUseLOCConstraints" "true" + "A" "" "" "" "PROP_ngdbuild_otherCmdLineOptions" "" + "A" "" "" "" "PROP_parTimingAnalyzerLoadDesign" "true" + "A" "" "" "" "PROP_parUseTimingConstraints" "true" + "A" "" "" "" "PROP_par_otherCmdLineOptions" "" + "A" "" "" "" "PROP_primeCorrelateOutput" "false" + "A" "" "" "" "PROP_primeFlatternOutputNetlist" "false" + "A" "" "" "" "PROP_primeTopLevelModule" "" + "A" "" "" "" "PROP_primetimeBlockRamData" "" + "A" "" "" "" "PROP_taengine_otherCmdLineOptions" "" + "A" "" "" "" "PROP_xcpldFitDesInit" "Low" + "A" "" "" "" "PROP_xcpldFitDesInputLmt_xbr" "32" + "A" "" "" "" "PROP_xcpldFitDesMultiLogicOpt" "true" + "A" "" "" "" "PROP_xcpldFitDesSlew" "Fast" + "A" "" "" "" "PROP_xcpldFitDesTimingCst" "true" + "A" "" "" "" "PROP_xcpldFitDesTriMode" "Keeper" + "A" "" "" "" "PROP_xcpldFitDesUnused" "Keeper" + "A" "" "" "" "PROP_xcpldFitDesVolt" "LVCMOS18" + "A" "" "" "" "PROP_xcpldFitTemplate_xpla3" "Optimize Density" + "A" "" "" "" "PROP_xcpldFittimRptOption" "Summary" + "A" "" "" "" "PROP_xcpldUseGlobalClocks" "true" + "A" "" "" "" "PROP_xcpldUseGlobalOutputEnables" "true" + "A" "" "" "" "PROP_xcpldUseGlobalSetReset" "true" + "A" "" "" "" "PROP_xcpldUseLocConst" "Always" + "A" "" "" "" "PROP_xilxBitgCfg_Clk" "Pull Up" + "A" "" "" "" "PROP_xilxBitgCfg_Code" "0xFFFFFFFF" + "A" "" "" "" "PROP_xilxBitgCfg_DCMShutdown" "false" + "A" "" "" "" "PROP_xilxBitgCfg_Done" "Pull Up" + "A" "" "" "" "PROP_xilxBitgCfg_GenOpt_ASCIIFile" "false" + "A" "" "" "" "PROP_xilxBitgCfg_GenOpt_BinaryFile" "false" + "A" "" "" "" "PROP_xilxBitgCfg_GenOpt_BitFile" "true" + "A" "" "" "" "PROP_xilxBitgCfg_GenOpt_Compress" "false" + "A" "" "" "" "PROP_xilxBitgCfg_GenOpt_DRC" "true" + "A" "" "" "" "PROP_xilxBitgCfg_GenOpt_EnableCRC" "true" + "A" "" "" "" "PROP_xilxBitgCfg_GenOpt_GClkDel0" "11111" + "A" "" "" "" "PROP_xilxBitgCfg_GenOpt_GClkDel1" "11111" + "A" "" "" "" "PROP_xilxBitgCfg_GenOpt_GClkDel2" "11111" + "A" "" "" "" "PROP_xilxBitgCfg_GenOpt_GClkDel3" "11111" + "A" "" "" "" "PROP_xilxBitgCfg_GenOpt_IEEE1532File" "false" + "A" "" "" "" "PROP_xilxBitgCfg_GenOpt_IEEE1532File_xbr" "false" + "A" "" "" "" "PROP_xilxBitgCfg_GenOpt_ReadBack" "false" + "A" "" "" "" "PROP_xilxBitgCfg_M0" "Pull Up" + "A" "" "" "" "PROP_xilxBitgCfg_M1" "Pull Up" + "A" "" "" "" "PROP_xilxBitgCfg_M2" "Pull Up" + "A" "" "" "" "PROP_xilxBitgCfg_Pgm" "Pull Up" + "A" "" "" "" "PROP_xilxBitgCfg_Rate" "4" + "A" "" "" "" "PROP_xilxBitgCfg_TCK" "Pull Up" + "A" "" "" "" "PROP_xilxBitgCfg_TDI" "Pull Up" + "A" "" "" "" "PROP_xilxBitgCfg_TDO" "Pull Up" + "A" "" "" "" "PROP_xilxBitgCfg_TMS" "Pull Up" + "A" "" "" "" "PROP_xilxBitgCfg_Unused" "Pull Down" + "A" "" "" "" "PROP_xilxBitgReadBk_Sec" "Enable Readback and Reconfiguration" + "A" "" "" "" "PROP_xilxBitgStart_Clk" "CCLK" + "A" "" "" "" "PROP_xilxBitgStart_Clk_Done" "6" + "A" "" "" "" "PROP_xilxBitgStart_Clk_DriveDone" "false" + "A" "" "" "" "PROP_xilxBitgStart_Clk_EnOut" "Default (5)" + "A" "" "" "" "PROP_xilxBitgStart_Clk_MatchCycle" "Auto" + "A" "" "" "" "PROP_xilxBitgStart_Clk_RelDLL" "Default (NoWait)" + "A" "" "" "" "PROP_xilxBitgStart_Clk_RelSet" "Default (6)" + "A" "" "" "" "PROP_xilxBitgStart_Clk_WrtEn" "4" + "A" "" "" "" "PROP_xilxBitgStart_IntDone" "false" + "A" "" "" "" "PROP_xilxMapAllowLogicOpt" "false" + "A" "" "" "" "PROP_xilxMapCoverMode" "Speed" + "A" "" "" "" "PROP_xilxMapDisableRegOrdering" "false" + "A" "" "" "" "PROP_xilxMapGenInputK" "4" + "A" "" "" "" "PROP_xilxMapPackRegInto" "For Inputs and Outputs" + "A" "" "" "" "PROP_xilxMapReplicateLogic" "true" + "A" "" "" "" "PROP_xilxMapReportDetail" "true" + "A" "" "" "" "PROP_xilxMapSliceLogicInUnusedBRAMs" "false" + "A" "" "" "" "PROP_xilxMapTimingDrivenPacking" "false" + "A" "" "" "" "PROP_xilxMapTrimUnconnSig" "true" + "A" "" "" "" "PROP_xilxNgdbldIOPads" "false" + "A" "" "" "" "PROP_xilxNgdbldMacro" "" + "A" "" "" "" "PROP_xilxNgdbldNTType" "Timestamp" + "A" "" "" "" "PROP_xilxNgdbldPresHierarchy" "false" + "A" "" "" "" "PROP_xilxNgdbldUR" "" + "A" "" "" "" "PROP_xilxNgdbldUnexpBlks" "false" + "A" "" "" "" "PROP_xilxNgdbld_AUL" "false" + "A" "" "" "" "PROP_xilxPARplacerCostTable" "1" + "A" "" "" "" "PROP_xilxPARplacerEffortLevel" "None" + "A" "" "" "" "PROP_xilxPARrouterEffortLevel" "None" + "A" "" "" "" "PROP_xilxPARstrat" "Normal Place and Route" + "A" "" "" "" "PROP_xilxPARuseBondedIO" "false" + "A" "" "" "" "PROP_xilxPostTrceAdvAna" "false" + "A" "" "" "" "PROP_xilxPostTrceRpt" "Error Report" + "A" "" "" "" "PROP_xilxPostTrceRptLimit" "3" + "A" "" "" "" "PROP_xilxPostTrceStamp" "" + "A" "" "" "" "PROP_xilxPostTrceTSIFile" "" + "A" "" "" "" "PROP_xilxPostTrceUncovPath" "" + "A" "" "" "" "PROP_xilxPreTrceAdvAna" "false" + "A" "" "" "" "PROP_xilxPreTrceRpt" "Error Report" + "A" "" "" "" "PROP_xilxPreTrceRptLimit" "3" + "A" "" "" "" "PROP_xilxPreTrceUncovPath" "" + "A" "" "" "" "PROP_xilxSynthAddBufg" "4" + "A" "" "" "" "PROP_xilxSynthAddIObuf" "true" + "A" "" "" "" "PROP_xilxSynthGlobOpt" "AllClockNets" + "A" "" "" "" "PROP_xilxSynthKeepHierarchy" "No" + "A" "" "" "" "PROP_xilxSynthKeepHierarchy_CPLD" "Yes" + "A" "" "" "" "PROP_xilxSynthMacroPreserve" "true" + "A" "" "" "" "PROP_xilxSynthMaxFanout" "100" + "A" "" "" "" "PROP_xilxSynthRegBalancing" "No" + "A" "" "" "" "PROP_xilxSynthRegDuplication" "true" + "A" "" "" "" "PROP_xilxSynthXORPreserve" "true" + "A" "" "" "" "PROP_xilxTriStateBuffTXMode" "On" + "A" "" "" "" "PROP_xstAsynToSync" "false" + "A" "" "" "" "PROP_xstAutoBRAMPacking" "false" + "A" "" "" "" "PROP_xstBRAMUtilRatio" "100" + "A" "" "" "" "PROP_xstBusDelimiter" "<>" + "A" "" "" "" "PROP_xstCase" "Maintain" + "A" "" "" "" "PROP_xstCoresSearchDir" "" + "A" "" "" "" "PROP_xstCrossClockAnalysis" "false" + "A" "" "" "" "PROP_xstEquivRegRemoval" "true" + "A" "" "" "" "PROP_xstFsmStyle" "LUT" + "A" "" "" "" "PROP_xstGenerateRTLNetlist" "Yes" + "A" "" "" "" "PROP_xstGenericsParameters" "" + "A" "" "" "" "PROP_xstHierarchySeparator" "/" + "A" "" "" "" "PROP_xstIniFile" "" + "A" "" "" "" "PROP_xstLibSearchOrder" "" + "A" "" "" "" "PROP_xstOptimizeInsPrimtives" "false" + "A" "" "" "" "PROP_xstPackIORegister" "Auto" + "A" "" "" "" "PROP_xstReadCores" "true" + "A" "" "" "" "PROP_xstSlicePacking" "true" + "A" "" "" "" "PROP_xstSliceUtilRatio" "100" + "A" "" "" "" "PROP_xstTristate2Logic" "Yes" + "A" "" "" "" "PROP_xstUseClockEnable" "Yes" + "A" "" "" "" "PROP_xstUseSyncReset" "Yes" + "A" "" "" "" "PROP_xstUseSyncSet" "Yes" + "A" "" "" "" "PROP_xstUseSynthConstFile" "true" + "A" "" "" "" "PROP_xstUserCompileList" "" + "A" "" "" "" "PROP_xstVeriIncludeDir_Global" "" + "A" "" "" "" "PROP_xstVerilog2001" "true" + "A" "" "" "" "PROP_xstVerilogMacros" "" + "A" "" "" "" "PROP_xstWorkDir" "./xst" + "A" "" "" "" "PROP_xstWriteTimingConstraints" "false" + "A" "" "" "" "PROP_xst_otherCmdLineOptions" "" + "A" "AutoGeneratedView" "VIEW_AbstractSimulation" "" "PROP_TopDesignUnit" "Architecture|i43hostmot2|Behavioral" + "A" "AutoGeneratedView" "VIEW_AnalyzedDesign" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_AnnotatedPreSimulation" "" "PROP_ISimIncreCompilation" "true" + "A" "AutoGeneratedView" "VIEW_AnnotatedPreSimulation" "" "PROP_ISimSpecifyDefMacroAndValue" "" + "A" "AutoGeneratedView" "VIEW_AnnotatedPreSimulation" "" "PROP_ISimSpecifySearchDirectory" "" + "A" "AutoGeneratedView" "VIEW_AnnotatedPreSimulation" "" "PROP_ISimValueRangeCheck" "false" + "A" "AutoGeneratedView" "VIEW_AnnotatedPreSimulation" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_AnnotatedResultsFuse" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_AnnotatedResultsISim" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_BehavioralFuse" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_BehavioralSimulationISim" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_FPGAConfiguration" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_FPGAConfigureDevice" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_FPGAGeneratePROM" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_Map" "" "PROP_SmartGuide" "false" + "A" "AutoGeneratedView" "VIEW_Map" "" "PROP_TopDesignUnit" "Module|i43hostmot2" + "A" "AutoGeneratedView" "VIEW_Par" "" "PROP_TopDesignUnit" "Module|i43hostmot2" + "A" "AutoGeneratedView" "VIEW_Post-MapAbstractSimulation" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_Post-MapPreSimulation" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_Post-ParAbstractSimulation" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_Post-ParFuse" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_Post-ParPreSimulation" "" "PROP_ISimCompileForHdlDebug" "true" + "A" "AutoGeneratedView" "VIEW_Post-ParPreSimulation" "" "PROP_ISimIncreCompilation" "true" + "A" "AutoGeneratedView" "VIEW_Post-ParPreSimulation" "" "PROP_ISimSpecifyDefMacroAndValue" "" + "A" "AutoGeneratedView" "VIEW_Post-ParPreSimulation" "" "PROP_ISimSpecifySearchDirectory" "" + "A" "AutoGeneratedView" "VIEW_Post-ParPreSimulation" "" "PROP_ISimValueRangeCheck" "false" + "A" "AutoGeneratedView" "VIEW_Post-ParPreSimulation" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_Post-ParSimulationISim" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_Post-SynthesisAbstractSimulation" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_Post-TranslateAbstractSimulation" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_Post-TranslatePreSimulation" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_PostAbstractSimulation" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_PreSimulation" "" "PROP_ISimCompileForHdlDebug" "true" + "A" "AutoGeneratedView" "VIEW_PreSimulation" "" "PROP_ISimIncreCompilation" "true" + "A" "AutoGeneratedView" "VIEW_PreSimulation" "" "PROP_ISimSpecifyDefMacroAndValue" "" + "A" "AutoGeneratedView" "VIEW_PreSimulation" "" "PROP_ISimSpecifySearchDir" "" + "A" "AutoGeneratedView" "VIEW_PreSimulation" "" "PROP_ISimSpecifySearchDirectory" "" + "A" "AutoGeneratedView" "VIEW_PreSimulation" "" "PROP_ISimValueRangeCheck" "false" + "A" "AutoGeneratedView" "VIEW_PreSimulation" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_Structural" "" "PROP_TopDesignUnit" "Module|i43hostmot2" + "A" "AutoGeneratedView" "VIEW_TBWBehavioralFuse" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_TBWBehavioralSimulationISim" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_TBWPost-MapPreSimulation" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_TBWPost-ParFuse" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_TBWPost-ParPreSimulation" "" "PROP_ISimCompileForHdlDebug" "true" + "A" "AutoGeneratedView" "VIEW_TBWPost-ParPreSimulation" "" "PROP_ISimIncreCompilation" "true" + "A" "AutoGeneratedView" "VIEW_TBWPost-ParPreSimulation" "" "PROP_ISimSpecifyDefMacroAndValue" "" + "A" "AutoGeneratedView" "VIEW_TBWPost-ParPreSimulation" "" "PROP_ISimSpecifySearchDirectory" "" + "A" "AutoGeneratedView" "VIEW_TBWPost-ParPreSimulation" "" "PROP_ISimValueRangeCheck" "false" + "A" "AutoGeneratedView" "VIEW_TBWPost-ParPreSimulation" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_TBWPost-ParSimulationISim" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_TBWPost-TranslatePreSimulation" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_TBWPreSimulation" "" "PROP_ISimCompileForHdlDebug" "true" + "A" "AutoGeneratedView" "VIEW_TBWPreSimulation" "" "PROP_ISimIncreCompilation" "true" + "A" "AutoGeneratedView" "VIEW_TBWPreSimulation" "" "PROP_ISimSpecifyDefMacroAndValue" "" + "A" "AutoGeneratedView" "VIEW_TBWPreSimulation" "" "PROP_ISimSpecifySearchDirectory" "" + "A" "AutoGeneratedView" "VIEW_TBWPreSimulation" "" "PROP_ISimValueRangeCheck" "false" + "A" "AutoGeneratedView" "VIEW_TBWPreSimulation" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_Translation" "" "PROP_SmartGuide" "false" + "A" "AutoGeneratedView" "VIEW_Translation" "" "PROP_TopDesignUnit" "Module|i43hostmot2" + "A" "AutoGeneratedView" "VIEW_UpdatedBitstream" "" "PROP_TopDesignUnit" "" + "A" "AutoGeneratedView" "VIEW_XSTAbstractSynthesis" "" "PROP_SmartGuide" "false" + "A" "AutoGeneratedView" "VIEW_XSTAbstractSynthesis" "" "PROP_TopDesignUnit" "Architecture|i43hostmot2|Behavioral" + "A" "AutoGeneratedView" "VIEW_XSTPreSynthesis" "" "PROP_TopDesignUnit" "Architecture|i43hostmot2|Behavioral" + "A" "AutoGeneratedView" "VIEW_XSTPreSynthesis" "" "PROP_xstVeriIncludeDir" "" + "A" "VIEW_Initial" "VIEW_Initial" "" "PROP_TopDesignUnit" "Architecture|i43hostmot2|Behavioral" + "B" "" "" "" "PROP_AutoGenFile" "false" + "B" "" "" "" "PROP_DevFamily" "Spartan3" + "B" "" "" "" "PROP_FitterOptimization_xpla3" "Density" + "B" "" "" "" "PROP_ISimCustomCompilationOrderFile" "" + "B" "" "" "" "PROP_ISimCustomSimCmdFileName_behav_tb" "" + "B" "" "" "" "PROP_ISimCustomSimCmdFileName_behav_tbw" "" + "B" "" "" "" "PROP_ISimCustomSimCmdFileName_gen_tbw" "" + "B" "" "" "" "PROP_ISimCustomSimCmdFileName_par_tb" "" + "B" "" "" "" "PROP_ISimCustomSimCmdFileName_par_tbw" "" + "B" "" "" "" "PROP_ISimGenVCDFile_par_tb" "false" + "B" "" "" "" "PROP_ISimGenVCDFile_par_tbw" "false" + "B" "" "" "" "PROP_ISimSimulationRun_behav_tb" "true" + "B" "" "" "" "PROP_ISimSimulationRun_behav_tbw" "true" + "B" "" "" "" "PROP_ISimSimulationRun_par_tb" "true" + "B" "" "" "" "PROP_ISimSimulationRun_par_tbw" "true" + "B" "" "" "" "PROP_ISimStoreAllSignalTransitions_behav_tb" "false" + "B" "" "" "" "PROP_ISimStoreAllSignalTransitions_behav_tbw" "false" + "B" "" "" "" "PROP_ISimStoreAllSignalTransitions_par_tb" "false" + "B" "" "" "" "PROP_ISimStoreAllSignalTransitions_par_tbw" "false" + "B" "" "" "" "PROP_MapEffortLevel" "Medium" + "B" "" "" "" "PROP_MapLogicOptimization" "false" + "B" "" "" "" "PROP_MapPlacerCostTable" "1" + "B" "" "" "" "PROP_MapPowerReduction" "false" + "B" "" "" "" "PROP_MapRegDuplication" "false" + "B" "" "" "" "PROP_SimModelRenTopLevInstTo" "UUT" + "B" "" "" "" "PROP_Simulator" "ISE Simulator (VHDL/Verilog)" + "B" "" "" "" "PROP_SynthConstraintsFile" "" + "B" "" "" "" "PROP_SynthMuxStyle" "Auto" + "B" "" "" "" "PROP_SynthRAMStyle" "Auto" + "B" "" "" "" "PROP_XPowerOptAdvancedVerboseRpt" "false" + "B" "" "" "" "PROP_XPowerOptMaxNumberLines" "1000" + "B" "" "" "" "PROP_XPowerOptUseTimeBased" "false" + "B" "" "" "" "PROP_impactBaud" "None" + "B" "" "" "" "PROP_impactConfigMode" "None" + "B" "" "" "" "PROP_impactPort" "None" + "B" "" "" "" "PROP_mpprViewPadRptForSelRslt" "" + "B" "" "" "" "PROP_mpprViewParRptForSelRslt" "" + "B" "" "" "" "PROP_parGenAsyDlyRpt" "false" + "B" "" "" "" "PROP_parGenClkRegionRpt" "false" + "B" "" "" "" "PROP_parGenSimModel" "false" + "B" "" "" "" "PROP_parGenTimingRpt" "true" + "B" "" "" "" "PROP_parMpprNodelistFile" "" + "B" "" "" "" "PROP_parMpprParIterations" "3" + "B" "" "" "" "PROP_parMpprResultsDirectory" "" + "B" "" "" "" "PROP_parMpprResultsToSave" "" + "B" "" "" "" "PROP_parPowerReduction" "false" + "B" "" "" "" "PROP_xcpldFitDesInReg_xbr" "true" + "B" "" "" "" "PROP_xcpldFitDesPtermLmt_xbr" "28" + "B" "" "" "" "PROP_xilxBitgCfg_GenOpt_DbgBitStr" "false" + "B" "" "" "" "PROP_xilxBitgCfg_GenOpt_LogicAllocFile" "false" + "B" "" "" "" "PROP_xilxBitgCfg_GenOpt_MaskFile" "false" + "B" "" "" "" "PROP_xilxBitgReadBk_GenBitStr" "false" + "B" "" "" "" "PROP_xilxMapPackfactor" "100" + "B" "" "" "" "PROP_xilxPAReffortLevel" "Standard" + "B" "" "" "" "PROP_xstMoveFirstFfStage" "true" + "B" "" "" "" "PROP_xstMoveLastFfStage" "true" + "B" "" "" "" "PROP_xstROMStyle" "Auto" + "B" "" "" "" "PROP_xstSafeImplement" "No" + "B" "AutoGeneratedView" "VIEW_Map" "" "PROP_ParSmartGuideFileName" "" + "B" "AutoGeneratedView" "VIEW_Translation" "" "PROP_MapSmartGuideFileName" "" + "C" "" "" "" "PROP_AceActiveName" "" + "C" "" "" "" "PROP_CompxlibLang" "VHDL" + "C" "" "" "" "PROP_CompxlibSimPath" "Search in Path" + "C" "" "" "" "PROP_DevDevice" "xc3s200" + "C" "" "" "" "PROP_DevFamilyPMName" "spartan3" + "C" "" "" "" "PROP_ISimSimulationRunTime_behav_tb" "1000 ns" + "C" "" "" "" "PROP_ISimSimulationRunTime_behav_tbw" "1000 ns" + "C" "" "" "" "PROP_ISimSimulationRunTime_par_tb" "1000 ns" + "C" "" "" "" "PROP_ISimSimulationRunTime_par_tbw" "1000 ns" + "C" "" "" "" "PROP_ISimVCDFileName_par_tb" "xpower.vcd" + "C" "" "" "" "PROP_ISimVCDFileName_par_tbw" "xpower.vcd" + "C" "" "" "" "PROP_MapExtraEffort" "None" + "C" "" "" "" "PROP_SimModelGenMultiHierFile" "false" + "C" "" "" "" "PROP_XPowerOptBaseTimeUnit" "ps" + "C" "" "" "" "PROP_XPowerOptNumberOfUnits" "1" + "C" "" "" "" "PROP_impactConfigFileName" "" + "C" "" "" "" "PROP_xilxPARextraEffortLevel" "None" + "D" "" "" "" "PROP_CompxlibUni9000Lib" "true" + "D" "" "" "" "PROP_CompxlibUniSimLib" "true" + "D" "" "" "" "PROP_DevPackage" "tq144" + "D" "" "" "" "PROP_Synthesis_Tool" "XST (VHDL/Verilog)" + "E" "" "" "" "PROP_DevSpeed" "-4" + "E" "" "" "" "PROP_PreferredLanguage" "VHDL" + "F" "" "" "" "PROP_ChangeDevSpeed" "-4" + "F" "" "" "" "PROP_SimModelTarget" "VHDL" + "F" "" "" "" "PROP_hdlInstTempTargetLang" "VHDL" + "F" "" "" "" "PROP_tbwTestbenchTargetLang" "VHDL" + "F" "" "" "" "PROP_xilxPostTrceSpeed" "-4" + "F" "" "" "" "PROP_xilxPreTrceSpeed" "-4" + "G" "" "" "" "PROP_PostSynthSimModelName" "_synthesis.vhd" + "G" "" "" "" "PROP_SimModelAutoInsertGlblModuleInNetlist" "true" + "G" "" "" "" "PROP_SimModelGenArchOnly" "false" + "G" "" "" "" "PROP_SimModelIncSdfAnnInVerilogFile" "true" + "G" "" "" "" "PROP_SimModelIncSimprimInVerilogFile" "false" + "G" "" "" "" "PROP_SimModelIncUnisimInVerilogFile" "false" + "G" "" "" "" "PROP_SimModelIncUselibDirInVerilogFile" "false" + "G" "" "" "" "PROP_SimModelNoEscapeSignal" "false" + "G" "" "" "" "PROP_SimModelOutputExtIdent" "false" + "G" "" "" "" "PROP_SimModelRenTopLevArchTo" "Structure" + "G" "" "" "" "PROP_SimModelRenTopLevMod" "" + "G" "AutoGeneratedView" "VIEW_Map" "" "PROP_PostMapSimModelName" "i43hostmot2_map.vhd" + "G" "AutoGeneratedView" "VIEW_Par" "" "PROP_PostParSimModelName" "i43hostmot2_timesim.vhd" + "G" "AutoGeneratedView" "VIEW_Post-MapAbstractSimulation" "" "PROP_tbwPostMapTestbenchName" "" + "G" "AutoGeneratedView" "VIEW_Post-ParAbstractSimulation" "" "PROP_tbwPostParTestbenchName" "" + "G" "AutoGeneratedView" "VIEW_Post-TranslateAbstractSimulation" "" "PROP_tbwPostXlateTestbenchName" "" + "G" "AutoGeneratedView" "VIEW_Translation" "" "PROP_PostXlateSimModelName" "i43hostmot2_translate.vhd" + "H" "" "" "" "PROP_SimModelBringOutGsrNetAsAPort" "false" + "H" "" "" "" "PROP_SimModelBringOutGtsNetAsAPort" "false" + "H" "" "" "" "PROP_SimModelPathUsedInSdfAnn" "Default" + "H" "AutoGeneratedView" "VIEW_Map" "" "PROP_SimModelRenTopLevEntTo" "i43hostmot2" + "H" "AutoGeneratedView" "VIEW_Par" "" "PROP_SimModelRenTopLevEntTo" "i43hostmot2" + "H" "AutoGeneratedView" "VIEW_Structural" "" "PROP_SimModelRenTopLevEntTo" "i43hostmot2" + "H" "AutoGeneratedView" "VIEW_Translation" "" "PROP_SimModelRenTopLevEntTo" "i43hostmot2" + "I" "" "" "" "PROP_SimModelGsrPortName" "GSR_PORT" + "I" "" "" "" "PROP_SimModelGtsPortName" "GTS_PORT" + "I" "" "" "" "PROP_SimModelRocPulseWidth" "100" + "I" "" "" "" "PROP_SimModelTocPulseWidth" "0"} + + HandleException { + RestoreProcessProperties $iProjHelper $process_props + } "A problem occured while restoring process properties." + + # library names and their members + set libraries { + } + + HandleException { + RestoreSourceLibraries $iProjHelper $libraries + } "A problem occured while restoring source libraries." + + # partition names for recreation + set partition_names { + } + + HandleException { + RestorePartitions $partition_names + } "A problem occured while restoring partitions." + + set opts_stream [ [Xilinx::Cit::FactoryCreate $::xilinx::Dpm::StreamBufferCompID ] GetInterface $xilinx::Prjrep::IStreamID ] + $opts_stream WriteString "5" + $opts_stream WriteString "5" + $opts_stream WriteString "5" + $opts_stream WriteString "5" + $opts_stream WriteString "0" + $opts_stream WriteString "0" + $opts_stream WriteString "3" + $opts_stream WriteString "1" + $opts_stream WriteString "1" + $opts_stream WriteString "1" + $opts_stream WriteString "2" + $opts_stream WriteString "0" + $opts_stream WriteString "6" + $opts_stream WriteString "./xst" + $opts_stream WriteString "C:/ISE9/5i22/hostmot2/HostMot2_guide.ncd" + $opts_stream WriteString "C:/ISE9/5i22/hostmot2/I20HostMot2_guide.ncd" + $opts_stream WriteString "C:/ISE9/5i22/hostmot2/i43hostmot2_guide.ncd" + $opts_stream WriteString "xpower.vcd" + $opts_stream WriteString "xpower.vcd" + $opts_stream WriteString "1" + RestoreSourceControlOptions "$project_file" $opts_stream + Release $opts_stream + if { $srcctrl_comp != 0 } { + set i_prjref [ $srcctrl_comp GetInterface $::xilinx::Dpm::IProjectHelperReferenceID ] + $i_prjref Set iProjHelper + } elseif {$iProjHelper != 0} { + $iProjHelper Close + } + Release $iProjHelper + # return back + cd $old_working_dir +} +
diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/hostmotid.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/hostmotid.vhd new file mode 100644 index 000000000..12b1acee5 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/hostmotid.vhd @@ -0,0 +1,104 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + + +entity hostmotid is + generic ( + buswidth : integer; + cookie : std_logic_vector(31 downto 0); + namelow : std_logic_vector(31 downto 0); + namehigh : std_logic_vector(31 downto 0); + idromoffset : std_logic_vector(31 downto 0)); + port ( + readid : in std_logic; + addr : in std_logic_vector(1 downto 0); + obus : out std_logic_vector (buswidth-1 downto 0)); +end hostmotid; + +architecture Behavioral of hostmotid is + +begin + + hostmotidproc: process (readid,addr) + begin + obus <= ( others => 'Z'); + if readid = '1' then + case addr is + when "00" => obus <= cookie; + when "01" => obus <= namelow; + when "10" => obus <= namehigh; + when "11" => obus <= idromoffset; + when others => null; + end case; + end if; + end process; + +end Behavioral; + diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/i43hostmot2.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/i43hostmot2.vhd new file mode 100644 index 000000000..77a5dc1a7 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/i43hostmot2.vhd @@ -0,0 +1,534 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +use work.IDROMParms.all; + +entity i43hostmot2 is + generic + ( + STEPGENs: integer := 4; + QCOUNTERS: integer := 4; + PWMGens: integer := 4; + SPIs: integer := 0; + SSIs: integer := 0; + UARTs: integer := 0; + PWMRefWidth: integer := 13; -- PWM resolution is PWMRefWidth-1 bits + StepGenTableWidth: integer := 6; -- How many output bits from stepgen + IDROMType: integer := 2; + SepClocks: boolean := true; + OneWS: boolean := true; + I30Pinout: boolean := true; + I44pinout: boolean := false; + QCtrOnlyPinout: boolean := false; + QCtrOnlyPinoutWithIMask: boolean := false; + SVST8_4Pinout: boolean := false; + SVST4_4Pinout: boolean := true; + ConnsWithI30: integer := 1; + ConnsWithI44: integer := 0; + UseStepGenPrescaler : boolean := false; + UseIRQLogic: boolean := true; + UseWatchDog: boolean := true; + OffsetToModules: integer := 64; + OffsetToPinDesc: integer := 512; + ClockHigh: integer := ClockHigh43; + ClockLow: integer := ClockLow43; + BoardNameLow : std_Logic_Vector(31 downto 0) := BoardNameMESA; + BoardNameHigh : std_Logic_Vector(31 downto 0) := BoardName7I43; + FPGASize: integer := 200; + FPGAPins: integer := 144; + IOPorts: integer := 2; + IOWidth: integer := 48; + PortWidth: integer := 24; + BusWidth: integer := 32; + AddrWidth: integer := 16; + InstStride0: integer := 4; + InstStride1: integer := 16; + RegStride0: integer := 256; + RegStride1: integer := 4; + LEDCount: integer := 8 + ); + + Port ( CLK : in std_logic; + LEDS : out std_logic_vector(7 downto 0); + IOBITS : inout std_logic_vector(47 downto 0); + EPP_DATABUS : inout std_logic_vector(7 downto 0); + EPP_DSTROBE : in std_logic; + EPP_ASTROBE : in std_logic; + EPP_WAIT : out std_logic; + EPP_READ : in std_logic; + RECONFIG : out std_logic; + PARACONFIG : out std_logic; + SPICLK : out std_logic; +-- SPIIN : in std_logic; + SPIOUT : out std_logic; + SPICS : out std_logic + ); +end i43hostmot2; + +architecture Behavioral of i43hostmot2 is + + +signal afcnt : std_logic_vector(2 downto 0); +signal afilter : std_logic_vector(1 downto 0); +signal dfcnt : std_logic_vector(2 downto 0); +signal dfilter : std_logic_vector(1 downto 0); +signal rfcnt : std_logic_vector(1 downto 0); +signal rfilter : std_logic; +signal waitpipe : std_logic_vector(9 downto 0); +alias waitpipeend: std_logic is waitpipe(9); +signal alatch : std_logic_vector(AddrWidth-1 downto 0); +signal seladd : std_logic_vector(AddrWidth-1 downto 0); +signal aread : std_logic; +signal awritele : std_logic; +signal wasaddr : std_logic; +signal dread : std_logic; +signal dreadle : std_logic; +signal dreadte : std_logic; +signal dwritele : std_logic; +signal dwritete : std_logic; +signal dstrobete : std_logic; +signal astrobete : std_logic; +signal depp_dstrobe : std_logic; +signal depp_astrobe : std_logic; +signal depp_read : std_logic; + +signal wdlatch : std_logic_vector(31 downto 0); +signal rdlatch : std_logic_vector(31 downto 0); +signal obus : std_logic_vector(31 downto 0); +signal translateaddr : std_logic_vector(AddrWidth-1 downto 0); +alias translatestrobe : std_logic is translateaddr(AddrWidth-1); +signal loadtranslateram : std_logic; +signal readtranslateram : std_logic; +signal translateramsel : std_logic; + +signal read32 : std_logic; +signal write32 : std_logic; + +signal ReconfigSel : std_logic; +signal idata: std_logic_vector(7 downto 0); + +signal ReConfigreg : std_logic := '0'; + +signal fclk : std_logic; +signal clkfx: std_logic; +signal clk0: std_logic; + +begin + +ahostmot2: entity HostMot2 + generic map ( + stepgens => STEPGENs, + qcounters => QCOUNTERS, + pwmgens => PWMGens, + spis => SPIs, + ssis => SSIs, + uarts => UARTs, + pwmrefwidth => PWMRefWidth, + stepgentablewidth => StepGenTableWidth, + idromtype => IDROMType, + sepclocks => SepClocks, + onews => OneWS, + i30pinout => I30Pinout, + i44pinout => I44pinout, + qctronlypinout => QCtrOnlyPinout, + qctronlypinoutwithimask => QCtrOnlyPinoutWithIMask, + svst8_4pinout => SVST8_4Pinout, + svst4_4pinout => SVST4_4Pinout, + connswithi30 => ConnsWithI30, + connswithi44 => ConnsWithI44, + usestepgenprescaler => UseStepGenPrescaler, + useirqlogic => UseIRQLogic, + usewatchdog => UseWatchDog, + offsettomodules => OffsetToModules, + offsettopindesc => OffsetToPinDesc, + clockhigh => ClockHigh, + clocklow => ClockLow, + boardnamelow => BoardNameLow, + boardnamehigh => BoardNameHigh, + fpgasize => FPGASize, + fpgapins => FPGAPins, + ioports => IOPorts, + iowidth => IOWidth, + portwidth => PortWidth, + buswidth => BusWidth, + addrwidth => AddrWidth, + inststride0 => InstStride0, + inststride1 => InstStride1, + regstride0 => RegStride0, + regstride1 => RegStride1, + ledcount => LEDCount + ) + port map ( + ibus => wdlatch, + obus => obus, + addr => seladd(AddrWidth-1 downto 2), + read => read32, + write => write32, + clklow => CLK, + clkhigh => fclk, +-- int => INT, + iobits => IOBITS, + leds => LEDS + ); + + transmogrifier: entity atrans + generic map ( + width => AddrWidth, + depth => 8) + port map( + clk => CLK, + wea => loadtranslateram, + rea => readtranslateram, + reb => '1', + adda => alatch(9 downto 2), + addb => alatch(7 downto 0), + din => wdlatch(15 downto 0), + douta => obus(15 downto 0), + doutb => translateaddr + ); + + ClockMult : DCM + generic map ( + CLKDV_DIVIDE => 2.0, + CLKFX_DIVIDE => 2, + CLKFX_MULTIPLY => 4, -- 4 FOR 100 MHz + CLKIN_DIVIDE_BY_2 => FALSE, + CLKIN_PERIOD => 20.0, + CLKOUT_PHASE_SHIFT => "NONE", + CLK_FEEDBACK => "1X", + DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", + + DFS_FREQUENCY_MODE => "LOW", + DLL_FREQUENCY_MODE => "LOW", + DUTY_CYCLE_CORRECTION => TRUE, + FACTORY_JF => X"C080", + PHASE_SHIFT => 0, + STARTUP_WAIT => FALSE) + port map ( + + CLK0 => clk0, -- + CLKFB => clk0, -- DCM clock feedback + CLKFX => clkfx, + CLKIN => CLK, -- Clock input (from IBUFG, BUFG or DCM) + PSCLK => '0', -- Dynamic phase adjust clock input + PSEN => '0', -- Dynamic phase adjust enable input + PSINCDEC => '0', -- Dynamic phase adjust increment/decrement + RST => '0' -- DCM asynchronous reset input + ); + + BUFG_inst : BUFG + port map ( + O => fclk, -- Clock buffer output + I => clkfx -- Clock buffer input + ); + + -- End of DCM_inst instantiation + + EPPInterface: process(clk, waitpipe, alatch, afilter, dfilter, + EPP_READ, EPP_DSTROBE, EPP_ASTROBE, + depp_dstrobe, depp_astrobe) + begin + + if rising_edge(CLK) then + depp_dstrobe <= EPP_DSTROBE; -- async so one level of FF before anything else + depp_astrobe <= EPP_ASTROBE; + depp_read <= EPP_READ; + afilter(1) <= afilter(0); + dfilter(1) <= dfilter(0); + if (depp_dstrobe = '0') or (depp_astrobe = '0') then + waitpipe <= waitpipe(8 downto 0) & '1'; -- left shift in a 1 + else + waitpipe <= (others => '0'); + end if; + + if depp_astrobe = '0' then + if afcnt /= "111" then + afcnt <= afcnt +1; + end if; + else + if afcnt /= "000" then + afcnt <= afcnt -1; + end if; + end if; + if afcnt = "111" then + afilter(0) <= '1'; + end if; + if afcnt = "000" then + afilter(0) <= '0'; + end if; + + if depp_dstrobe = '0' then + if dfcnt /= "111" then + dfcnt <= dfcnt +1; + end if; + else + if dfcnt /= "000" then + dfcnt <= dfcnt -1; + end if; + end if; + if dfcnt = "111" then + dfilter(0) <= '1'; + end if; + if dfcnt = "000" then + dfilter(0) <= '0'; + end if; + + if depp_read = '1' then + if rfcnt /= "11" then + rfcnt <= rfcnt +1; + end if; + else + if rfcnt /= "00" then + rfcnt <= rfcnt -1; + end if; + end if; + if rfcnt = "11" then + rfilter <= '1'; + end if; + if rfcnt = "00" then + rfilter <= '0'; + end if; + + if awritele = '1' then + if wasaddr = '0' then + alatch(7 downto 0) <= EPP_DATABUS; + else + alatch(15 downto 8) <= EPP_DATABUS; + end if; + end if; + + if dstrobete = '1' then + wasaddr <= '0'; + end if; + + if astrobete = '1' then + wasaddr <= '1'; + end if; + + if dstrobete = '1' and alatch(15) = '1' then -- auto increment address on data access if address MSB is 1 + alatch(14 downto 0) <= alatch(14 downto 0) +1; + end if; + + end if; -- clk + + EPP_WAIT <= waitpipeend; + + if dfilter = "01" and rfilter = '0' then -- generate write 80 ns after leading edge of strobe + dwritele <= '1'; + else + dwritele <= '0'; + end if; + + if dfilter = "10" and rfilter = '0' then -- generate write 80 ns after leading edge of strobe + dwritete <= '1'; + else + dwritete <= '0'; + end if; + + if dfilter = "01" and rfilter = '1' then -- generate read 80 ns after leading edge of strobe + dreadle <= '1'; + else + dreadle <= '0'; + end if; + + if dfilter = "10" and rfilter = '1' then -- generate read 80 ns after leading edge of strobe + dreadte <= '1'; + else + dreadte <= '0'; + end if; + + if dfilter = "10" then -- generate writete 80 ns after trailng edge of strobe + dstrobete <= '1'; + else + dstrobete <= '0'; + end if; + + if afilter = "10" then -- generate writete 80 ns after trailng edge of strobe + astrobete <= '1'; + else + astrobete <= '0'; + end if; + + if afilter = "01" and rfilter = '0' then -- generate write 80 ns after leading edge of strobe + awritele <= '1'; + else + awritele <= '0'; + end if; + + if rfilter = '1' and depp_dstrobe = '0' then + dread <= '1'; + else + dread <= '0'; + end if; + + if rfilter = '1' and depp_astrobe = '0' then + aread <= '1'; + else + aread <= '0'; + end if; + + end process EPPInterface; + + bus_shim32: process (CLK,alatch,EPP_DATABUS) -- 8 to 32 bit bus shim + begin + if rising_edge(CLK) then + if dwritele = '1' then -- on writes, latch the data in our 32 bit write data latch + case seladd(1 downto 0) is -- 32 data is written after last byte saved in latch + when "00" => wdlatch(7 downto 0) <= EPP_DataBus; + when "01" => wdlatch(15 downto 8) <= EPP_DataBus; + when "10" => wdlatch(23 downto 16) <= EPP_DataBus; + when "11" => wdlatch(31 downto 24) <= EPP_DataBus; + when others => null; + end case; + end if; + if alatch(14 downto 9) = TranslateRegionAddr(6 downto 1) then + if dreadle = '1' and translatestrobe = '1' then + rdlatch <= obus; + end if; + else + if dreadle = '1' and seladd(1 downto 0) = "00" then + rdlatch <= obus; + end if; + end if; + end if; -- clk + + case seladd(1 downto 0) is -- on reads, data previously stored in read data latch + when "00" => idata <= rdlatch(7 downto 0); -- is muxed onto 8 bit bus by A(0..1) + when "01" => idata <= rdlatch(15 downto 8); + when "10" => idata <= rdlatch(23 downto 16); + when "11" => idata <= rdlatch(31 downto 24); + when others => null; + end case; + + if alatch(14 downto 10) = TranslateRamAddr(6 downto 2) then + translateramsel <= '1'; + else + translateramsel <= '0'; + end if; + + if dwritete = '1' and translateramsel = '1' then + loadtranslateram <= '1'; + else + loadtranslateram <= '0'; + end if; + + if dreadle = '1' and translateramsel = '1' then + readtranslateram <= '1'; + else + readtranslateram <= '0'; + end if; + + if alatch(14 downto 8) = TranslateRegionAddr(6 downto 0) then + write32 <= dwritete and translatestrobe; + read32 <= dreadle and translatestrobe; + seladd <= '0'&translateaddr(AddrWidth-2 downto 0); -- drop msb = translatestrobe + else + write32 <= dwritete and alatch(1) and alatch(0); + read32 <= dreadle and ((not alatch(1)) and (not alatch(0))); + seladd <= '0'&alatch(AddrWidth-2 downto 0); -- drop msb = autoincbit + end if; + end process; + + doreconfig: process (CLK,ReConfigreg) + begin + if alatch = x"7F7F" then + ReconfigSel <= '1'; + else + ReconfigSel <= '0'; + end if; + if rising_edge(CLK) then + if dwritele = '1' and ReconfigSel = '1' then + if EPP_DATABUS = x"5A" then + ReConfigreg <= '1'; + end if; + end if; + end if; + RECONFIG <= not ReConfigreg; + end process doreconfig; + + BusDrive: process (aread,dread,idata,alatch) + begin + EPP_DATABUS <= "ZZZZZZZZ"; + if dread = '1' then + EPP_DATABUS <= idata; + end if; + if aread = '1' then + if wasaddr = '0' then + EPP_DATABUS <= alatch(7 downto 0); + else + EPP_DATABUS <= alatch(15 downto 8); + end if; + end if; + PARACONFIG <= '1'; + SPICS <= '1'; + SPICLK <= '0'; + SPIOUT <= '0'; + end process BusDrive; + +end; diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/idrom.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/idrom.vhd new file mode 100644 index 000000000..89c8ea235 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/idrom.vhd @@ -0,0 +1,305 @@ + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +use work.IDROMParms.all; + +entity IDROM is + generic ( + idromtype : integer; + offsettomodules : integer; + offsettopindesc : integer; + boardnamelow : std_logic_vector(31 downto 0); + boardnamehigh : std_logic_vector(31 downto 0); + fpgasize : integer; + fpgapins : integer; + ioports : integer; + iowidth : integer; + portwidth : integer; + clocklow : integer; + clockhigh : integer; + inststride0 : integer; + inststride1 : integer; + regstride0 : integer; + regstride1 : integer; + pindesc : PinDescType; + moduleid : moduleIDType ); + port ( + clk : in std_logic; + we : in std_logic; + re : in std_logic; + radd : in std_logic_vector(7 downto 0); + wadd : in std_logic_vector(7 downto 0); + din : in std_logic_vector(31 downto 0); + dout : out std_logic_vector(31 downto 0) + ); +end IDROM; + + architecture syn of IDROM is -- 256 x 32 spram + constant empty : std_logic_vector(31 downto 0) := x"00000000"; + type ram_type is array (0 to 255) of std_logic_vector(31 downto 0); + signal RAM : ram_type := + ( + + CONV_STD_LOGIC_VECTOR(idromtype,32), + CONV_STD_LOGIC_VECTOR(offsettomodules,32), + CONV_STD_LOGIC_VECTOR(offsettopindesc,32), + boardnamelow, + boardnamehigh, + CONV_STD_LOGIC_VECTOR(fpgasize,32), + CONV_STD_LOGIC_VECTOR(fpgapins,32), + CONV_STD_LOGIC_VECTOR(ioports,32), + CONV_STD_LOGIC_VECTOR(iowidth,32), + CONV_STD_LOGIC_VECTOR(portwidth,32), + CONV_STD_LOGIC_VECTOR(clocklow,32), + CONV_STD_LOGIC_VECTOR(clockhigh,32), + CONV_STD_LOGIC_VECTOR(inststride0,32), + CONV_STD_LOGIC_VECTOR(inststride1,32), + CONV_STD_LOGIC_VECTOR(regstride0,32), + CONV_STD_LOGIC_VECTOR(regstride1,32), + +-- module IDs starting at doubleword 16 +-- 32 module id records = 96 doubles total + + moduleid(0).NumInstances&moduleid(0).Clock&moduleid(0).Version&moduleid(0).GTag, + moduleid(0).Strides&moduleid(0).NumRegisters&moduleid(0).BaseAddr, + moduleid(0).MultRegs, + + moduleid(1).NumInstances&moduleid(1).Clock&moduleid(1).Version&moduleid(1).GTag, + moduleid(1).Strides&moduleid(1).NumRegisters&moduleid(1).BaseAddr, + moduleid(1).MultRegs, + + moduleid(2).NumInstances&moduleid(2).Clock&moduleid(2).Version&moduleid(2).GTag, + moduleid(2).Strides&moduleid(2).NumRegisters&moduleid(2).BaseAddr, + moduleid(2).MultRegs, + + moduleid(3).NumInstances&moduleid(3).Clock&moduleid(3).Version&moduleid(3).GTag, + moduleid(3).Strides&moduleid(3).NumRegisters&moduleid(3).BaseAddr, + moduleid(3).MultRegs, + + moduleid(4).NumInstances&moduleid(4).Clock&moduleid(4).Version&moduleid(4).GTag, + moduleid(4).Strides&moduleid(4).NumRegisters&moduleid(4).BaseAddr, + moduleid(4).MultRegs, + + moduleid(5).NumInstances&moduleid(5).Clock&moduleid(5).Version&moduleid(5).GTag, + moduleid(5).Strides&moduleid(5).NumRegisters&moduleid(5).BaseAddr, + moduleid(5).MultRegs, + + moduleid(6).NumInstances&moduleid(6).Clock&moduleid(6).Version&moduleid(6).GTag, + moduleid(6).Strides&moduleid(6).NumRegisters&moduleid(6).BaseAddr, + moduleid(6).MultRegs, + + moduleid(7).NumInstances&moduleid(7).Clock&moduleid(7).Version&moduleid(7).GTag, + moduleid(7).Strides&moduleid(7).NumRegisters&moduleid(7).BaseAddr, + moduleid(7).MultRegs, + + moduleid(8).NumInstances&moduleid(8).Clock&moduleid(8).Version&moduleid(8).GTag, + moduleid(8).Strides&moduleid(8).NumRegisters&moduleid(8).BaseAddr, + moduleid(8).MultRegs, + + moduleid(9).NumInstances&moduleid(9).Clock&moduleid(9).Version&moduleid(9).GTag, + moduleid(9).Strides&moduleid(9).NumRegisters&moduleid(9).BaseAddr, + moduleid(9).MultRegs, + + moduleid(10).NumInstances&moduleid(10).Clock&moduleid(10).Version&moduleid(10).GTag, + moduleid(10).Strides&moduleid(10).NumRegisters&moduleid(10).BaseAddr, + moduleid(10).MultRegs, + + moduleid(11).NumInstances&moduleid(11).Clock&moduleid(11).Version&moduleid(11).GTag, + moduleid(11).Strides&moduleid(11).NumRegisters&moduleid(11).BaseAddr, + moduleid(11).MultRegs, + + moduleid(12).NumInstances&moduleid(12).Clock&moduleid(12).Version&moduleid(12).GTag, + moduleid(12).Strides&moduleid(12).NumRegisters&moduleid(12).BaseAddr, + moduleid(12).MultRegs, + + moduleid(13).NumInstances&moduleid(13).Clock&moduleid(13).Version&moduleid(13).GTag, + moduleid(13).Strides&moduleid(13).NumRegisters&moduleid(13).BaseAddr, + moduleid(13).MultRegs, + + moduleid(14).NumInstances&moduleid(14).Clock&moduleid(14).Version&moduleid(14).GTag, + moduleid(14).Strides&moduleid(14).NumRegisters&moduleid(14).BaseAddr, + moduleid(14).MultRegs, + + moduleid(15).NumInstances&moduleid(15).Clock&moduleid(15).Version&moduleid(15).GTag, + moduleid(15).Strides&moduleid(15).NumRegisters&moduleid(15).BaseAddr, + moduleid(15).MultRegs, + + moduleid(16).NumInstances&moduleid(16).Clock&moduleid(16).Version&moduleid(16).GTag, + moduleid(16).Strides&moduleid(16).NumRegisters&moduleid(16).BaseAddr, + moduleid(16).MultRegs, + + moduleid(17).NumInstances&moduleid(17).Clock&moduleid(17).Version&moduleid(17).GTag, + moduleid(17).Strides&moduleid(17).NumRegisters&moduleid(17).BaseAddr, + moduleid(17).MultRegs, + + moduleid(18).NumInstances&moduleid(18).Clock&moduleid(18).Version&moduleid(18).GTag, + moduleid(18).Strides&moduleid(18).NumRegisters&moduleid(18).BaseAddr, + moduleid(18).MultRegs, + + moduleid(19).NumInstances&moduleid(19).Clock&moduleid(19).Version&moduleid(19).GTag, + moduleid(19).Strides&moduleid(19).NumRegisters&moduleid(19).BaseAddr, + moduleid(19).MultRegs, + + moduleid(20).NumInstances&moduleid(20).Clock&moduleid(20).Version&moduleid(20).GTag, + moduleid(20).Strides&moduleid(20).NumRegisters&moduleid(20).BaseAddr, + moduleid(20).MultRegs, + + moduleid(21).NumInstances&moduleid(21).Clock&moduleid(21).Version&moduleid(21).GTag, + moduleid(21).Strides&moduleid(21).NumRegisters&moduleid(21).BaseAddr, + moduleid(21).MultRegs, + + moduleid(22).NumInstances&moduleid(22).Clock&moduleid(22).Version&moduleid(22).GTag, + moduleid(22).Strides&moduleid(22).NumRegisters&moduleid(22).BaseAddr, + moduleid(22).MultRegs, + + moduleid(23).NumInstances&moduleid(23).Clock&moduleid(23).Version&moduleid(23).GTag, + moduleid(23).Strides&moduleid(23).NumRegisters&moduleid(23).BaseAddr, + moduleid(23).MultRegs, + + moduleid(24).NumInstances&moduleid(24).Clock&moduleid(24).Version&moduleid(24).GTag, + moduleid(24).Strides&moduleid(24).NumRegisters&moduleid(24).BaseAddr, + moduleid(24).MultRegs, + + moduleid(25).NumInstances&moduleid(25).Clock&moduleid(25).Version&moduleid(25).GTag, + moduleid(25).Strides&moduleid(25).NumRegisters&moduleid(25).BaseAddr, + moduleid(25).MultRegs, + + moduleid(26).NumInstances&moduleid(26).Clock&moduleid(26).Version&moduleid(26).GTag, + moduleid(26).Strides&moduleid(26).NumRegisters&moduleid(26).BaseAddr, + moduleid(26).MultRegs, + + moduleid(27).NumInstances&moduleid(27).Clock&moduleid(27).Version&moduleid(27).GTag, + moduleid(27).Strides&moduleid(27).NumRegisters&moduleid(27).BaseAddr, + moduleid(27).MultRegs, + + moduleid(28).NumInstances&moduleid(28).Clock&moduleid(28).Version&moduleid(28).GTag, + moduleid(28).Strides&moduleid(28).NumRegisters&moduleid(28).BaseAddr, + moduleid(28).MultRegs, + + moduleid(29).NumInstances&moduleid(29).Clock&moduleid(29).Version&moduleid(29).GTag, + moduleid(29).Strides&moduleid(29).NumRegisters&moduleid(29).BaseAddr, + moduleid(29).MultRegs, + + moduleid(30).NumInstances&moduleid(30).Clock&moduleid(30).Version&moduleid(30).GTag, + moduleid(30).Strides&moduleid(30).NumRegisters&moduleid(30).BaseAddr, + moduleid(30).MultRegs, + + moduleid(31).NumInstances&moduleid(31).Clock&moduleid(31).Version&moduleid(31).GTag, + moduleid(31).Strides&moduleid(31).NumRegisters&moduleid(31).BaseAddr, + moduleid(31).MultRegs, + + +-- 16 empty doublewords from 112 through 127 + empty,empty,empty,empty,empty,empty,empty,empty, + empty,empty,empty,empty,empty,empty,empty,empty, +-- pindesc starting at doubleword 128 + + pindesc(0),pindesc(1),pindesc(2),pindesc(3),pindesc(4),pindesc(5),pindesc(6),pindesc(7), + pindesc(8),pindesc(9),pindesc(10),pindesc(11),pindesc(12),pindesc(13),pindesc(14),pindesc(15), + pindesc(16),pindesc(17),pindesc(18),pindesc(19),pindesc(20),pindesc(21),pindesc(22),pindesc(23), + pindesc(24),pindesc(25),pindesc(26),pindesc(27),pindesc(28),pindesc(29),pindesc(30),pindesc(31), + pindesc(32),pindesc(33),pindesc(34),pindesc(35),pindesc(36),pindesc(37),pindesc(38),pindesc(39), + pindesc(40),pindesc(41),pindesc(42),pindesc(43),pindesc(44),pindesc(45),pindesc(46),pindesc(47), + pindesc(48),pindesc(49),pindesc(50),pindesc(51),pindesc(52),pindesc(53),pindesc(54),pindesc(55), + pindesc(56),pindesc(57),pindesc(58),pindesc(59),pindesc(60),pindesc(61),pindesc(62),pindesc(63), + pindesc(64),pindesc(65),pindesc(66),pindesc(67),pindesc(68),pindesc(69),pindesc(70),pindesc(71), + pindesc(72),pindesc(73),pindesc(74),pindesc(75),pindesc(76),pindesc(77),pindesc(78),pindesc(79), + pindesc(80),pindesc(81),pindesc(82),pindesc(83),pindesc(84),pindesc(85),pindesc(86),pindesc(87), + pindesc(88),pindesc(89),pindesc(90),pindesc(91),pindesc(92),pindesc(93),pindesc(94),pindesc(95), + pindesc(96),pindesc(97),pindesc(98),pindesc(99),pindesc(100),pindesc(101),pindesc(102),pindesc(103), + pindesc(104),pindesc(105),pindesc(106),pindesc(107),pindesc(108),pindesc(109),pindesc(110),pindesc(111), + pindesc(112),pindesc(113),pindesc(114),pindesc(115),pindesc(116),pindesc(117),pindesc(118),pindesc(119), + pindesc(120),pindesc(121),pindesc(122),pindesc(123),pindesc(124),pindesc(124),pindesc(126),pindesc(127) + + ); + + + signal dradd : std_logic_vector(7 downto 0); + signal readout : std_logic_vector(31 downto 0); + + begin + process (clk) + begin + if (clk'event and clk = '1') then + if (we = '1') then + RAM(conv_integer(wadd)) <= din; + end if; + dradd <= radd; + end if; + readout <= RAM(conv_integer(dradd)); + dout <= (others => 'Z'); + if re = '1' then + dout <= readout; + end if; + end process; + +end; + + diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/irqlogic.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/irqlogic.vhd new file mode 100644 index 000000000..c8dedb613 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/irqlogic.vhd @@ -0,0 +1,139 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +entity irqlogic is + generic ( + buswidth : integer; + dividerwidth : integer + ); + port ( + clk : in std_logic; + ibus : in std_logic_vector (buswidth-1 downto 0); + obus : out std_logic_vector (buswidth-1 downto 0); + loaddiv : in std_logic; + readdiv : in std_logic; + loadstatus : in std_logic; + readstatus : in std_logic; + clear : in std_logic; + ratesource : in std_logic_vector (4 downto 0); + int : out std_logic); +end irqlogic; + +architecture Behavioral of irqlogic is + +signal irqdiv : std_logic_vector (dividerwidth-1 downto 0); +alias irqdivmsb : std_logic is irqdiv(dividerwidth-1); +signal divlatch : std_logic_vector (dividerwidth-1 downto 0); +signal statusreg : std_logic_vector(4 downto 0); +alias mask : std_logic is statusreg(1); +alias irqff : std_logic is statusreg(0); +alias ratesel : std_logic_vector(2 downto 0) is statusreg(4 downto 2); +signal rated : std_logic_vector(1 downto 0); +signal rate : std_logic; + +begin + + PeriodicIRQlogic : process (clk,statusreg,irqff) + begin + if rising_edge(clk) then + rated <= rated(0) & rate; + if loadstatus = '1' then + statusreg <= ibus(4 downto 0); + end if; + if loaddiv = '1' then + divlatch <= ibus(dividerwidth-1 downto 0); + irqdiv <= ibus(dividerwidth-1 downto 0); + end if; + if rated = "10" then -- falling edge of rate source + if irqdivmsb = '1' then -- note special case where divider latch MSB is set = divide by 1 + irqdiv <= divlatch; + irqff <= '1'; + else + irqdiv <= irqdiv -1; + end if; + end if; -- rate falling edge + if clear = '1' then + irqff <= '0'; + end if; + end if; -- (clk) + obus <= (others => 'Z'); + if readstatus = '1' then + obus(4 downto 0) <= statusreg; + obus(buswidth-1 downto 5) <= (others => '0'); + end if; + if readdiv = '1' then + obus(dividerwidth-1 downto 0) <= divlatch; + obus(buswidth-1 downto dividerwidth) <= (others => '0'); + end if; + int <= not (irqff and mask); + rate <= ratesource(CONV_INTEGER(ratesel)); -- we chose ratesource from appropriate PWM ref gen bit + end process; + +end Behavioral; + diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/kubstepgeny.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/kubstepgeny.vhd new file mode 100644 index 000000000..383900ede --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/kubstepgeny.vhd @@ -0,0 +1,351 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + + +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + + +entity stepgen is + generic ( + buswidth : integer :=32; + timersize : integer := 14; + tablewidth : integer := 6; + asize : integer :=48; + rsize : integer := 32 + ); + Port ( clk : in std_logic; + ibus : in std_logic_vector(buswidth-1 downto 0); + obus : out std_logic_vector(buswidth-1 downto 0); + loadsteprate : in std_logic; + loadaccum : in std_logic; + loadstepmode : in std_logic; + loaddirsetuptime : in std_logic; + loaddirholdtime : in std_logic; + loadpulseactivetime : in std_logic; + loadpulseidletime : in std_logic; + loadtable : in std_logic; + loadtablemax : in std_logic; + readsteprate : in std_logic; + readaccum : in std_logic; + readstepmode : in std_logic; + readdirsetuptime : in std_logic; + readdirholdtime : in std_logic; + readpulseactivetime : in std_logic; + readpulseidletime : in std_logic; + readtable : in std_logic; + readtablemax : in std_logic; + basicrate : in std_logic; + hold : in std_logic; + stout : out std_logic_vector(tablewidth-1 downto 0) + ); +end stepgen; + +architecture Behavioral of stepgen is + + +-- Step Generator related signals + + signal stepaccum: std_logic_vector(asize-1 downto 0); + signal nextaccum: std_logic_vector(asize-1 downto 0); + alias stepmsbs: std_logic_vector(1 downto 0) is stepaccum(rsize-1 downto rsize -2); + alias stepmsb: std_logic is stepaccum(rsize -1); + alias nextmsb: std_logic is nextaccum(rsize -1); + signal dstepmsb : std_logic; + signal ddshold : std_logic; + signal steprate: std_logic_vector(rsize -1 downto 0); + alias stepdir: std_logic is steprate(rsize -1); + signal dstepdir : std_logic; + signal stepdirout : std_logic; + signal pulsewait : std_logic; + signal steppulse : std_logic := '0'; + signal dpulsewait : std_logic := '0'; + signal dirsetupwait : std_logic; + signal dirholdwait : std_logic; + signal ddirholdwait : std_logic; + signal dirshwait : std_logic; + signal dirhold : std_logic; + signal dirshcount: std_logic_vector(timersize-1 downto 0); + signal pulsewidthcount: std_logic_vector(timersize-1 downto 0); + signal dirsetuptime: std_logic_vector(timersize -1 downto 0); + signal dirholdtime: std_logic_vector(timersize -1 downto 0); + signal pulseactivetime: std_logic_vector(timersize -1 downto 0); + signal pulseidletime: std_logic_vector(timersize -1 downto 0); + signal stepmode: std_logic_vector(1 downto 0); + signal localout: std_logic_vector(tablewidth-1 downto 0); + signal wewouldcount : std_logic; + signal dirchange : std_logic; + signal waitforhold : std_logic; + signal waitforpulse : std_logic; + signal tableptr: std_logic_vector(3 downto 0); + signal tablemax: std_logic_vector(3 downto 0); + signal tabledata: std_logic_vector(tablewidth-1 downto 0); + + component SRL16E +-- + generic (INIT : bit_vector); + + +-- + port (D : in std_logic; + CE : in std_logic; + CLK : in std_logic; + A0 : in std_logic; + A1 : in std_logic; + A2 : in std_logic; + A3 : in std_logic; + Q : out std_logic); + end component; + + +begin + + steptable: for i in 0 to tablewidth -1 generate + asr16e: SRL16E generic map (x"0000") port map( + D => ibus(i), + CE => loadtable, + CLK => clk, + A0 => tableptr(0), + A1 => tableptr(1), + A2 => tableptr(2), + A3 => tableptr(3), + Q => tabledata(i) + ); + end generate; + + astepgen: process (clk) + begin + if rising_edge(clk) then + + if basicrate = '1' and hold = '0' and ddshold = '0' then -- our basic step rate DDS + stepaccum <= nextaccum; + dstepdir <= stepdir; -- only updated when we add + end if; + + if pulsewait = '1' then -- our two timers + pulsewidthcount <= pulsewidthcount -1; -- we share dirshcount between setup and hold functions + end if; + + if (pulsewait = '0') and (dpulsewait = '1') and (steppulse = '1') then + pulsewidthcount <= pulseidletime; -- output pulse idle time + steppulse <= '0'; -- clear our output pulse + end if; + + if dirshwait = '1' then + dirshcount <= dirshcount -1; + end if; + + if (stepmsb = '0' and dstepmsb = '1' and dstepdir = '0') -- we counted up + or (stepmsb = '1' and dstepmsb = '0' and dstepdir = '1') then -- we counted down -- the output of the DDS + pulsewidthcount <= pulseactivetime; -- output pulse active time + steppulse <= '1'; + dirshcount <= dirholdtime; -- set pulse to dir change hold timer + dirhold <= '1'; -- set our flag to indicate + else + if dirholdwait = '0' then -- no change during hold time + if stepdirout /= stepdir then -- we changed the external direction signal + dirshcount <= dirsetuptime; -- set dir change to next pulse setup time + dirhold <= '0'; -- set our flag to indicate + stepdirout <= stepdir; + end if; -- our timer is for setup time + end if; + end if; -- our timer is for hold time + + + if (stepmsb = '0' and dstepmsb = '1' and dstepdir = '0') then -- we counted up
+ if (tableptr = tablemax) then + tableptr <= x"0"; + else
+ tableptr <= tableptr +1;
+ end if;
+ end if;
+ if (stepmsb = '1' and dstepmsb = '0' and dstepdir = '1') then -- we counted down
+ if (tableptr = x"0") then
+ tableptr <= tablemax;
+ else + tableptr <= tableptr -1; + end if;
+ end if; + + + if loadstepmode = '1' then -- our register writes + stepmode <= ibus(1 downto 0); + end if; + if loadsteprate = '1' then + steprate <= ibus(rsize -1 downto 0); + end if; + if loadaccum = '1' then + stepaccum(asize -1 downto asize-buswidth) <= ibus; + steppulse <= '0'; + end if; + if loaddirsetuptime = '1' then + dirsetuptime <= ibus(timersize -1 downto 0); + end if; + if loaddirholdtime = '1' then + dirholdtime <= ibus(timersize -1 downto 0); + end if; + if loadpulseactivetime = '1' then + pulseactivetime <= ibus(timersize -1 downto 0); + end if; + if loadpulseidletime = '1' then + pulseidletime <= ibus(timersize -1 downto 0); + end if; + + if loadtablemax = '1' then + tablemax <= ibus(3 downto 0); + tableptr <= x"0"; + end if;
+ + dpulsewait <= pulsewait; + dstepmsb <= stepmsb; + ddirholdwait <= dirholdwait; -- ddirholdwait needed to cover case where dirhold wait has become 0 + end if; -- clk -- but setup timer has not started yet (Probably more elegant to use state machine) + + dirchange <= stepdirout xor stepdir; + wewouldcount <= nextmsb xor stepmsb; + waitforhold <= (dirholdwait or ddirholdwait) and dirchange; + waitforpulse <= pulsewait or dpulsewait; + + nextaccum <= signed(stepaccum)+ signed(steprate); -- to lookahead + + if (wewouldcount = '1') and + (((waitforhold = '1') or (dirsetupwait = '1') or (waitforpulse = '1'))) + then -- need to pause + ddshold <= '1'; + else + ddshold <= '0'; + end if; + + if pulsewidthcount = 0 then + pulsewait <= '0'; + else + pulsewait <= '1'; + end if; + + if dirshcount = 0 then + dirshwait <= '0'; + else + dirshwait <= '1'; + end if; + + dirholdwait <= (dirhold and dirshwait); + dirsetupwait <= (not dirhold) and dirshwait; + + obus <= (others => 'Z'); + +-- if readsteprate = '1' then +-- obus(rsize -1 downto 0) <= steprate; +-- end if; + + if readaccum = '1' then + obus <= stepaccum(asize -1 downto asize-buswidth); + end if; + +-- if readstepmode = '1' then -- register readbacks commented out for size +-- obus(3 downto 0) <= stepmode; +-- obus(31 downto 4) <= (others => '0'); +-- end if; + +-- if readdirsetuptime = '1' then +-- obus(timersize -1 downto 0) <= dirsetuptime; +-- obus(31 downto timersize) <= (others => '0'); +-- end if; +-- if readdirholdtime = '1' then +-- obus(timersize -1 downto 0) <= dirholdtime; +-- obus(31 downto timersize) <= (others => '0'); +-- end if; +-- if readpulseactivetime = '1' then +-- obus(timersize -1 downto 0) <= pulsewidth; +-- obus(31 downto timersize) <= (others => '0'); +-- end if; +-- if readpulseidletime = '1' then +-- obus(timersize -1 downto 0) <= pulseidle; +-- obus(31 downto timersize) <= (others => '0'); +-- end if; + localout <= tabledata; -- this is the default unless: + case stepmode is + when "00" => + localout(0) <= steppulse; -- step + localOut(1) <= stepdirout; -- dir + when "01" => + localout(0) <= steppulse and (not stepdirout); -- count up + localOut(1) <= steppulse and stepdirout; -- count down + when "10" => + case stepmsbs is + when "00" => localout(1 downto 0) <= "00"; -- quadrature + when "01" => localout(1 downto 0) <= "01"; + when "10" => localout (1 downto 0)<= "11"; + when "11" => localout(1 downto 0) <= "10"; + when others => null; + end case; + when others => null; + end case; + stout <= localout; + + end process astepgen; + +end Behavioral; diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/pwmpdmgenh.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/pwmpdmgenh.vhd new file mode 100644 index 000000000..c4bbaa2a1 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/pwmpdmgenh.vhd @@ -0,0 +1,235 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +entity pwmpdmgenh is + generic ( + buswidth : integer; + refwidth : integer + ); + port ( + clk: in std_logic; + hclk: in std_logic; + refcount: in std_logic_vector (refwidth-1 downto 0); + ibus: in std_logic_vector (buswidth -1 downto 0); + loadpwmval: in std_logic; + pcrloadcmd: std_logic; + pdmrate : in std_logic; + pwmouta: out std_logic; + pwmoutb: out std_logic + ); +end pwmpdmgenh; + +architecture behavioral of pwmpdmgenh is + +signal pwmval: std_logic_vector (refwidth-2 downto 0); +signal prepwmval: std_logic_vector (refwidth-2 downto 0); +signal fixedpwmval: std_logic_vector (refwidth-2 downto 0); +signal fixedrefcount: std_logic_vector (refwidth-2 downto 0); +signal pdmaccum: std_logic_vector (refwidth-1 downto 0); +alias pdmbit: std_logic is pdmaccum(refwidth-1); +signal maskedrefcount: std_logic_vector (refwidth-2 downto 0); +signal pwm: std_logic; +signal dir: std_logic; +signal toggle: std_logic; +signal mask: std_logic_vector (refwidth-2 downto 0); +signal predir: std_logic; +signal premodereg: std_logic_vector(5 downto 0); +signal modereg: std_logic_vector(5 downto 0); +alias pwmwidth: std_logic_vector(1 downto 0) is modereg(1 downto 0); +alias pwmmode: std_logic is modereg(2); +alias pwmoutmode: std_logic_vector(1 downto 0) is modereg(4 downto 3); +alias doublebuf: std_logic is modereg(5); +signal loadpwmreq: std_logic; +signal oldloadpwmreq: std_logic; +signal olderloadpwmreq: std_logic; +signal loadpcrreq: std_logic; +signal oldloadpcrreq: std_logic; +signal olderloadpcrreq: std_logic; +signal oldtoggle: std_logic; +signal cyclestart: std_logic; + +begin + apwmgen: process (clk, + hclk, + refcount, + ibus, + loadpwmval, + pwmval, + pwm + ) + + begin + if rising_edge(hclk) then + if pdmrate = '1' then + pdmaccum <= ('0'&pdmaccum(refwidth-2 downto 0)) + ('0'&pwmval); + end if; + if oldloadpwmreq = '1' and olderloadpwmreq = '1' then + pwmval <= prepwmval; + dir <= predir; + end if; + if oldloadpcrreq = '1' and olderloadpcrreq ='1' then + modereg <= premodereg; + end if; + + olderloadpwmreq <= oldloadpwmreq; + olderloadpcrreq <= oldloadpcrreq; + + oldloadpwmreq <= loadpwmreq and (cyclestart or (not doublebuf)); + oldloadpcrreq <= loadpcrreq; + + -- was combinatorial but now pipelined to meet 100 MHz timing + if (UNSIGNED(maskedrefcount) < UNSIGNED(pwmval)) then + pwm <= '1'; + else + pwm <= '0'; + end if; + case pwmmode is + when '0' => fixedrefcount <= refcount(refwidth-2 downto 0); + when '1' => + if toggle = '1' then -- symmetrical mode + fixedrefcount <= (not refcount(refwidth-2 downto 0)); + else + fixedrefcount <= refcount(refwidth-2 downto 0); + end if; + when others => null; + end case; + oldtoggle <= toggle; + end if; -- hclk + + maskedrefcount <= fixedrefcount and mask; + + if pwmmode = '1' then + cyclestart <= ((not toggle) and oldtoggle); -- falling edge of toggle + else + cyclestart <= toggle xor oldtoggle; + end if; + + case pwmwidth is + when "00" => + mask(refwidth-2 downto refwidth-4) <= "000"; + mask(refwidth-5 downto 0) <= ( others => '1'); + toggle <= refcount(refwidth-4); + when "01" => + mask(refwidth-2 downto refwidth-3) <= "00"; + mask(refwidth-4 downto 0) <= ( others => '1'); + toggle <= refcount(refwidth-3); + when "10" => + mask(refwidth-2) <= '0'; + mask(refwidth-3 downto 0) <= ( others => '1'); + toggle <= refcount(refwidth-2); + when "11" => + mask <= (others => '1'); + toggle <= refcount(refwidth-1); + when others => null; + end case; + + if rising_edge(clk) then -- 33/48/50 mhz local bus clock + if loadpwmval = '1' then + prepwmval <= ibus((refwidth-2)+16 downto 16); -- Fixme! only works for buswidth 32 + predir <= ibus(BusWidth -1); + loadpwmreq <= '1'; + end if; + if pcrloadcmd = '1' then + premodereg <= ibus(5 downto 0); + loadpcrreq <= '1'; + end if; + end if; -- clk + + if olderloadpwmreq = '1' then -- asynchronous request clear, could use flancter but dont need async clear + loadpwmreq <= '0'; + end if; + + if olderloadpcrreq = '1' then -- asynchronous request clear "" + loadpcrreq <= '0'; + end if; + + case pwmoutmode is + when "00" => + pwmouta <= pwm; -- normal sign magnitude + pwmoutb <= dir; + when "01" => + pwmouta <= dir; -- reversed pwm/dir = locked antiphase + pwmoutb <= pwm; + when "10" => + if dir = '1' then -- up/down mode + pwmouta <= pwm; + pwmoutb <= '0'; + else + pwmouta <= '0'; + pwmoutb <= pwm; + end if; + when "11" => + pwmouta <= pdmbit; + pwmoutb <= dir; + when others => null; + end case; +-- pwmoutc <= ena; + end process; +end behavioral; + diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/pwmrefh.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/pwmrefh.vhd new file mode 100644 index 000000000..38a982223 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/pwmrefh.vhd @@ -0,0 +1,165 @@ +library IEEE; +use IEEE.std_logic_1164.ALL; +use IEEE.std_logic_ARITH.ALL; +use IEEE.std_logic_UNSIGNED.ALL; +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +entity pwmrefh is + generic ( + buswidth : integer; + refwidth : integer + ); + Port ( + clk: in std_logic; + hclk: in std_logic; + refcount: out std_logic_vector (refwidth-1 downto 0); + ibus: in std_logic_vector (buswidth -1 downto 0); + pdmrate: out std_logic; + pwmrateload: in std_logic; + pdmrateload: in std_logic + ); +end pwmrefh; + +architecture behavioral of pwmrefh is + +signal count: std_logic_vector (refwidth -1 downto 0); +signal pwmrateacc: std_logic_vector (16 downto 0); +alias pwmratemsb: std_logic is pwmrateacc(16); +signal oldpwmratemsb: std_logic; +signal pwmratelatch: std_logic_vector (15 downto 0); +signal prepwmratelatch: std_logic_vector (15 downto 0); +signal pwmratelatchloadreq: std_logic; +signal oldpwmratelatchloadreq: std_logic; +signal olderpwmratelatchloadreq: std_logic; +signal pdmrateacc: std_logic_vector (16 downto 0); +alias pdmratemsb: std_logic is pdmrateacc(16); +signal oldpdmratemsb: std_logic; +signal pdmratelatch: std_logic_vector (15 downto 0); +signal prepdmratelatch: std_logic_vector (15 downto 0); +signal pdmratelatchloadreq: std_logic; +signal oldpdmratelatchloadreq: std_logic; +signal olderpdmratelatchloadreq: std_logic; +signal prate: std_logic; + + +begin + apwmref: process (clk, + + count, + ibus) + begin + if rising_edge(hclk) then -- 100 Mhz high speed clock + + if oldpwmratelatchloadreq = '1' and olderpwmratelatchloadreq = '1' then + pwmratelatch <= prepwmratelatch; + end if; + oldpwmratelatchloadreq <= pwmratelatchloadreq; + olderpwmratelatchloadreq <= oldpwmratelatchloadreq; + pwmrateacc <= pwmrateacc + pwmratelatch; + oldpwmratemsb <= pwmratemsb; + if oldpwmratemsb /= pwmratemsb then + count <= count + 1; + end if; -- old /= new + + + if oldpdmratelatchloadreq = '1' and olderpdmratelatchloadreq = '1' then + pdmratelatch <= prepdmratelatch; + end if; + oldpdmratelatchloadreq <= pdmratelatchloadreq; + olderpdmratelatchloadreq <= oldpdmratelatchloadreq; + pdmrateacc <= pdmrateacc + pdmratelatch; + oldpdmratemsb <= pdmratemsb; + if oldpdmratemsb /= pdmratemsb then + prate <= '1'; + else + prate <= '0'; + end if; -- old /= new + + end if; -- hclk + + if rising_edge(clk) then -- 33/48/50 Mhz local bus clock + if pwmrateload = '1' then + prepwmratelatch <= ibus; + pwmratelatchloadreq <= '1'; + end if; + if pdmrateload = '1' then + prepdmratelatch <= ibus; + pdmratelatchloadreq <= '1'; + end if; + end if; -- clk + + if olderpwmratelatchloadreq = '1' then -- asyncronous request clear + pwmratelatchloadreq <= '0'; + end if; + if olderpdmratelatchloadreq = '1' then -- asyncronous request clear + pdmratelatchloadreq <= '0'; + end if; + refcount <= count; + pdmrate <= prate; + end process; + +end behavioral; + diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/qcounters.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/qcounters.vhd new file mode 100644 index 000000000..b23bb130e --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/qcounters.vhd @@ -0,0 +1,360 @@ +library IEEE; +use IEEE.std_logic_1164.ALL; +use IEEE.std_logic_ARITH.ALL; +use IEEE.std_logic_UNSIGNED.ALL; +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +entity qcounter is + generic ( + buswidth : integer := 32 + ); + port ( + obus: out std_logic_vector (buswidth-1 downto 0); + ibus: in std_logic_vector (buswidth-1 downto 0); + quada: in std_logic; + quadb: in std_logic; + index: in std_logic; + loadccr: in std_logic; + readccr: in std_logic; + readcount: in std_logic; + countclear: in std_logic; + timestamp: in std_logic_vector (15 downto 0); + indexmask: in std_logic; + clk: in std_logic + ); +end qcounter; + +architecture behavioral of qcounter is + +signal count: std_logic_vector (15 downto 0); +signal up: std_logic; +signal down: std_logic; +signal countlatch: std_logic_vector (15 downto 0); +signal timestamplatch: std_logic_vector (15 downto 0); +signal quadadel: std_logic; +signal quada1: std_logic; +signal quada2: std_logic; +signal quadacnt: std_logic_vector (3 downto 0); +signal quadafilt: std_logic; +signal quadbdel: std_logic; +signal quadb1: std_logic; +signal quadb2: std_logic; +signal quadbcnt: std_logic_vector (3 downto 0); +signal quadbfilt: std_logic; +signal indexdel: std_logic; +signal index1: std_logic; +signal index2: std_logic; +signal indexdet: std_logic; +signal indexcnt: std_logic_vector (3 downto 0); +signal indexfilt: std_logic; +signal qcountup: std_logic; +signal qcountdown: std_logic; +signal udcountup: std_logic; +signal udcountdown: std_logic; +signal doclear: std_logic; +signal clearonindex: std_logic; -- ccr register bits... +signal latchonindex:std_logic; +signal justonce: std_logic; +signal abgateindex: std_logic; +signal indexsrc: std_logic; +signal quadfilter: std_logic; +signal countermode: std_logic; +signal quaderror: std_logic; +signal indexpol: std_logic; +signal fixedindexmask: std_logic; +signal indexmaskpol: std_logic; +signal useindexmask: std_logic; +signal abmaskpol: std_logic; +signal flimit: std_logic_vector(3 downto 0); + + +begin + aqcounter: process (clk) + + begin + -- new index logic 02/09/2006 PCW + + if abgateindex = '0' then -- not gated by A,B + if indexpol = '1' then + indexsrc <= indexdel; + else + indexsrc <= not indexdel; + end if; + else -- gated by A,B + if indexpol = '1' then -- normal index + if abmaskpol = '1' then + indexsrc <= quadadel and quadbdel and indexdel; -- enable by A,B high + else + indexsrc <= (not (quadadel or quadbdel)) and indexdel; -- enable by A,B low + end if; + else -- inverted index + if abmaskpol = '1' then + indexsrc <= quadadel and quadbdel and (not indexdel); -- enable by A,B high + else + indexsrc <= (not (quadadel or quadbdel)) and (not indexdel);-- enable by A,B low + end if; + end if; + end if; + + if indexmaskpol = '1' then + fixedindexmask <= indexmask; + else + fixedindexmask <= not indexmask; + end if; + + if quadfilter = '1' then + flimit <= "1111"; + else + flimit <= "0011"; + end if; + if countermode = '0' and doclear = '0' and ( + (quada2 = '0' and quada1 = '1' and quadb2 = '0' and quadb1 = '0') or + (quada2 = '0' and quada1 = '0' and quadb2 = '1' and quadb1 = '0') or + (quada2 = '1' and quada1 = '1' and quadb2 = '0' and quadb1 = '1') or + (quada2 = '1' and quada1 = '0' and quadb2 = '1' and quadb1 = '1')) then + qcountup <= '1'; + else + qcountup <= '0'; + end if; + + if (countermode = '1' and doclear = '0' and + quadb2 = '1' and quada2 = '0' and quada1 = '1') then -- up down mode: count up on rising edge of A when B is high + udcountup <= '1'; + else + udcountup <= '0'; + end if; + + if countermode = '0' and doclear = '0' and ( + (quada2 = '0' and quada1 = '0' and quadb2 = '0' and quadb1 = '1') or + (quada2 = '0' and quada1 = '1' and quadb2 = '1' and quadb1 = '1') or + (quada2 = '1' and quada1 = '0' and quadb2 = '0' and quadb1 = '0') or + (quada2 = '1' and quada1 = '1' and quadb2 = '1' and quadb1 = '0')) then + qcountdown <= '1'; + else + qcountdown <= '0'; + end if; + + if (countermode = '1' and doclear = '0' and + quadb2 = '0' and quada2 = '0' and quada1 = '1') then + udcountdown <= '1'; + else + udcountdown <= '0'; + end if; + + if rising_edge(clk) then + + + quadadel <= quada; + quada1 <= quadafilt; + quada2 <= quada1; + + quadbdel <= quadb; + quadb1 <= quadbfilt; + quadb2 <= quadb1; + + indexdel <= index; + index1 <= indexfilt; + index2 <= index1; + + -- deadended counter for A input filter -- + if (quadadel = '1') and (quadacnt < flimit) then + quadacnt <= quadacnt + 1; + end if; + if (quadadel = '0') and (quadacnt /= 0) then + quadacnt <= quadacnt -1; + end if; + if quadacnt >= flimit then + quadafilt<= '1'; + end if; + if quadacnt = 0 then + quadafilt<= '0'; + end if; + + -- deadended counter for A input filter -- + if (quadbdel = '1') and (quadbcnt < flimit ) then + quadbcnt <= quadbcnt + 1; + end if; + if (quadbdel = '0') and (quadbcnt /= 0) then + quadbcnt <= quadbcnt -1; + end if; + if quadbcnt >= flimit then + quadbfilt<= '1'; + end if; + if quadbcnt = 0 then + quadbfilt <= '0'; + end if; + + -- deadended counter for index input filter -- + if (indexsrc = '1') and (indexcnt < flimit ) then + indexcnt <= indexcnt + 1; + end if; + if (indexsrc = '0') and (indexcnt /= 0) then + indexcnt <= indexcnt -1; + end if; + if indexcnt >= flimit then + indexfilt<= '1'; + end if; + if indexcnt = 0 then + indexfilt<= '0'; + end if; + + if (countclear = '1') or + ((clearonindex = '1') and (indexdet = '1')) then -- rising edge of conditioned index + doclear <= '1'; + if justonce = '1' then + clearonindex <= '0'; + end if; + else + doclear <= '0'; + end if; + + if ((latchonindex = '1') and (indexdet = '1') ) then -- rising edge of conditioned index + countlatch <= count; + if justonce = '1' then + latchonindex <= '0'; + end if; + end if; + + + if countermode = '0' and ( + (quada2 = '0' and quada1 = '1' and quadb2 = '0' and quadb1 = '1') or -- any time both a,b change at same time + (quada2 = '1' and quada1 = '0' and quadb2 = '1' and quadb1 = '0') or -- indicates a quadrature count error + (quada2 = '0' and quada1 = '1' and quadb2 = '1' and quadb1 = '0') or + (quada2 = '1' and quada1 = '0' and quadb2 = '0' and quadb1 = '1')) then + quaderror <= '1'; + end if; + + if up /= down then + timestamplatch <= timestamp; -- time stamp whenever we count + if up = '1' then + count <= count + 1; + else + count <= count - 1; + end if; + end if; + + if doclear = '1' then + count <= x"0000"; + end if; + + if loadccr = '1' then + quaderror <= ibus(15); + abmaskpol <= ibus(14); + quadfilter <= ibus(11); + countermode <= ibus(10); + useindexmask <= ibus(9); + indexmaskpol <= ibus(8); + abgateindex <= ibus(7); + justonce <= ibus(6); + clearonindex <= ibus(5); + latchonindex <= ibus(4); + indexpol <= ibus(3); + end if; + end if; --(clock edge) + + if (index1 = '1') and (index2 = '0') and ((fixedindexmask = '1') or (useindexmask = '0')) then + indexdet <= '1'; + else + indexdet <= '0'; + end if; + + if (qcountup = '1' or udcountup = '1' ) and doclear = '0' then + up <= '1'; + else + up <= '0'; + end if; + + if (qcountdown = '1' or udcountdown = '1' ) and doclear = '0' then + down <= '1'; + else + down <= '0'; + end if; + + obus <= (others => 'Z'); + + if (readcount = '1') then + obus(31 downto 16) <= timestamplatch; + obus(15 downto 0) <= count; + end if; + if (readccr = '1') then + obus(31 downto 16) <= countlatch; + obus(15) <= quaderror; + obus(14) <= abmaskpol; + obus(11) <= quadfilter; + obus(10) <= countermode; + obus(9) <= useindexmask; + obus(8) <= indexmaskpol; + obus(7) <= abgateindex; + obus(6) <= justonce; + obus(5) <= clearonindex; + obus(4) <= latchonindex; + obus(3) <= indexpol; + obus(2) <= index1; + obus(1) <= quadb1; + obus(0) <= quada1; + end if; + end process; +end behavioral; diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/simplespix.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/simplespix.vhd new file mode 100644 index 000000000..bd166290d --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/simplespix.vhd @@ -0,0 +1,193 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +entity simplespi is + generic ( + buswidth : integer + ); + port ( + clk : in std_logic; + ibus : in std_logic_vector(buswidth-1 downto 0); + obus : out std_logic_vector(buswidth-1 downto 0); + loadbitcount : in std_logic; + loadbitrate : in std_logic; + loaddata : in std_logic; + readdata : in std_logic; + readbitcount : in std_logic; + readbitrate : in std_logic; + spiclk : out std_logic; + spiin : in std_logic; + spiout: out std_logic; + spiframe: out std_logic; + davout: out std_logic + ); +end simplespi; + +architecture behavioral of simplespi is + +constant DivWidth: integer := 8; +-- ssi interface related signals + +signal RateDivReg : std_logic_vector(DivWidth -1 downto 0); +signal RateDiv : std_logic_vector(DivWidth -1 downto 0); +signal ModeReg : std_logic_vector(7 downto 0); +alias BitcountReg : std_logic_vector(5 downto 0) is ModeReg(5 downto 0); +alias CPOL : std_logic is ModeReg(6); +alias CPHA : std_logic is ModeReg(7); +signal BitCount : std_logic_vector(5 downto 0); +signal ClockFF: std_logic; +signal SPISreg: std_logic_vector(buswidth-1 downto 0); +signal Go: std_logic; +signal Frame: std_logic; +signal Dav: std_logic; +signal SPIInLatch: std_logic; +signal FirstLeadingEdge: std_logic; + +begin + + aspiinterface: process (clk, readdata, ModeReg, ClockFF, Frame, + SPISreg, readbitcount, BitcountReg, Go, + Dav, readbitrate, RateDivReg) + begin + if rising_edge(clk) then + + if loaddata = '1' then + SPISreg <= ibus; + BitCount <= BitCountReg; + Go <= '1'; + Frame <= '1'; + Dav <= '0'; + ClockFF <= '0'; + FirstLeadingEdge <= '1'; + RateDiv <= RateDivReg; + end if; + + if Frame = '1' then + if RateDiv = 0 then + RateDiv <= RateDivReg; + SPIInLatch <= spiin; + if ClockFF = '0' then + if BitCount(5) = '1' then + Frame <= '0'; -- frame cleared 1/2 SPI clock after GO + Dav <= '1'; + else + ClockFF <= '1'; + end if; + if CPHA = '1' and FirstLeadingEdge = '0' then -- shift out on leading edge for CPHA = 1 case + SPISreg <= SPISreg(30 downto 0) & (SPIInLatch); + end if; + FirstLeadingEdge <= '0'; + else + ClockFF <= '0'; + BitCount <= BitCount -1; + if BitCount(5) = '1' then + Go <= '0'; -- go is clear - no more output clocks + end if; + if CPHA = '0' then -- shift out on trailing edge for CPHA = 0 case + SPISreg <= SPISreg(30 downto 0) & (SPIInLatch); + end if; + end if; + else + RateDiv <= RateDiv -1; + end if; + end if; + + + if loadbitcount = '1' then + ModeReg <= ibus(7 downto 0); + end if; + if loadbitrate = '1' then + RateDivReg <= ibus(DivWidth -1 downto 0); + end if; + + end if; -- clk + + obus <= (others => 'Z'); + if readdata = '1' then + obus <= SPISReg; + end if; + if readbitcount = '1' then + obus(7 downto 0) <= ModeReg; + obus(buswidth -2) <= Go; + obus(buswidth -1) <= Dav; + end if; + if readbitrate = '1' then + obus(DivWidth-1 downto 0) <= RateDivReg; + end if; + spiclk <= (ClockFF and GO) xor CPOL; + spiframe <= not Frame; + davout <= Dav; + for i in 0 to buswidth -1 loop + if i = BitCountReg then + spiout <= SPISReg(i); + end if; + end loop; + end process aspiinterface; + +end Behavioral; diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/timestamp.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/timestamp.vhd new file mode 100644 index 000000000..dd639b78f --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/timestamp.vhd @@ -0,0 +1,113 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + + +entity timestamp is + Port ( ibus : in std_logic_vector(15 downto 0); + obus : out std_logic_vector(15 downto 0); + loadtsdiv : in std_logic; + readts : in std_logic; + readtsdiv : in std_logic; + tscount : out std_logic_vector (15 downto 0); + clk : in std_logic); +end timestamp; + +architecture Behavioral of timestamp is + +signal counter: std_logic_vector (15 downto 0); +signal div: std_logic_vector(15 downto 0); +alias divmsb: std_logic is div(15); +signal divlatch: std_logic_vector (15 downto 0); + +begin + + atimestamp: process (clk) + begin + if rising_edge(clk) then + div <= div -1; + if divmsb = '1' then + div <= divlatch; + counter <= counter + 1; + end if; + if loadtsdiv = '1' then + divlatch <= ibus; + end if; + end if; -- clk + obus <= (others => 'Z'); + if readts = '1' then + obus <= counter; + end if; + if readtsdiv = '1' then + obus <= divlatch; + end if; + tscount <= counter; + end process; + +end Behavioral; diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/uartr.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/uartr.vhd new file mode 100644 index 000000000..c9af12633 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/uartr.vhd @@ -0,0 +1,340 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + + +-- Simple UART with 32 bit bus interface +-- 16 byte deep receive FIFO +-- Can read 4,3,2,1 bytes from FIFO depending on data register read offset +-- Base Address = 1 byte +-- Base Address +1 = 2 bytes +-- Base Address +2 = 3 bytes +-- Base Address +3 = 4 bytes +entity uartr is + port ( + clk : in std_logic; + ibus : in std_logic_vector(31 downto 0); + obus : out std_logic_vector(31 downto 0); + addr : in std_logic_vector(1 downto 0); + popfifo : in std_logic; + loadbitrate : in std_logic; + readbitrate : in std_logic; + clrfifo : in std_logic; + readfifocount : in std_logic; + loadmode : in std_logic; + readmode : in std_logic; + fifohasdata : out std_logic; + rxmask : in std_logic; + rxdata : in std_logic + ); +end uartr; + +architecture Behavioral of uartr is + +-- FIFO related signals + signal pushdata: std_logic_vector(7 downto 0); + signal popadd0: std_logic_vector(3 downto 0) := x"f"; + signal popadd1: std_logic_vector(3 downto 0) := x"f"; + signal popadd2: std_logic_vector(3 downto 0) := x"f"; + signal popadd3: std_logic_vector(3 downto 0) := x"f"; + + signal popdata: std_logic_vector(31 downto 0); + signal datacounter: std_logic_vector(4 downto 0); + signal push: std_logic; + signal pop: std_logic; + signal popsize: std_logic_vector(2 downto 0); + signal clear: std_logic; + signal lfifoempty: std_logic; + signal lfifohasdata: std_logic; + +-- uart interface related signals + +constant DDSWidth : integer := 16; + +signal BitrateDDSReg : std_logic_vector(DDSWidth-1 downto 0); +signal BitrateDDSAccum : std_logic_vector(DDSWidth-1 downto 0); +alias DDSMSB : std_logic is BitrateDDSAccum(15); +signal OldDDSMSB: std_logic; +signal SampleTime: std_logic; +signal BitCount : std_logic_vector(3 downto 0); +signal BytePointer : std_logic_vector(2 downto 0) := "000"; +signal SReg: std_logic_vector(9 downto 0); +alias SregData: std_logic_vector(7 downto 0)is SReg(8 downto 1); +alias StartBit: std_logic is Sreg(0); +alias StopBit: std_logic is Sreg(9); +signal RXPipe : std_logic_vector(1 downto 0); +signal Go: std_logic; +signal DAV: std_logic; +signal ModeReg: std_logic_vector(3 downto 0); +alias FalseStart: std_logic is ModeReg(0); +alias OverRun: std_logic is ModeReg(1); +alias RXMaskEn: std_logic is ModeReg(3); + + component SRL16E +-- + generic (INIT : bit_vector); + + +-- + port (D : in std_logic; + CE : in std_logic; + CLK : in std_logic; + A0 : in std_logic; + A1 : in std_logic; + A2 : in std_logic; + A3 : in std_logic; + Q : out std_logic); + end component; + + +begin + + fifosrl0: for i in 0 to 7 generate + asr16e: SRL16E generic map (x"0000") port map( + D => pushdata(i), + CE => push, + CLK => clk, + A0 => popadd0(0), + A1 => popadd0(1), + A2 => popadd0(2), + A3 => popadd0(3), + Q => popdata(i) + ); + end generate; + + fifosrl1: for i in 0 to 7 generate + asr16e: SRL16E generic map (x"0000") port map( + D => pushdata(i), + CE => push, + CLK => clk, + A0 => popadd1(0), + A1 => popadd1(1), + A2 => popadd1(2), + A3 => popadd1(3), + Q => popdata(8+i) + ); + end generate; + + fifosrl2: for i in 0 to 7 generate + asr16e: SRL16E generic map (x"0000") port map( + D => pushdata(i), + CE => push, + CLK => clk, + A0 => popadd2(0), + A1 => popadd2(1), + A2 => popadd2(2), + A3 => popadd2(3), + Q => popdata(16+i) + ); + end generate; + + fifosrl3: for i in 0 to 7 generate + asr16e: SRL16E generic map (x"0000") port map( + D => pushdata(i), + CE => push, + CLK => clk, + A0 => popadd3(0), + A1 => popadd3(1), + A2 => popadd3(2), + A3 => popadd3(3), + Q => popdata(24+i) + ); + end generate; + + afifo: process (clk,popdata,datacounter) + begin + if rising_edge(clk) then + + if push = '1' and pop = '0' and datacounter /= 16 then -- a push + -- always increment the data counter if not full + datacounter <= datacounter +1; + popadd0 <= popadd0 +1; -- popadd must follow data down shiftreg + end if; + + if (pop = '1') and (push = '0') then -- a pop + datacounter <= datacounter - popsize; + popadd0 <= popadd0 - popsize; + end if; + + if (pop = '1') and (push = '1') then -- simultaneaous pop and push + datacounter <= datacounter - (addr); + popadd0 <= popadd0 - (addr); + end if; + + if clear = '1' then -- a clear fifo + popadd0 <= (others => '1'); + datacounter <= (others => '0'); + end if; + + + end if; -- clk rise + -- The way this mess works is that we have 4 byte wide FIFOs with duplicated data + -- but the readout point is shifted by one byte for each succeeding FIFO so we can read up to + -- 32 bits (4 bytes) at once. Wasteful, but SRL16s are cheap + + + popadd1 <= popadd0 -1; -- note that these are not forced to 0 on underflow + popadd2 <= popadd0 -2; -- so unused bytes of a less than 4 byte read + popadd3 <= popadd0 -3; -- will be stale recv data - not good for security reasons! + -- if this matters, force to 0 on underflow will result in duplicated + -- current data on unused bytes. + + popsize <= ('0'&addr) +1; + + if datacounter = 0 then + lfifoempty <= '1'; + else + lfifoempty <= '0'; + end if; + fifohasdata <= not lfifoempty; + end process afifo; + + + asimpleuartrx: process (clk) + begin + if rising_edge(clk) then + RXPipe <= RXPipe(0) & rxdata; -- Two stage rx data pipeline to compensate for + -- two clock delay from start bit detection to acquire loop startup + + if Go = '1' then + BitRateDDSAccum <= BitRateDDSAccum + BitRateDDSReg; + if SampleTime = '1' then + + if BitCount = 0 then + Go <= '0'; + DAV <= '1'; + if RXPipe(1) = '0' then + OverRun <= '1'; + end if; + end if; + + if BitCount = "1001" then -- false start bit check + if RXPipe(1) = '1' then + Go <= '0'; + FalseStart <= '1'; + end if; + end if; + + SReg <= RXPipe(1) & SReg(9 downto 1); -- right shift = LSb first + BitCount <= BitCount -1; + + end if; + else + BitRateDDSAccum <= (others => '0'); + BitCount <= "1001"; + end if; + + if Go = '0' and rxdata = '0' and (rxmask and RXMaskEn) = '0' then -- start bit detection + Go <= '1'; + end if; + + if DAV = '1' then -- DAV is just one clock wide + DAV <= '0'; + end if; + + OldDDSMSB <= DDSMSB; -- for Phase accumulator MSB edge detection + + if loadbitrate = '1' then + BitRateDDSReg <= ibus(DDSWidth-1 downto 0); + end if; + + if loadmode= '1' then + ModeReg <= ibus(3 downto 0); + end if; + + end if; -- clk + + SampleTime <= (not OldDDSMSB) and DDSMSB; -- sample on rising edge of DDS MSB + pushdata <= SRegData; + push <= DAV; + pop <= popfifo; + clear <= clrfifo; + + obus <= (others => 'Z'); + if readfifocount = '1' then + obus(4 downto 0) <= datacounter; +-- obus(31 downto 5) <= (others => '0'); + end if; + if readbitrate = '1' then + obus(DDSWidth-1 downto 0) <= BitRateDDSReg; + end if; + if popfifo = '1' then + obus <= popdata; + end if; + if readmode = '1' then + obus(3 downto 0) <= ModeReg; + obus(6) <= rxmask; + obus(7) <= not lfifoempty; + + end if; + fifohasdata <= not lfifoempty; + + end process asimpleuartrx; + +end Behavioral; diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/uartx.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/uartx.vhd new file mode 100644 index 000000000..24e5e66fb --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/uartx.vhd @@ -0,0 +1,308 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +entity uartx is + Port ( clk : in std_logic; + ibus : in std_logic_vector(31 downto 0); + obus : out std_logic_vector(31 downto 0); + addr : in std_logic_vector(1 downto 0); + pushfifo : in std_logic; + loadbitrate : in std_logic; + readbitrate : in std_logic; + clrfifo : in std_logic; + readfifocount : in std_logic; + loadmode : in std_logic; + readmode : in std_logic; + fifoempty : out std_logic; + txen : in std_logic; + drven : out std_logic; + txdata : out std_logic + ); +end uartx; + +architecture Behavioral of uartx is + +-- FIFO related signals + signal pushdata: std_logic_vector(33 downto 0); + signal popadd: std_logic_vector(3 downto 0) := x"f"; + signal popdata: std_logic_vector(33 downto 0); + alias byteshere: std_logic_vector(1 downto 0) is popdata(33 downto 32); + signal datacounter: std_logic_vector(4 downto 0); + signal push: std_logic; + signal pop: std_logic; + signal clear: std_logic; + signal lfifoempty: std_logic; + signal fifohasdata: std_logic; + +-- uart interface related signals + +constant DDSWidth : integer := 16; + +signal BitrateDDSReg : std_logic_vector(DDSWidth-1 downto 0); +signal BitrateDDSAccum : std_logic_vector(DDSWidth-1 downto 0); +alias DDSMSB : std_logic is BitrateDDSAccum(15); +signal OldDDSMSB: std_logic; +signal SampleTime: std_logic; +signal BitCount : std_logic_vector(3 downto 0); +signal BytePointer : std_logic_vector(2 downto 0) := "000"; +signal SReg: std_logic_vector(10 downto 0); +signal SendData: std_logic_vector(7 downto 0); +alias SregData: std_logic_vector(7 downto 0)is SReg(9 downto 2); +alias StartBit: std_logic is Sreg(1); +alias StopBit: std_logic is Sreg(10); +alias IdleBit: std_logic is Sreg(0); +signal Go: std_logic := '0'; +signal ModeReg: std_logic_vector(5 downto 0); +alias DriveEnDelay: std_logic_vector(3 downto 0) is ModeReg (3 downto 0); +alias DriveEnAuto: std_logic is ModeReg(4); +alias DriveEnBit: std_logic is ModeReg(5); +signal DriveEnable: std_logic; +signal DriveEnHold: std_logic; +signal WaitingForDrive: std_logic; +signal DriveDelayCount: std_logic_vector(3 downto 0); + + + component SRL16E +-- + generic (INIT : bit_vector); + + +-- + port (D : in std_logic; + CE : in std_logic; + CLK : in std_logic; + A0 : in std_logic; + A1 : in std_logic; + A2 : in std_logic; + A3 : in std_logic; + Q : out std_logic); + end component; + + +begin + + fifosrl: for i in 0 to 33 generate + asr16e: SRL16E generic map (x"0000") port map( + D => pushdata(i), + CE => push, + CLK => clk, + A0 => popadd(0), + A1 => popadd(1), + A2 => popadd(2), + A3 => popadd(3), + Q => popdata(i) + ); + end generate; + + + + afifo: process (clk,popdata,datacounter) + begin + if rising_edge(clk) then + + if push = '1' and pop = '0' and datacounter /= 16 then -- a push + -- always increment the data counter if not full + datacounter <= datacounter +1; + popadd <= popadd +1; -- popadd must follow data down shiftreg + end if; + + if (pop = '1') and (push = '0') and (lfifoempty = '0') then -- a pop + -- always decrement the data counter if not empty + datacounter <= datacounter -1; + popadd <= popadd -1; + end if; + +-- if both push and pop are asserted we dont change either counter + + if clear = '1' then -- a clear fifo + popadd <= (others => '1'); + datacounter <= (others => '0'); + end if; + + + end if; -- clk rise + if datacounter = 0 then + lfifoempty <= '1'; + else + lfifoempty <= '0'; + end if; + fifohasdata <= not lfifoempty; + end process afifo; + + + asimpleuarttx: process (clk) + begin + if rising_edge(clk) then + if Go = '1' then + BitRateDDSAccum <= BitRateDDSAccum - BitRateDDSReg; + if SampleTime = '1' then + SReg <= '1' & SReg(10 downto 1); -- right shift = LSb first + BitCount <= BitCount -1; + if BitCount = 0 then + Go <= '0'; + end if; + end if; + else + BitRateDDSAccum <= (others => '0'); + end if; + + + if pop = '1' then -- just one clock + pop <= '0'; + end if; + + if Go = '0' then + StartBit <= '0'; + StopBit <= '1'; + IdleBit <= '1'; + BitCount <= "1010"; + if fifohasdata = '1' and pop = '0' and txen = '1' and DriveEnHold = '0' then -- UART SReg not busy and we have data + if bytepointer <= ('0'& byteshere) then -- still bytes to send in this double word + SRegData <= SendData; + Go <= '1'; + bytepointer <= bytepointer +1; + else + pop <= '1'; + bytepointer <= "000"; + end if; + end if; + end if; + + + if DriveEnable = '0' then + DriveDelayCount <= DriveEnDelay; + else + if WaitingForDrive = '1' then + DriveDelayCount <= DriveDelayCount -1; + end if; + end if; + + + OldDDSMSB <= DDSMSB; + + if loadbitrate = '1' then + BitRateDDSReg <= ibus(DDSWidth-1 downto 0); + end if; + + if loadmode = '1' then + ModeReg<= ibus(5 downto 0); + end if; + + end if; -- clk + + SampleTime <= (not OldDDSMSB) and DDSMSB; + pushdata <= addr & ibus; -- msbs of FIFO data are address bits to specify data size + push <= pushfifo; + clear <= clrfifo; + + if DriveDelayCount /= 0 then + WaitingForDrive <= '1'; + else + WaitingForDrive <= '0'; + end if; + + DriveEnHold <= (not DriveEnable) or WaitingForDrive; + + if DriveEnAuto = '1' then + DriveEnable <= (Go or Pop or FIFOHasData) and txen; -- note that this means txen should never be removed -- when there is data to xmit + else -- in the middle of a block transmission + DriveEnable <= DriveEnBit; + end if; + + case bytepointer(1 downto 0) is + when "00" => SendData <= PopData(7 downto 0); + when "01" => SendData <= PopData(15 downto 8); + when "10" => SendData <= PopData(23 downto 16); + when "11" => SendData <= PopData(31 downto 24); + when others => null; + end case; + + obus <= (others => 'Z'); + if readfifocount = '1' then + obus(4 downto 0) <= datacounter; + obus(31 downto 5) <= (others => '0'); + end if; + if readbitrate = '1' then + obus(DDSWidth-1 downto 0) <= BitRateDDSReg; + end if; + + if readmode = '1' then + obus(5 downto 0) <= ModeReg; + obus(6) <= txen; + obus(7) <= Go or Pop or FIFOHasData; + end if; + + txdata<= SReg(0); + fifoempty <= lfifoempty; + drven <= DriveEnable; + + end process asimpleuarttx; + +end Behavioral; diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/ubrategen.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/ubrategen.vhd new file mode 100644 index 000000000..07f9fbbda --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/ubrategen.vhd @@ -0,0 +1,114 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +entity rategen is + Port ( ibus : in std_logic_vector(31 downto 0); + obus : out std_logic_vector(31 downto 0); + loadbasicrate : in std_logic; + readbasicrate : in std_logic; + hold : in std_logic; + basicrate : out std_logic; + clk : in std_logic); +end rategen; + +architecture Behavioral of rategen is + +signal rateaccum: std_logic_vector (32 downto 0); +alias ratemsb: std_logic is rateaccum(32); +signal oldratemsb: std_logic; +signal ratelatch: std_logic_vector (31 downto 0); +signal rateout: std_logic; + +begin + + rategen: process (clk) + begin + if rising_edge(clk) then + if hold = '0' then + rateaccum <= rateaccum + ratelatch; + end if; + if oldratemsb /= ratemsb then + rateout <= '1'; + else + rateout <= '0'; + end if; + oldratemsb <= ratemsb; + if loadbasicrate = '1' then + ratelatch <= ibus; + rateaccum <= (others => '0'); + end if; + end if; -- clk + obus <= (others => 'Z'); + if readbasicrate = '1' then + obus <= ratelatch; + end if; + basicrate <= rateout; + end process; + +end Behavioral; diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/watchdog.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/watchdog.vhd new file mode 100644 index 000000000..4c7daad58 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/watchdog.vhd @@ -0,0 +1,144 @@ + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +entity watchdog is + generic ( + buswidth : integer + ); + port ( clk : in std_logic; + ibus : in std_logic_vector (buswidth-1 downto 0); + obus : out std_logic_vector (buswidth-1 downto 0); + loadtime : in std_logic; + readtime : in std_logic; + loadstatus: in std_logic; + readstatus: in std_logic;
+ cookie: in std_logic; + wdbite : out std_logic; + wdlatchedbite : out std_logic ); +end watchdog; + +architecture Behavioral of watchdog is +constant otherz: std_logic_vector (buswidth-2 downto 0) := (others => '0'); +signal wdtimer: std_logic_vector (buswidth-1 downto 0) := '1' & otherz; +signal wdtime: std_logic_vector (buswidth-1 downto 0); +alias wdtimermsb: std_logic is wdtimer(buswidth-1); +signal wdstatus: std_logic := '0'; +signal oldwdtimermsb: std_logic := '0'; + +begin + atimeout: process (clk,wdtimer,wdstatus, + readtime, readstatus, + wdtimermsb, oldwdtimermsb) + begin + if rising_edge(clk) then + + oldwdtimermsb <= wdtimermsb; + + if wdtimermsb /= '1' then + wdtimer <= wdtimer -1; + end if; + + if loadtime = '1' then + wdtimer <= ibus; + wdtime <= ibus;
+ end if; +
+ if cookie = '1' then
+ if ibus(buswidth-1 downto buswidth-8) = x"5A" then
+ wdtimer <= wdtime;
+ end if;
+ end if;
+ + if loadstatus = '1' then + wdstatus <= ibus(0); + end if; + if wdtimermsb = '1' and oldwdtimermsb = '0' then -- edge triggered + wdbite <= '1'; + wdstatus <= '1'; + else + wdbite <= '0'; + end if; + end if; -- clk + obus <= (others =>'Z'); + + if readtime = '1' then + obus <= wdtimer; + end if; + if readstatus = '1' then + obus(0) <= wdstatus; + obus(buswidth -1 downto 1) <= (others => '0'); + end if; + + + wdlatchedbite <= wdstatus; + end process; + +end Behavioral; diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/wordpr.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/wordpr.vhd new file mode 100644 index 000000000..52150672e --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/wordpr.vhd @@ -0,0 +1,170 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +entity wordpr is + generic ( + size : integer := 24; + buswidth : integer := 32 + ); + port ( + clear: in STD_LOGIC; + clk: in STD_LOGIC; + ibus: in STD_LOGIC_VECTOR (buswidth-1 downto 0); + obus: out STD_LOGIC_VECTOR (buswidth-1 downto 0); + loadport: in STD_LOGIC; + loadddr: in STD_LOGIC; + loadaltdatasrc: in STD_LOGIC; + loadopendrainmode: in STD_LOGIC; + loadinvert: in STD_LOGIC; + readddr: in STD_LOGIC; + portdata: out STD_LOGIC_VECTOR (size-1 downto 0); + altdata: in STD_LOGIC_VECTOR (size-1 downto 0) + ); +end wordpr; + +architecture behavioral of wordpr is + +signal outreg: std_logic_vector (size-1 downto 0); +signal ddrreg: std_logic_vector (size-1 downto 0); +signal tsoutreg: std_logic_vector (size-1 downto 0); +signal opendrainsel: std_logic_vector (size-1 downto 0); +signal altdatasel: std_logic_vector (size-1 downto 0); +signal invertsel: std_logic_vector (size-1 downto 0); +signal tdata: std_logic_vector (size-1 downto 0); +signal tddr: std_logic_vector (size-1 downto 0); + +begin + awordioport: process ( + clk, + ibus, + loadport, + loadddr, + readddr, + outreg,ddrreg) + begin + if rising_edge(clk) then + if loadport = '1' then + outreg <= ibus(size-1 downto 0); + end if; + if loadddr = '1' then + ddrreg <= ibus(size-1 downto 0); + end if; + if loadaltdatasrc = '1' then + altdatasel <= ibus(size-1 downto 0); + end if; + if loadopendrainmode = '1' then + opendrainsel <= ibus(size-1 downto 0); + end if; + if loadinvert = '1' then + invertsel <= ibus(size-1 downto 0); + end if; + if clear = '1' then + ddrreg <= (others => '0'); + opendrainsel <= (others => '0'); + end if; + end if; -- clk + + for i in 0 to size-1 loop + if altdatasel(i) = '0' then + if invertsel(i) = '0' then -- normal output data, normal outputs can be inverted + tdata(i) <= outreg(i); + else + tdata(i) <= not outreg(i); + end if; + else + if invertsel(i) = '0' then -- alternate output data, alternate outputs can be inverted + tdata(i) <= altdata(i); + else + tdata(i) <= not altdata(i); + end if; + end if; + if opendrainsel(i) = '0' then -- normal DDR + if ddrreg(i) = '1' then + tsoutreg(i) <= tdata(i); + else + tsoutreg(i) <= 'Z'; + end if; + else + if tdata(i) = '0' then -- open drain option = active pulldown + tsoutreg(i) <= '0'; + else + tsoutreg(i) <= 'Z'; + end if; + end if; + end loop; + + portdata <= tsoutreg; + obus <= (others => 'Z'); + if readddr = '1' then + obus(size-1 downto 0) <= ddrreg; + obus(buswidth -1 downto size) <= (others => '0'); + end if; + + end process; +end behavioral; diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/src/wordrb.vhd b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/wordrb.vhd new file mode 100644 index 000000000..f2569ac0a --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/src/wordrb.vhd @@ -0,0 +1,91 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +-- +-- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics +-- http://www.mesanet.com +-- +-- This program is is licensed under a disjunctive dual license giving you +-- the choice of one of the two following sets of free software/open source +-- licensing terms: +-- +-- * GNU General Public License (GPL), version 2.0 or later +-- * 3-clause BSD License +-- +-- +-- The GNU GPL License: +-- +-- 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. +-- +-- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- +-- +-- The 3-clause BSD License: +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above +-- copyright notice, this list of conditions and the following +-- disclaimer in the documentation and/or other materials +-- provided with the distribution. +-- +-- * Neither the name of Mesa Electronics nor the names of its +-- contributors may be used to endorse or promote products +-- derived from this software without specific prior written +-- permission. +-- +-- +-- Disclaimer: +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +entity wordrb is + generic (size : integer; + buswidth : integer); + port ( + obus: out STD_LOGIC_VECTOR (31 downto 0); + readport: in STD_LOGIC; + portdata: in STD_LOGIC_VECTOR (size-1 downto 0) ); +end wordrb; + +architecture behavioral of wordrb is + +begin + awordiorb: process (portdata,readport) + begin + obus <= (others => 'Z'); + if readport = '1' then + obus(size-1 downto 0) <= portdata; + obus(buswidth -1 downto size) <= (others => '0'); + end if; + end process; + +end behavioral; diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/sv8_2.bit b/src/hal/drivers/mesa7i43-firmware/hostmot2/sv8_2.bit Binary files differnew file mode 100644 index 000000000..4a3fa6814 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/sv8_2.bit diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/sv8_4.bit b/src/hal/drivers/mesa7i43-firmware/hostmot2/sv8_4.bit Binary files differnew file mode 100644 index 000000000..a2ea8552e --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/sv8_4.bit diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/svst44_2.bit b/src/hal/drivers/mesa7i43-firmware/hostmot2/svst44_2.bit Binary files differnew file mode 100644 index 000000000..d7913e8eb --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/svst44_2.bit diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/svst44_4.bit b/src/hal/drivers/mesa7i43-firmware/hostmot2/svst44_4.bit Binary files differnew file mode 100644 index 000000000..6f861bfb8 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/svst44_4.bit diff --git a/src/hal/drivers/mesa7i43-firmware/hostmot2/svst46_4.bit b/src/hal/drivers/mesa7i43-firmware/hostmot2/svst46_4.bit Binary files differnew file mode 100644 index 000000000..367d0e165 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/hostmot2/svst46_4.bit diff --git a/src/hal/drivers/mesa7i43-firmware/source/epp-iopr8.ise b/src/hal/drivers/mesa7i43-firmware/source/epp-iopr8.ise Binary files differindex 71b0900f1..961d17283 100644 --- a/src/hal/drivers/mesa7i43-firmware/source/epp-iopr8.ise +++ b/src/hal/drivers/mesa7i43-firmware/source/epp-iopr8.ise diff --git a/src/hal/drivers/mesa7i43-firmware/source/idinfo.vhd b/src/hal/drivers/mesa7i43-firmware/source/idinfo.vhd new file mode 100644 index 000000000..3fa6e9816 --- /dev/null +++ b/src/hal/drivers/mesa7i43-firmware/source/idinfo.vhd @@ -0,0 +1,81 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 15:38:30 12/17/2007 +-- Design Name: +-- Module Name: idinfo - Behavioral +-- Project Name: +-- Target Devices: +-- Tool versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +entity idinfo is + generic (
+ width : integer;
+ cookie : std_logic_vector (31 downto 0);
+ namelow : std_logic_vector (31 downto 0);
+ namehigh : std_logic_vector (31 downto 0);
+ version : std_logic_vector (31 downto 0)
+ ); + port (
+ obus : out std_logic_vector (width-1 downto 0); + addr : in std_logic_vector (width-1 downto 0); + read : in std_logic); +end idinfo; + +architecture Behavioral of idinfo is +begin
+
+ idinfoproc: process (read,addr) + begin + obus <= (others => 'Z'); + if addr (6 downto 2) = "00000" and read = '1' then + case addr (1 downto 0) is + when "00" => obus <= Cookie(7 downto 0); + when "01" => obus <= Cookie(15 downto 8); + when "10" => obus <= Cookie(23 downto 16); + when "11" => obus <= Cookie(31 downto 24); + when others => null; + end case; + end if; + if addr (6 downto 2) = "00001" and read = '1' then + case addr (1 downto 0) is + when "00" => obus <= NameLow(31 downto 24);
+ when "01" => obus <= NameLow(23 downto 16);
+ when "10" => obus <= NameLow(15 downto 8); + when "11" => obus <= NameLow(7 downto 0); + when others => null; + end case; + end if; + if addr (6 downto 2) = "00010" and read = '1' then + case addr (1 downto 0) is + when "00" => obus <= NameHigh(31 downto 24);
+ when "01" => obus <= NameHigh(23 downto 16);
+ when "10" => obus <= NameHigh(15 downto 8);
+ when "11" => obus <= NameHigh(7 downto 0); + when others => null; + end case; + end if; + if addr (6 downto 2) = "00011" and read = '1' then + case addr (1 downto 0) is + when "00" => obus <= Version(7 downto 0); + when "01" => obus <= Version(15 downto 8); + when "10" => obus <= Version(23 downto 16); + when "11" => obus <= Version(31 downto 24); + when others => null; + end case; + end if; + end process; + +end Behavioral; diff --git a/src/hal/drivers/mesa7i43-firmware/source/ioport.vhd b/src/hal/drivers/mesa7i43-firmware/source/ioport.vhd index 5d66e64bb..07a0bb985 100644 --- a/src/hal/drivers/mesa7i43-firmware/source/ioport.vhd +++ b/src/hal/drivers/mesa7i43-firmware/source/ioport.vhd @@ -1,69 +1,3 @@ - --- --- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics --- http://www.mesanet.com --- --- This program is is licensed under a disjunctive dual license giving you --- the choice of one of the two following sets of free software/open source --- licensing terms: --- --- * GNU General Public License (GPL), version 2.0 or later --- * 3-clause BSD License --- --- --- The GNU GPL License: --- --- 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. --- --- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --- --- --- The 3-clause BSD License: --- --- Redistribution and use in source and binary forms, with or without --- modification, are permitted provided that the following conditions --- are met: --- --- * Redistributions of source code must retain the above copyright --- notice, this list of conditions and the following disclaimer. --- --- * Redistributions in binary form must reproduce the above --- copyright notice, this list of conditions and the following --- disclaimer in the documentation and/or other materials --- provided with the distribution. --- --- * Neither the name of Mesa Electronics nor the names of its --- contributors may be used to endorse or promote products --- derived from this software without specific prior written --- permission. --- --- --- Disclaimer: --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT --- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS --- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE --- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, --- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, --- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; --- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER --- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT --- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN --- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- - library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; diff --git a/src/hal/drivers/mesa7i43-firmware/source/ioportrb.vhd b/src/hal/drivers/mesa7i43-firmware/source/ioportrb.vhd index ab27bcb70..0d120ce34 100644 --- a/src/hal/drivers/mesa7i43-firmware/source/ioportrb.vhd +++ b/src/hal/drivers/mesa7i43-firmware/source/ioportrb.vhd @@ -1,69 +1,3 @@ - --- --- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics --- http://www.mesanet.com --- --- This program is is licensed under a disjunctive dual license giving you --- the choice of one of the two following sets of free software/open source --- licensing terms: --- --- * GNU General Public License (GPL), version 2.0 or later --- * 3-clause BSD License --- --- --- The GNU GPL License: --- --- 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. --- --- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --- --- --- The 3-clause BSD License: --- --- Redistribution and use in source and binary forms, with or without --- modification, are permitted provided that the following conditions --- are met: --- --- * Redistributions of source code must retain the above copyright --- notice, this list of conditions and the following disclaimer. --- --- * Redistributions in binary form must reproduce the above --- copyright notice, this list of conditions and the following --- disclaimer in the documentation and/or other materials --- provided with the distribution. --- --- * Neither the name of Mesa Electronics nor the names of its --- contributors may be used to endorse or promote products --- derived from this software without specific prior written --- permission. --- --- --- Disclaimer: --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT --- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS --- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE --- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, --- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, --- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; --- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER --- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT --- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN --- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- - library IEEE; use IEEE.std_logic_1164.ALL; use IEEE.std_logic_ARITH.ALL; diff --git a/src/hal/drivers/mesa7i43-firmware/source/main.vhd b/src/hal/drivers/mesa7i43-firmware/source/main.vhd index 8bfa87fcd..0ba70033a 100644 --- a/src/hal/drivers/mesa7i43-firmware/source/main.vhd +++ b/src/hal/drivers/mesa7i43-firmware/source/main.vhd @@ -1,69 +1,3 @@ - --- --- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics --- http://www.mesanet.com --- --- This program is is licensed under a disjunctive dual license giving you --- the choice of one of the two following sets of free software/open source --- licensing terms: --- --- * GNU General Public License (GPL), version 2.0 or later --- * 3-clause BSD License --- --- --- The GNU GPL License: --- --- 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. --- --- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --- --- --- The 3-clause BSD License: --- --- Redistribution and use in source and binary forms, with or without --- modification, are permitted provided that the following conditions --- are met: --- --- * Redistributions of source code must retain the above copyright --- notice, this list of conditions and the following disclaimer. --- --- * Redistributions in binary form must reproduce the above --- copyright notice, this list of conditions and the following --- disclaimer in the documentation and/or other materials --- provided with the distribution. --- --- * Neither the name of Mesa Electronics nor the names of its --- contributors may be used to endorse or promote products --- derived from this software without specific prior written --- permission. --- --- --- Disclaimer: --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT --- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS --- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE --- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, --- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, --- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; --- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER --- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT --- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN --- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- - library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; @@ -76,7 +10,12 @@ use IEEE.STD_LOGIC_UNSIGNED.ALL; entity main is generic - ( Nports : integer := 6 + ( Nports : integer := 6; + Cookie : Std_Logic_Vector(31 downto 0) := x"55AACAFE"; + NameLow : Std_Logic_Vector(31 downto 0) := x"45505049"; +-- NameHigh : Std_Logic_Vector(31 downto 0) := x"4F382D34"; -- 400K + NameHigh : Std_Logic_Vector(31 downto 0) := x"4F382D32"; -- 200K + Version : Std_Logic_Vector(31 downto 0) := x"00000001" ); Port ( CLK : in std_logic; @@ -98,30 +37,28 @@ end main; architecture Behavioral of main is - function OneOfSixDecode(ena1 : std_logic;ena2 : std_logic; dec : std_logic_vector(2 downto 0)) return std_logic_vector is - variable result : std_logic_vector(5 downto 0); - begin + function OneOfNdecode(width : integer;ena1 : std_logic;ena2 : std_logic; dec : std_logic_vector) return std_logic_vector is + variable result : std_logic_vector(width-1 downto 0); + begin if ena1 = '1' and ena2 = '1' then - case dec is - when "000" => result := "000001"; - when "001" => result := "000010"; - when "010" => result := "000100"; - when "011" => result := "001000"; - when "100" => result := "010000"; - when "101" => result := "100000"; - when others => result := "000000"; - end case; - else - result := "000000"; + for i in 0 to width -1 loop + if CONV_INTEGER(dec) = i then + result(i) := '1'; + else + result(i) := '0'; + end if; + end loop; + else + result := (others => '0'); end if; return result; - end OneOfSixDecode; + end OneOfNDecode; signal afcnt : std_logic_vector(1 downto 0); signal afilter : std_logic_vector(1 downto 0); signal dfcnt : std_logic_vector(1 downto 0); signal dfilter : std_logic_vector(1 downto 0); -signal waitpipe : std_logic_vector(1 downto 0); +signal waitpipe : std_logic_vector(5 downto 0); signal alatch : std_logic_vector(7 downto 0); signal seladd : std_logic_vector(7 downto 0); signal aread : std_logic; @@ -151,6 +88,21 @@ signal ReadSPICS : std_logic; begin + id: entity idinfo + generic map + ( + width => 8, + cookie => Cookie, + namelow => NameLow, + namehigh => NameHigh, + version => Version + ) + port map ( + obus => idata, + addr => alatch, + read => dread + ); + makeoports: for i in 0 to NPorts-1 generate oportx: entity ioport generic map (Width => 8) @@ -204,7 +156,8 @@ begin EPPInterface: process(clk, waitpipe, alatch, afilter, dfilter, - EPP_READ, EPP_DSTROBE, EPP_ASTROBE) + EPP_READ, EPP_DSTROBE, EPP_ASTROBE, + depp_dstrobe, depp_astrobe) begin if rising_edge(CLK) then @@ -212,13 +165,12 @@ begin depp_astrobe <= EPP_ASTROBE; afilter(1) <= afilter(0); dfilter(1) <= dfilter(0); - waitpipe(1) <= waitpipe(0); - if depp_dstrobe = '0' or depp_astrobe = '0' then - waitpipe(0) <= '1'; + + if (depp_dstrobe = '0') or (depp_astrobe = '0') then + waitpipe <= waitpipe(4 downto 0) & '1'; -- left shift in a 1 else - waitpipe(0) <= '0'; - end if; - + waitpipe <= "000000"; + end if; if depp_astrobe = '0' then if afcnt /= "11" then @@ -251,7 +203,6 @@ begin if dfcnt = "00" then dfilter(0) <= '0'; end if; - if awrite = '1' then alatch <= EPP_DATABUS; @@ -263,7 +214,7 @@ begin end if; -- clk - EPP_WAIT <= waitpipe(1); + EPP_WAIT <= waitpipe(5); if dfilter = "01" and EPP_READ = '0' then -- generate write 80 ns after leading edge of strobe dwrite <= '1'; @@ -345,11 +296,11 @@ begin end if; - LoadPortCmd <= OneOfSixDecode(PortSel,dwrite,alatch(2 downto 0)); - ReadPortCmd <= OneOfSixDecode(PortSel,dread,alatch(2 downto 0)); + LoadPortCmd <= OneOfNDecode(Nports,PortSel,dwrite,alatch(2 downto 0)); + ReadPortCmd <= OneOfNDecode(Nports,PortSel,dread,alatch(2 downto 0)); - LoadDDRCmd <= OneOfSixDecode(PortDDRSel,dwrite,alatch(2 downto 0)); - ReadDDRCmd <= OneOfSixDecode(PortDDRSel,dread,alatch(2 downto 0)); + LoadDDRCmd <= OneOfNDecode(Nports,PortDDRSel,dwrite,alatch(2 downto 0)); + ReadDDRCmd <= OneOfNDecode(Nports,PortDDRSel,dread,alatch(2 downto 0)); end process iodecode; @@ -378,4 +329,4 @@ begin PARACONFIG <= '1'; end process BusDrive; -end Behavioral; +end; diff --git a/src/hal/drivers/mesa7i43-firmware/source/simplespid.vhd b/src/hal/drivers/mesa7i43-firmware/source/simplespid.vhd index 6428f9edd..c1feef6fe 100644 --- a/src/hal/drivers/mesa7i43-firmware/source/simplespid.vhd +++ b/src/hal/drivers/mesa7i43-firmware/source/simplespid.vhd @@ -1,69 +1,3 @@ - --- --- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics --- http://www.mesanet.com --- --- This program is is licensed under a disjunctive dual license giving you --- the choice of one of the two following sets of free software/open source --- licensing terms: --- --- * GNU General Public License (GPL), version 2.0 or later --- * 3-clause BSD License --- --- --- The GNU GPL License: --- --- 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. --- --- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --- --- --- The 3-clause BSD License: --- --- Redistribution and use in source and binary forms, with or without --- modification, are permitted provided that the following conditions --- are met: --- --- * Redistributions of source code must retain the above copyright --- notice, this list of conditions and the following disclaimer. --- --- * Redistributions in binary form must reproduce the above --- copyright notice, this list of conditions and the following --- disclaimer in the documentation and/or other materials --- provided with the distribution. --- --- * Neither the name of Mesa Electronics nor the names of its --- contributors may be used to endorse or promote products --- derived from this software without specific prior written --- permission. --- --- --- Disclaimer: --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT --- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS --- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE --- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, --- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, --- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; --- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER --- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT --- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN --- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- - library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; @@ -110,7 +44,7 @@ signal CS : std_logic := '1'; begin - aspiinterface: process (clk, readdata, Go, DAV, + aspiinterface: process (clk, readdata, Go, DAV, SPIOutDel, SPISreg, readcs, CS, ClockFF) begin if rising_edge(clk) then |