@@ -0,0 +1,789 @@ | |||||
# | |||||
# Automatically generated make config: don't edit | |||||
# Sat Feb 6 10:24:49 2010 | |||||
# | |||||
BR2_HAVE_DOT_CONFIG=y | |||||
BR2_VERSION="2009.08" | |||||
# BR2_alpha is not set | |||||
BR2_arm=y | |||||
# BR2_armeb is not set | |||||
# BR2_avr32 is not set | |||||
# BR2_cris is not set | |||||
# BR2_ia64 is not set | |||||
# BR2_i386 is not set | |||||
# BR2_m68k is not set | |||||
# BR2_mips is not set | |||||
# BR2_mipsel is not set | |||||
# BR2_nios2 is not set | |||||
# BR2_powerpc is not set | |||||
# BR2_sh is not set | |||||
# BR2_sh64 is not set | |||||
# BR2_sparc is not set | |||||
# BR2_sparc64 is not set | |||||
# BR2_x86_64 is not set | |||||
# BR2_xtensa is not set | |||||
# BR2_generic_arm is not set | |||||
# BR2_arm7tdmi is not set | |||||
# BR2_arm610 is not set | |||||
# BR2_arm710 is not set | |||||
# BR2_arm720t is not set | |||||
# BR2_arm920t is not set | |||||
# BR2_arm922t is not set | |||||
BR2_arm926t=y | |||||
# BR2_arm10t is not set | |||||
# BR2_arm1136jf_s is not set | |||||
# BR2_arm1176jz_s is not set | |||||
# BR2_arm1176jzf_s is not set | |||||
# BR2_sa110 is not set | |||||
# BR2_sa1100 is not set | |||||
# BR2_xscale is not set | |||||
# BR2_iwmmxt is not set | |||||
BR2_ARM_TYPE="ARM926T" | |||||
BR2_ARM_OABI=y | |||||
# BR2_ARM_EABI is not set | |||||
BR2_ARCH="arm" | |||||
BR2_ENDIAN="LITTLE" | |||||
BR2_GCC_TARGET_TUNE="arm9tdmi" | |||||
BR2_GCC_TARGET_ARCH="armv5te" | |||||
BR2_GCC_TARGET_ABI="apcs-gnu" | |||||
# | |||||
# Target options | |||||
# | |||||
# | |||||
# Project Options | |||||
# | |||||
BR2_PROJECT="LiCKS" | |||||
BR2_HOSTNAME="licks" | |||||
BR2_BANNER="Welcome to LiCKS!" | |||||
# | |||||
# Preset Devices | |||||
# | |||||
# BR2_TARGET_AMD is not set | |||||
# BR2_TARGET_ARMLTD is not set | |||||
BR2_BOARD_NAME="at91sam9260ek" | |||||
BR2_BOARD_PATH="target/device/Atmel/$(BR2_BOARD_NAME)" | |||||
BR2_TARGET_ATMEL=y | |||||
# | |||||
# Atmel AT91 Specific Device Support | |||||
# | |||||
BR2_TARGET_AT91=y | |||||
# | |||||
# Selection criteria | |||||
# | |||||
BR2_TARGET_ATMEL_ALL=y | |||||
# | |||||
# Device Selection | |||||
# | |||||
# BR2_TARGET_AT91RM9200 is not set | |||||
BR2_TARGET_AT91SAM9260=y | |||||
# BR2_TARGET_AT91SAM9G20 is not set | |||||
# BR2_TARGET_AT91SAM9261 is not set | |||||
# BR2_TARGET_AT91SAM9261S is not set | |||||
# BR2_TARGET_AT91SAM9RL64 is not set | |||||
# BR2_TARGET_AT91SAM9263 is not set | |||||
# BR2_TARGET_AT91SAM9G40 is not set | |||||
# BR2_TARGET_AT91SAM9M10 is not set | |||||
# BR2_TARGET_AT91SAM9M11 is not set | |||||
# BR2_TARGET_AT91SAM9XE is not set | |||||
# BR2_TARGET_AT572D940HF is not set | |||||
# BR2_TARGET_AT91CAP9 is not set | |||||
# | |||||
# Development Board Selection | |||||
# | |||||
# BR2_TARGET_AT91RM9200DF is not set | |||||
# BR2_TARGET_AT91RM9200EK is not set | |||||
# BR2_TARGET_AT91RM9200DK is not set | |||||
# BR2_TARGET_AT91SAM9260DFC is not set | |||||
BR2_TARGET_AT91SAM9260EK=y | |||||
# BR2_TARGET_AT91SAM9G20DFC is not set | |||||
# BR2_TARGET_AT91SAM9G20EK is not set | |||||
# BR2_TARGET_AT91SAM9XEEK is not set | |||||
# BR2_TARGET_AT91SAM9261EK is not set | |||||
# BR2_TARGET_AT91SAM9RL64EK is not set | |||||
# BR2_TARGET_AT91SAM9263EK is not set | |||||
# BR2_TARGET_AT572D940DCM is not set | |||||
# BR2_TARGET_AT91CAP9DK is not set | |||||
# BR2_TARGET_AT91CAP9ADK is not set | |||||
BR2_TARGET_AT91_ADVANCED_INFO=y | |||||
# | |||||
# Package support | |||||
# | |||||
# | |||||
# Secondary locations | |||||
# | |||||
BR2_AT91_LINUXPATCH_SITE="http://maxim.org.za/AT91RM9200/2.6" | |||||
BR2_TARGET_ATMEL_COPYTO="/tftpboot" | |||||
# BR2_TARGET_AT91BOOTSTRAP is not set | |||||
# BR2_TARGET_KWIKBYTE is not set | |||||
# | |||||
# Generic System Support | |||||
# | |||||
# BR2_TARGET_GENERIC_ACCESS_POINT is not set | |||||
# BR2_TARGET_GENERIC_FIREWALL is not set | |||||
# | |||||
# Generic development system requires a toolchain with WCHAR and PROGRAM_INVOCATION support | |||||
# | |||||
# | |||||
# Build options | |||||
# | |||||
BR2_WGET="wget --passive-ftp -nd" | |||||
BR2_SVN_CO="svn co" | |||||
BR2_SVN_UP="svn up" | |||||
BR2_GIT="git clone" | |||||
BR2_ZCAT="gzip -d -c" | |||||
BR2_BZCAT="bzcat" | |||||
BR2_TAR_OPTIONS="" | |||||
BR2_DL_DIR="$(BASE_DIR)/dl" | |||||
BR2_COPYTO="" | |||||
# | |||||
# Mirrors and Download locations | |||||
# | |||||
BR2_PRIMARY_SITE="" | |||||
BR2_BACKUP_SITE="http://buildroot.net/downloads/sources/" | |||||
BR2_SOURCEFORGE_MIRROR="easynews" | |||||
BR2_KERNEL_MIRROR="http://www.kernel.org/pub/" | |||||
BR2_GNU_MIRROR="http://ftp.gnu.org/pub/gnu" | |||||
BR2_DEBIAN_MIRROR="http://ftp.debian.org" | |||||
# | |||||
# Atmel Mirrors | |||||
# | |||||
BR2_ATMEL_MIRROR="ftp://www.at91.com/pub/buildroot/" | |||||
BR2_AT91_PATCH_MIRROR="http://maxim.org.za/AT91RM9200/2.6/" | |||||
BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir" | |||||
# BR2_FPU_SUFFIX is not set | |||||
BR2_TOPDIR_PREFIX="" | |||||
BR2_TOPDIR_SUFFIX="" | |||||
BR2_GNU_BUILD_SUFFIX="pc-linux-gnu" | |||||
BR2_GNU_TARGET_SUFFIX="linux-uclibc" | |||||
BR2_JLEVEL=1 | |||||
# BR2_PREFER_IMA is not set | |||||
# BR2_DEPRECATED is not set | |||||
BR2_RECENT=y | |||||
# BR2_CONFIG_CACHE is not set | |||||
# BR2_ENABLE_DEBUG is not set | |||||
BR2_STRIP_strip=y | |||||
# BR2_STRIP_sstrip is not set | |||||
# BR2_STRIP_none is not set | |||||
# BR2_OPTIMIZE_0 is not set | |||||
# BR2_OPTIMIZE_1 is not set | |||||
# BR2_OPTIMIZE_2 is not set | |||||
# BR2_OPTIMIZE_3 is not set | |||||
BR2_OPTIMIZE_S=y | |||||
# BR2_PREFER_STATIC_LIB is not set | |||||
# BR2_HAVE_MANPAGES is not set | |||||
# BR2_HAVE_INFOPAGES is not set | |||||
# BR2_HAVE_DOCUMENTATION is not set | |||||
# BR2_HAVE_DEVFILES is not set | |||||
BR2_UPDATE_CONFIG=y | |||||
# | |||||
# Toolchain | |||||
# | |||||
BR2_TOOLCHAIN_BUILDROOT=y | |||||
# BR2_TOOLCHAIN_EXTERNAL is not set | |||||
# BR2_TOOLCHAIN_EXTERNAL_SOURCE is not set | |||||
BR2_TOOLCHAIN_SOURCE=y | |||||
BR2_EXT_GCC_VERSION_4_1_2=y | |||||
BR2_EXT_GCC_VERSION_4_2_1=y | |||||
BR2_EXT_GCC_VERSION_4_2_2=y | |||||
BR2_EXT_GCC_VERSION_4_2_3=y | |||||
BR2_EXT_BINUTILS_VERSION_2_17=y | |||||
BR2_EXT_BINUTILS_VERSION_2_18=y | |||||
BR2_EXT_UCLIBC_VERSION_0_9_28_3=y | |||||
BR2_EXT_UCLIBC_VERSION_0_9_29=y | |||||
BR2_EXT_UCLIBC_VERSION_0_9_30=y | |||||
BR2_EXT_UCLIBC_VERSION_0_9_30_1=y | |||||
# | |||||
# Kernel Header Options | |||||
# | |||||
# BR2_KERNEL_HEADERS_2_6_26 is not set | |||||
# BR2_KERNEL_HEADERS_2_6_27 is not set | |||||
# BR2_KERNEL_HEADERS_2_6_28 is not set | |||||
# BR2_KERNEL_HEADERS_2_6_29 is not set | |||||
BR2_KERNEL_HEADERS_2_6_30=y | |||||
# BR2_KERNEL_HEADERS_SNAP is not set | |||||
BR2_DEFAULT_KERNEL_HEADERS="2.6.30.5" | |||||
# | |||||
# uClibc Options | |||||
# | |||||
# BR2_UCLIBC_VERSION_0_9_28_3 is not set | |||||
# BR2_UCLIBC_VERSION_0_9_29 is not set | |||||
# BR2_UCLIBC_VERSION_0_9_30 is not set | |||||
BR2_UCLIBC_VERSION_0_9_30_1=y | |||||
# BR2_UCLIBC_VERSION_SNAPSHOT is not set | |||||
BR2_UCLIBC_VERSION_STRING="0.9.30.1" | |||||
BR2_UCLIBC_CONFIG="toolchain/uClibc/uClibc-0.9.30.config" | |||||
# BR2_PTHREAD_DEBUG is not set | |||||
# BR2_UCLIBC_INSTALL_TEST_SUITE is not set | |||||
# | |||||
# Binutils Options | |||||
# | |||||
# BR2_BINUTILS_VERSION_2_17 is not set | |||||
# BR2_BINUTILS_VERSION_2_17_50_0_17 is not set | |||||
# BR2_BINUTILS_VERSION_2_18 is not set | |||||
# BR2_BINUTILS_VERSION_2_18_50_0_1 is not set | |||||
# BR2_BINUTILS_VERSION_2_18_50_0_3 is not set | |||||
# BR2_BINUTILS_VERSION_2_18_50_0_6 is not set | |||||
# BR2_BINUTILS_VERSION_2_18_50_0_8 is not set | |||||
# BR2_BINUTILS_VERSION_2_18_50_0_9 is not set | |||||
# BR2_BINUTILS_VERSION_2_19 is not set | |||||
BR2_BINUTILS_VERSION_2_19_1=y | |||||
BR2_BINUTILS_VERSION="2.19.1" | |||||
BR2_EXTRA_BINUTILS_CONFIG_OPTIONS="" | |||||
# | |||||
# GCC Options | |||||
# | |||||
# BR2_GCC_VERSION_3_4_6 is not set | |||||
# BR2_GCC_VERSION_4_0_4 is not set | |||||
# BR2_GCC_VERSION_4_1_2 is not set | |||||
# BR2_GCC_VERSION_4_2_1 is not set | |||||
# BR2_GCC_VERSION_4_2_2 is not set | |||||
# BR2_GCC_VERSION_4_2_3 is not set | |||||
# BR2_GCC_VERSION_4_2_4 is not set | |||||
# BR2_GCC_VERSION_4_3_2 is not set | |||||
BR2_GCC_VERSION_4_3_3=y | |||||
# BR2_GCC_VERSION_4_3_4 is not set | |||||
# BR2_GCC_VERSION_4_4_X is not set | |||||
BR2_GCC_SUPPORTS_SYSROOT=y | |||||
BR2_GCC_SUPPORTS_FINEGRAINEDMTUNE=y | |||||
BR2_GCC_VERSION="4.3.3" | |||||
BR2_TOOLCHAIN_SYSROOT=y | |||||
# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set | |||||
BR2_EXTRA_GCC_CONFIG_OPTIONS="" | |||||
# BR2_GCC_CROSS_FORTRAN is not set | |||||
# BR2_INSTALL_LIBGCJ is not set | |||||
# BR2_INSTALL_OBJC is not set | |||||
# BR2_INSTALL_FORTRAN is not set | |||||
BR2_GCC_SHARED_LIBGCC=y | |||||
# | |||||
# Ccache Options | |||||
# | |||||
# BR2_CCACHE is not set | |||||
# | |||||
# Gdb Options | |||||
# | |||||
# BR2_PACKAGE_GDB is not set | |||||
# BR2_PACKAGE_GDB_SERVER is not set | |||||
# BR2_PACKAGE_GDB_HOST is not set | |||||
# | |||||
# Common Toolchain Options | |||||
# | |||||
# BR2_LARGEFILE is not set | |||||
# BR2_INET_IPV6 is not set | |||||
# BR2_INET_RPC is not set | |||||
# BR2_ENABLE_LOCALE is not set | |||||
# BR2_ENABLE_LOCALE_PURGE is not set | |||||
BR2_USE_WCHAR=y | |||||
# BR2_SOFT_FLOAT is not set | |||||
# BR2_USE_SSP is not set | |||||
# BR2_PTHREADS_NONE is not set | |||||
# BR2_PTHREADS is not set | |||||
BR2_PTHREADS_OLD=y | |||||
# BR2_PTHREADS_NATIVE is not set | |||||
# BR2_PROGRAM_INVOCATION is not set | |||||
BR2_GCC_CROSS_CXX=y | |||||
BR2_INSTALL_LIBSTDCPP=y | |||||
BR2_TARGET_OPTIMIZATION="-O2 -pipe" | |||||
# BR2_ELF2FLT is not set | |||||
# BR2_MKLIBS is not set | |||||
# BR2_PACKAGE_SSTRIP_TARGET is not set | |||||
# BR2_PACKAGE_SSTRIP_HOST is not set | |||||
# BR2_ENABLE_MULTILIB is not set | |||||
# BR2_VFP_FLOAT is not set | |||||
BR2_CROSS_TOOLCHAIN_TARGET_UTILS=y | |||||
# | |||||
# Package Selection for the target | |||||
# | |||||
BR2_PACKAGE_BUSYBOX=y | |||||
# BR2_BUSYBOX_VERSION_1_12_X is not set | |||||
# BR2_BUSYBOX_VERSION_1_13_X is not set | |||||
BR2_BUSYBOX_VERSION_1_14_X=y | |||||
# BR2_PACKAGE_BUSYBOX_SNAPSHOT is not set | |||||
BR2_BUSYBOX_VERSION="1.14.3" | |||||
BR2_PACKAGE_BUSYBOX_FULLINSTALL=y | |||||
BR2_PACKAGE_BUSYBOX_CONFIG="package/busybox/busybox-1.13.x.config" | |||||
BR2_PACKAGE_BUSYBOX_HIDE_OTHERS=y | |||||
# BR2_PACKAGE_BUSYBOX_SKELETON is not set | |||||
# | |||||
# The minimum needed to build a uClibc development system | |||||
# | |||||
# BR2_PACKAGE_FLEX is not set | |||||
# BR2_PACKAGE_GCC_TARGET is not set | |||||
# BR2_PACKAGE_MAKE is not set | |||||
# | |||||
# Other development stuff | |||||
# | |||||
# BR2_PACKAGE_AUTOCONF is not set | |||||
# BR2_PACKAGE_AUTOMAKE is not set | |||||
# BR2_PACKAGE_BISON is not set | |||||
# BR2_PACKAGE_CCACHE_TARGET is not set | |||||
# BR2_PACKAGE_CVS is not set | |||||
# BR2_PACKAGE_DISTCC is not set | |||||
# BR2_PACKAGE_DMALLOC is not set | |||||
# BR2_PACKAGE_FAKEROOT is not set | |||||
BR2_HOST_FAKEROOT=y | |||||
# BR2_PACKAGE_GETTEXT is not set | |||||
# BR2_PACKAGE_LIBINTL is not set | |||||
# BR2_PACKAGE_LIBGMP is not set | |||||
# BR2_PACKAGE_GPERF is not set | |||||
# BR2_PACKAGE_LIBMPFR is not set | |||||
# BR2_PACKAGE_LIBTOOL is not set | |||||
# BR2_PACKAGE_M4 is not set | |||||
# BR2_PACKAGE_OPROFILE is not set | |||||
# BR2_PACKAGE_PKG_CONFIG is not set | |||||
BR2_PACKAGE_READLINE=y | |||||
# BR2_PACKAGE_PCRE is not set | |||||
# | |||||
# Other stuff | |||||
# | |||||
# BR2_PACKAGE_AT is not set | |||||
# BR2_PACKAGE_BEECRYPT is not set | |||||
# BR2_PACKAGE_BERKELEYDB is not set | |||||
# BR2_PACKAGE_BSDIFF is not set | |||||
# BR2_PACKAGE_CUPS is not set | |||||
# BR2_PACKAGE_CUSTOMIZE is not set | |||||
# BR2_PACKAGE_ENCHANT is not set | |||||
# BR2_PACKAGE_FILE is not set | |||||
# BR2_PACKAGE_GAMIN is not set | |||||
# BR2_PACKAGE_ICU is not set | |||||
# BR2_PACKAGE_KEXEC is not set | |||||
# BR2_PACKAGE_LIBCONFIG is not set | |||||
# BR2_PACKAGE_LIBCONFUSE is not set | |||||
# BR2_PACKAGE_LIBDAEMON is not set | |||||
# BR2_PACKAGE_LIBELF is not set | |||||
# BR2_PACKAGE_LIBEVENT is not set | |||||
# BR2_PACKAGE_LIBGCRYPT is not set | |||||
# BR2_PACKAGE_LIBGPG_ERROR is not set | |||||
BR2_PACKAGE_LIBICONV=y | |||||
# BR2_PACKAGE_LIBIDN is not set | |||||
# BR2_PACKAGE_LIBLOCKFILE is not set | |||||
# BR2_PACKAGE_LIBOIL is not set | |||||
# BR2_PACKAGE_LIBSYSFS is not set | |||||
# BR2_PACKAGE_LOCKFILE_PROGS is not set | |||||
# BR2_PACKAGE_LOGROTATE is not set | |||||
# BR2_PACKAGE_LSOF is not set | |||||
# BR2_PACKAGE_LTP-TESTSUITE is not set | |||||
# BR2_PACKAGE_LTRACE is not set | |||||
# BR2_PACKAGE_MEMSTAT is not set | |||||
# BR2_PACKAGE_NG_SPICE_REWORK is not set | |||||
# BR2_PACKAGE_POPT is not set | |||||
# BR2_PACKAGE_SCREEN is not set | |||||
# BR2_PACKAGE_SHARED_MIME_INFO is not set | |||||
# BR2_PACKAGE_STARTUP_NOTIFICATION is not set | |||||
# BR2_PACKAGE_STRACE is not set | |||||
# BR2_PACKAGE_SUDO is not set | |||||
# | |||||
# Database | |||||
# | |||||
# BR2_PACKAGE_MYSQL_CLIENT is not set | |||||
# BR2_PACKAGE_SQLITE is not set | |||||
# | |||||
# Networking | |||||
# | |||||
# | |||||
# Networking applications | |||||
# | |||||
# BR2_PACKAGE_ARGUS is not set | |||||
# BR2_PACKAGE_AVAHI is not set | |||||
# BR2_PACKAGE_AXEL is not set | |||||
# | |||||
# bind requires a toolchain with LARGEFILE support | |||||
# | |||||
# BR2_PACKAGE_BMON is not set | |||||
# BR2_PACKAGE_BRIDGE is not set | |||||
# BR2_PACKAGE_CTORRENT is not set | |||||
# BR2_PACKAGE_DNSMASQ is not set | |||||
BR2_PACKAGE_DROPBEAR=y | |||||
# BR2_PACKAGE_ETHTOOL is not set | |||||
# BR2_PACKAGE_HASERL is not set | |||||
# BR2_PACKAGE_IFPLUGD is not set | |||||
# BR2_PACKAGE_IPERF is not set | |||||
# | |||||
# iproute2 requires a toolchain with IPv6 support | |||||
# | |||||
# BR2_PACKAGE_IPSEC_TOOLS is not set | |||||
# | |||||
# iptables requires a toolchain with LARGEFILE support | |||||
# | |||||
# BR2_PACKAGE_IW is not set | |||||
# BR2_PACKAGE_KISMET is not set | |||||
# BR2_PACKAGE_L2TP is not set | |||||
# BR2_PACKAGE_LIBCGI is not set | |||||
# BR2_PACKAGE_LIBCGICC is not set | |||||
# BR2_PACKAGE_LIBCURL is not set | |||||
# BR2_PACKAGE_LIBDNET is not set | |||||
# BR2_PACKAGE_LIBEXOSIP2 is not set | |||||
# BR2_PACKAGE_LIBNL is not set | |||||
# BR2_PACKAGE_LIBOSIP2 is not set | |||||
# BR2_PACKAGE_LIBPCAP is not set | |||||
# BR2_PACKAGE_LIBSOUP is not set | |||||
# BR2_PACKAGE_LIBUPNP is not set | |||||
# BR2_PACKAGE_LINKS is not set | |||||
BR2_PACKAGE_LRZSZ=y | |||||
# BR2_PACKAGE_MDNSRESPONDER is not set | |||||
# BR2_PACKAGE_MIIDIAG is not set | |||||
# BR2_PACKAGE_MROUTED is not set | |||||
# BR2_PACKAGE_MUTT is not set | |||||
# BR2_PACKAGE_NBD is not set | |||||
# BR2_PACKAGE_NCFTP is not set | |||||
# BR2_PACKAGE_NEON is not set | |||||
# | |||||
# netkitbase requires a toolchain with RPC support | |||||
# | |||||
# BR2_PACKAGE_NETKITTELNET is not set | |||||
# BR2_PACKAGE_NETPLUG is not set | |||||
# BR2_PACKAGE_NETSNMP is not set | |||||
# BR2_PACKAGE_NETSTAT_NAT is not set | |||||
# | |||||
# nfs-utils requires a toolchain with 'Enable RPC' selected | |||||
# | |||||
# BR2_PACKAGE_NTP is not set | |||||
# BR2_PACKAGE_OLSR is not set | |||||
# BR2_PACKAGE_OPENNTPD is not set | |||||
# BR2_PACKAGE_OPENSSH is not set | |||||
# BR2_PACKAGE_OPENSSL is not set | |||||
# BR2_PACKAGE_OPENVPN is not set | |||||
# | |||||
# portmap requires a toolchain with 'Enable RPC' selected | |||||
# | |||||
# BR2_PACKAGE_PPPD is not set | |||||
# BR2_PACKAGE_RP_PPPOE is not set | |||||
# BR2_PACKAGE_PPTP_LINUX is not set | |||||
# BR2_PACKAGE_PROFTPD is not set | |||||
# | |||||
# quagga suite | |||||
# | |||||
# BR2_PACKAGE_QUAGGA_ZEBRA is not set | |||||
# BR2_PACKAGE_QUAGGA_BGPD is not set | |||||
# BR2_PACKAGE_QUAGGA_RIPD is not set | |||||
# BR2_PACKAGE_QUAGGA_RIPNGD is not set | |||||
# BR2_PACKAGE_QUAGGA_OSPFD is not set | |||||
# BR2_PACKAGE_QUAGGA_WATCHQUAGGA is not set | |||||
# BR2_PACKAGE_QUAGGA_ISISD is not set | |||||
# BR2_PACKAGE_RSYNC is not set | |||||
# BR2_PACKAGE_SAMBA is not set | |||||
# BR2_PACKAGE_SOCAT is not set | |||||
# BR2_PACKAGE_SPAWN_FCGI is not set | |||||
# BR2_PACKAGE_STUNNEL is not set | |||||
# BR2_PACKAGE_TCPDUMP is not set | |||||
# BR2_PACKAGE_DHCPDUMP is not set | |||||
# BR2_PACKAGE_TFTPD is not set | |||||
# BR2_PACKAGE_TN5250 is not set | |||||
# BR2_PACKAGE_TTCP is not set | |||||
# BR2_PACKAGE_UDPCAST is not set | |||||
# BR2_PACKAGE_VPNC is not set | |||||
# BR2_PACKAGE_VSFTPD is not set | |||||
# BR2_PACKAGE_VTUN is not set | |||||
# BR2_PACKAGE_WEBIF is not set | |||||
BR2_PACKAGE_WIRELESS_TOOLS=y | |||||
BR2_PACKAGE_WPA_SUPPLICANT=y | |||||
# BR2_PACKAGE_WPA_SUPPLICANT_EAP is not set | |||||
BR2_PACKAGE_WPA_SUPPLICANT_CLI=y | |||||
BR2_PACKAGE_WPA_SUPPLICANT_PASSPHRASE=y | |||||
# | |||||
# Hardware handling / blockdevices and filesystem maintenance | |||||
# | |||||
# | |||||
# dbus not available (need expat or libxml2) | |||||
# | |||||
# | |||||
# dbus-glib needs dbus to be compiled with expat support | |||||
# | |||||
# BR2_PACKAGE_DEVMEM2 is not set | |||||
# | |||||
# dmraid requires a toolchain with LARGEFILE support | |||||
# | |||||
# BR2_PACKAGE_DOSFSTOOLS is not set | |||||
# BR2_PACKAGE_LIBUUID is not set | |||||
# | |||||
# e2fsprogs requires a toolchain with LARGEFILE support | |||||
# | |||||
# BR2_PACKAGE_EEPROG is not set | |||||
# BR2_PACKAGE_FCONFIG is not set | |||||
# BR2_PACKAGE_FIS is not set | |||||
# | |||||
# libfuse requires a toolchain with LARGEFILE support | |||||
# | |||||
# BR2_PACKAGE_GADGETFS_TEST is not set | |||||
# BR2_PACKAGE_HAL is not set | |||||
# BR2_PACKAGE_HWDATA is not set | |||||
# BR2_PACKAGE_I2C_TOOLS is not set | |||||
# BR2_PACKAGE_INPUT_TOOLS is not set | |||||
# BR2_PACKAGE_IOSTAT is not set | |||||
# BR2_PACKAGE_LIBAIO is not set | |||||
# BR2_PACKAGE_LIBRAW1394 is not set | |||||
BR2_PACKAGE_LIBUSB=y | |||||
# BR2_PACKAGE_LM_SENSORS is not set | |||||
# | |||||
# lvm2 requires a toolchain with LARGEFILE support | |||||
# | |||||
# BR2_PACKAGE_MDADM is not set | |||||
# BR2_PACKAGE_MEMTESTER is not set | |||||
# BR2_PACKAGE_MTD is not set | |||||
# | |||||
# ntfs-3g requires a toolchain with LARGEFILE and WCHAR support | |||||
# | |||||
# BR2_PACKAGE_NTFSPROGS is not set | |||||
# BR2_PACKAGE_PCIUTILS is not set | |||||
# BR2_PACKAGE_SETSERIAL is not set | |||||
# BR2_PACKAGE_SMARTMONTOOLS is not set | |||||
# BR2_PACKAGE_USBMOUNT is not set | |||||
BR2_PACKAGE_USBUTILS=y | |||||
# BR2_PACKAGE_WIPE is not set | |||||
# BR2_PACKAGE_XFSPROGS is not set | |||||
# | |||||
# Audio and video libraries and applications | |||||
# | |||||
# BR2_PACKAGE_ALSA_LIB is not set | |||||
# | |||||
# alsa-utils requires a toolchain with LARGEFILE support | |||||
# | |||||
# | |||||
# asterisk - disabled (required openssl and mpg123) | |||||
# | |||||
# BR2_PACKAGE_AUMIX is not set | |||||
# BR2_PACKAGE_FLAC is not set | |||||
# BR2_PACKAGE_GSTREAMER is not set | |||||
# BR2_PACKAGE_LIBID3TAG is not set | |||||
# BR2_PACKAGE_LIBMAD is not set | |||||
# BR2_PACKAGE_LIBMMS is not set | |||||
# BR2_PACKAGE_LIBMPD is not set | |||||
# BR2_PACKAGE_LIBOGG is not set | |||||
# BR2_PACKAGE_LIBSNDFILE is not set | |||||
# BR2_PACKAGE_LIBTHEORA is not set | |||||
# BR2_PACKAGE_LIBVORBIS is not set | |||||
# BR2_PACKAGE_MADPLAY is not set | |||||
# BR2_PACKAGE_MPG123 is not set | |||||
# BR2_PACKAGE_MPLAYER is not set | |||||
# BR2_PACKAGE_SPEEX is not set | |||||
# BR2_PACKAGE_FESTIVAL is not set | |||||
# BR2_PACKAGE_TAGLIB is not set | |||||
# BR2_PACKAGE_VLC is not set | |||||
# | |||||
# Graphic libraries and applications (graphic/text) | |||||
# | |||||
# | |||||
# text rendering libraries | |||||
# | |||||
BR2_PACKAGE_NCURSES=y | |||||
# BR2_PACKAGE_NCURSES_TARGET_PANEL is not set | |||||
# BR2_PACKAGE_NCURSES_TARGET_FORM is not set | |||||
# BR2_PACKAGE_NCURSES_TARGET_MENU is not set | |||||
# BR2_PACKAGE_NCURSES_TARGET_HEADERS is not set | |||||
# BR2_PACKAGE_NEWT is not set | |||||
# BR2_PACKAGE_SLANG is not set | |||||
# | |||||
# text rendering applications | |||||
# | |||||
# BR2_PACKAGE_DIALOG is not set | |||||
# | |||||
# graphic libraries | |||||
# | |||||
# BR2_PACKAGE_DIRECTFB is not set | |||||
# BR2_PACKAGE_FBDUMP is not set | |||||
# BR2_PACKAGE_IMAGEMAGICK is not set | |||||
BR2_PACKAGE_JPEG=y | |||||
# BR2_PACKAGE_LIBART is not set | |||||
# BR2_PACKAGE_LIBPNG is not set | |||||
# BR2_PACKAGE_LIBUNGIF is not set | |||||
# BR2_PACKAGE_LINUX_FUSION is not set | |||||
# BR2_PACKAGE_PIXMAN is not set | |||||
# BR2_PACKAGE_SDL is not set | |||||
# BR2_PACKAGE_TIFF is not set | |||||
# | |||||
# busybox graphic applications | |||||
# | |||||
# | |||||
# --> May be broken in busybox | |||||
# | |||||
# BR2_PACKAGE_FBV is not set | |||||
# BR2_PACKAGE_FBSET is not set | |||||
# | |||||
# other GUIs | |||||
# | |||||
# BR2_PACKAGE_QT is not set | |||||
# BR2_PACKAGE_XORG7 is not set | |||||
# | |||||
# X libraries and helper libraries | |||||
# | |||||
# BR2_PACKAGE_ATK is not set | |||||
# BR2_PACKAGE_CAIRO is not set | |||||
# BR2_PACKAGE_PANGO is not set | |||||
# BR2_PACKAGE_LIBDRM is not set | |||||
# BR2_PACKAGE_LIBERATION is not set | |||||
# BR2_PACKAGE_LIBGLIB12 is not set | |||||
# BR2_PACKAGE_LIBGLIB2 is not set | |||||
# BR2_PACKAGE_OPENMOTIF is not set | |||||
# BR2_PACKAGE_FONTCONFIG is not set | |||||
# BR2_PACKAGE_FREETYPE is not set | |||||
# BR2_PACKAGE_TSLIB is not set | |||||
# BR2_PACKAGE_WEBKIT is not set | |||||
# | |||||
# X Window managers | |||||
# | |||||
# BR2_PACKAGE_MATCHBOX is not set | |||||
# | |||||
# X applications | |||||
# | |||||
# BR2_PACKAGE_ALSAMIXERGUI is not set | |||||
# BR2_PACKAGE_GQVIEW is not set | |||||
# BR2_PACKAGE_GOB2 is not set | |||||
# BR2_PACKAGE_LEAFPAD is not set | |||||
# BR2_PACKAGE_PCMANFM is not set | |||||
# BR2_PACKAGE_SYLPHEED is not set | |||||
# BR2_PACKAGE_TORSMO is not set | |||||
# BR2_PACKAGE_X11VNC is not set | |||||
# BR2_PACKAGE_XPDF is not set | |||||
# BR2_PACKAGE_XSTROKE is not set | |||||
# | |||||
# Compressors / decompressors | |||||
# | |||||
# BR2_PACKAGE_LZO is not set | |||||
# BR2_PACKAGE_LZOP is not set | |||||
# BR2_PACKAGE_LZMA_TARGET is not set | |||||
# BR2_PACKAGE_LZMA_HOST is not set | |||||
BR2_PACKAGE_ZLIB=y | |||||
# BR2_PACKAGE_ZLIB_TARGET_HEADERS is not set | |||||
# | |||||
# Package managers | |||||
# | |||||
# BR2_PACKAGE_IPKG is not set | |||||
# BR2_PACKAGE_PORTAGE is not set | |||||
# | |||||
# Interpreter languages / Scripting | |||||
# | |||||
# BR2_PACKAGE_LUA is not set | |||||
# BR2_PACKAGE_MICROPERL is not set | |||||
# BR2_PACKAGE_PYTHON is not set | |||||
# BR2_PACKAGE_RUBY is not set | |||||
# BR2_PACKAGE_TCL is not set | |||||
# BR2_PACKAGE_PHP is not set | |||||
# | |||||
# XML handling | |||||
# | |||||
# BR2_PACKAGE_EXPAT is not set | |||||
# BR2_PACKAGE_EZXML is not set | |||||
# BR2_PACKAGE_LIBXML2 is not set | |||||
# BR2_PACKAGE_LIBXSLT is not set | |||||
# BR2_PACKAGE_XERCES is not set | |||||
# | |||||
# Java | |||||
# | |||||
# BR2_PACKAGE_CLASSPATH is not set | |||||
# | |||||
# Games | |||||
# | |||||
# BR2_PACKAGE_GNUCHESS is not set | |||||
# BR2_PACKAGE_MAGICCUBE4D is not set | |||||
# BR2_PACKAGE_PRBOOM is not set | |||||
# BR2_PACKAGE_RUBIX is not set | |||||
# BR2_PACKAGE_VICE is not set | |||||
# BR2_PACKAGE_XBOARD is not set | |||||
# | |||||
# Target filesystem options | |||||
# | |||||
BR2_ROOTFS_PREFIX="rootfs" | |||||
BR2_ROOTFS_SUFFIX="" | |||||
BR2_ROOTFS_POST_BUILD_SCRIPT="" | |||||
# | |||||
# filesystem for target device | |||||
# | |||||
# BR2_TARGET_ROOTFS_CRAMFS is not set | |||||
# BR2_TARGET_ROOTFS_CLOOP is not set | |||||
BR2_TARGET_ROOTFS_EXT2=y | |||||
BR2_TARGET_ROOTFS_EXT2_BLOCKS=0 | |||||
BR2_TARGET_ROOTFS_EXT2_INODES=0 | |||||
BR2_TARGET_ROOTFS_EXT2_RESBLKS=0 | |||||
BR2_TARGET_ROOTFS_EXT2_SQUASH=y | |||||
BR2_TARGET_ROOTFS_EXT2_OUTPUT="$(IMAGE).ext2" | |||||
BR2_TARGET_ROOTFS_EXT2_NONE=y | |||||
# BR2_TARGET_ROOTFS_EXT2_GZIP is not set | |||||
# BR2_TARGET_ROOTFS_EXT2_BZIP2 is not set | |||||
# BR2_TARGET_ROOTFS_EXT2_LZMA is not set | |||||
BR2_TARGET_ROOTFS_EXT2_COPYTO="" | |||||
# BR2_TARGET_ROOTFS_JFFS2 is not set | |||||
# BR2_TARGET_ROOTFS_SQUASHFS is not set | |||||
# BR2_TARGET_ROOTFS_TAR is not set | |||||
# BR2_TARGET_ROOTFS_CPIO is not set | |||||
BR2_TARGET_ROOTFS_INITRAMFS=y | |||||
# BR2_TARGET_ROOTFS_ROMFS is not set | |||||
# | |||||
# bootloader for target device | |||||
# | |||||
# BR2_TARGET_UBOOT is not set | |||||
BR2_BOOTSOURCE_DATAFLASHCARD=y | |||||
BR2_BOOTSOURCE_DATAFLASH=y | |||||
BR2_BOOTSOURCE_NANDFLASH=y | |||||
BR2_BOOTSOURCE=y | |||||
# | |||||
# Kernel | |||||
# | |||||
BR2_KERNEL_none=y | |||||
# BR2_KERNEL_LINUX_ADVANCED is not set | |||||
# BR2_KERNEL_LINUX is not set |
@@ -0,0 +1,281 @@ | |||||
-- 'Bucket Brigade' FIFO | |||||
-- 16 deep | |||||
-- 8-bit data | |||||
-- | |||||
-- Version : 1.10 | |||||
-- Version Date : 3rd December 2003 | |||||
-- Reason : '--translate' directives changed to '--synthesis translate' directives | |||||
-- | |||||
-- Version : 1.00 | |||||
-- Version Date : 14th October 2002 | |||||
-- | |||||
-- Start of design entry : 14th October 2002 | |||||
-- | |||||
-- Ken Chapman | |||||
-- Xilinx Ltd | |||||
-- Benchmark House | |||||
-- 203 Brooklands Road | |||||
-- Weybridge | |||||
-- Surrey KT13 ORH | |||||
-- United Kingdom | |||||
-- | |||||
-- chapman@xilinx.com | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- NOTICE: | |||||
-- | |||||
-- Copyright Xilinx, Inc. 2002. This code may be contain portions patented by other | |||||
-- third parties. By providing this core as one possible implementation of a standard, | |||||
-- Xilinx is making no representation that the provided implementation of this standard | |||||
-- is free from any claims of infringement by any third party. Xilinx expressly | |||||
-- disclaims any warranty with respect to the adequacy of the implementation, including | |||||
-- but not limited to any warranty or representation that the implementation is free | |||||
-- from claims of any third party. Futhermore, Xilinx is providing this core as a | |||||
-- courtesy to you and suggests that you contact all third parties to obtain the | |||||
-- necessary rights to use this implementation. | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Library declarations | |||||
-- | |||||
-- The Unisim Library is used to define Xilinx primitives. It is also used during | |||||
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd | |||||
-- | |||||
library IEEE; | |||||
use IEEE.STD_LOGIC_1164.ALL; | |||||
use IEEE.STD_LOGIC_ARITH.ALL; | |||||
use IEEE.STD_LOGIC_UNSIGNED.ALL; | |||||
library unisim; | |||||
use unisim.vcomponents.all; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Main Entity for BBFIFO_16x8 | |||||
-- | |||||
entity bbfifo_16x8 is | |||||
Port ( data_in : in std_logic_vector(7 downto 0); | |||||
data_out : out std_logic_vector(7 downto 0); | |||||
reset : in std_logic; | |||||
write : in std_logic; | |||||
read : in std_logic; | |||||
full : out std_logic; | |||||
half_full : out std_logic; | |||||
data_present : out std_logic; | |||||
clk : in std_logic); | |||||
end bbfifo_16x8; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Start of Main Architecture for BBFIFO_16x8 | |||||
-- | |||||
architecture low_level_definition of bbfifo_16x8 is | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Signals used in BBFIFO_16x8 | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
signal pointer : std_logic_vector(3 downto 0); | |||||
signal next_count : std_logic_vector(3 downto 0); | |||||
signal half_count : std_logic_vector(3 downto 0); | |||||
signal count_carry : std_logic_vector(2 downto 0); | |||||
signal pointer_zero : std_logic; | |||||
signal pointer_full : std_logic; | |||||
signal decode_data_present : std_logic; | |||||
signal data_present_int : std_logic; | |||||
signal valid_write : std_logic; | |||||
-- | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Attributes to define LUT contents during implementation | |||||
-- The information is repeated in the generic map for functional simulation-- | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
attribute INIT : string; | |||||
attribute INIT of zero_lut : label is "0001"; | |||||
attribute INIT of full_lut : label is "8000"; | |||||
attribute INIT of dp_lut : label is "BFA0"; | |||||
attribute INIT of valid_lut : label is "C4"; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Start of BBFIFO_16x8 circuit description | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
begin | |||||
-- SRL16E data storage | |||||
data_width_loop: for i in 0 to 7 generate | |||||
-- | |||||
attribute INIT : string; | |||||
attribute INIT of data_srl : label is "0000"; | |||||
-- | |||||
begin | |||||
data_srl: SRL16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => data_in(i), | |||||
CE => valid_write, | |||||
CLK => clk, | |||||
A0 => pointer(0), | |||||
A1 => pointer(1), | |||||
A2 => pointer(2), | |||||
A3 => pointer(3), | |||||
Q => data_out(i) ); | |||||
end generate data_width_loop; | |||||
-- 4-bit counter to act as data pointer | |||||
-- Counter is clock enabled by 'data_present' | |||||
-- Counter will be reset when 'reset' is active | |||||
-- Counter will increment when 'valid_write' is active | |||||
count_width_loop: for i in 0 to 3 generate | |||||
-- | |||||
attribute INIT : string; | |||||
attribute INIT of count_lut : label is "6606"; | |||||
-- | |||||
begin | |||||
register_bit: FDRE | |||||
port map ( D => next_count(i), | |||||
Q => pointer(i), | |||||
CE => data_present_int, | |||||
R => reset, | |||||
C => clk); | |||||
count_lut: LUT4 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"6606") | |||||
--synthesis translate_on | |||||
port map( I0 => pointer(i), | |||||
I1 => read, | |||||
I2 => pointer_zero, | |||||
I3 => write, | |||||
O => half_count(i)); | |||||
lsb_count: if i=0 generate | |||||
begin | |||||
count_muxcy: MUXCY | |||||
port map( DI => pointer(i), | |||||
CI => valid_write, | |||||
S => half_count(i), | |||||
O => count_carry(i)); | |||||
count_xor: XORCY | |||||
port map( LI => half_count(i), | |||||
CI => valid_write, | |||||
O => next_count(i)); | |||||
end generate lsb_count; | |||||
mid_count: if i>0 and i<3 generate | |||||
begin | |||||
count_muxcy: MUXCY | |||||
port map( DI => pointer(i), | |||||
CI => count_carry(i-1), | |||||
S => half_count(i), | |||||
O => count_carry(i)); | |||||
count_xor: XORCY | |||||
port map( LI => half_count(i), | |||||
CI => count_carry(i-1), | |||||
O => next_count(i)); | |||||
end generate mid_count; | |||||
upper_count: if i=3 generate | |||||
begin | |||||
count_xor: XORCY | |||||
port map( LI => half_count(i), | |||||
CI => count_carry(i-1), | |||||
O => next_count(i)); | |||||
end generate upper_count; | |||||
end generate count_width_loop; | |||||
-- Detect when pointer is zero and maximum | |||||
zero_lut: LUT4 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0001") | |||||
--synthesis translate_on | |||||
port map( I0 => pointer(0), | |||||
I1 => pointer(1), | |||||
I2 => pointer(2), | |||||
I3 => pointer(3), | |||||
O => pointer_zero ); | |||||
full_lut: LUT4 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"8000") | |||||
--synthesis translate_on | |||||
port map( I0 => pointer(0), | |||||
I1 => pointer(1), | |||||
I2 => pointer(2), | |||||
I3 => pointer(3), | |||||
O => pointer_full ); | |||||
-- Data Present status | |||||
dp_lut: LUT4 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"BFA0") | |||||
--synthesis translate_on | |||||
port map( I0 => write, | |||||
I1 => read, | |||||
I2 => pointer_zero, | |||||
I3 => data_present_int, | |||||
O => decode_data_present ); | |||||
dp_flop: FDR | |||||
port map ( D => decode_data_present, | |||||
Q => data_present_int, | |||||
R => reset, | |||||
C => clk); | |||||
-- Valid write signal | |||||
valid_lut: LUT3 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"C4") | |||||
--synthesis translate_on | |||||
port map( I0 => pointer_full, | |||||
I1 => write, | |||||
I2 => read, | |||||
O => valid_write ); | |||||
-- assign internal signals to outputs | |||||
full <= pointer_full; | |||||
half_full <= pointer(3); | |||||
data_present <= data_present_int; | |||||
end low_level_definition; | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- END OF FILE BBFIFO_16x8.VHD | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
@@ -0,0 +1,352 @@ | |||||
-- Constant (K) Compact UART Receiver | |||||
-- | |||||
-- Version : 1.10 | |||||
-- Version Date : 3rd December 2003 | |||||
-- Reason : '--translate' directives changed to '--synthesis translate' directives | |||||
-- | |||||
-- Version : 1.00 | |||||
-- Version Date : 16th October 2002 | |||||
-- | |||||
-- Start of design entry : 16th October 2002 | |||||
-- | |||||
-- Ken Chapman | |||||
-- Xilinx Ltd | |||||
-- Benchmark House | |||||
-- 203 Brooklands Road | |||||
-- Weybridge | |||||
-- Surrey KT13 ORH | |||||
-- United Kingdom | |||||
-- | |||||
-- chapman@xilinx.com | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- NOTICE: | |||||
-- | |||||
-- Copyright Xilinx, Inc. 2002. This code may be contain portions patented by other | |||||
-- third parties. By providing this core as one possible implementation of a standard, | |||||
-- Xilinx is making no representation that the provided implementation of this standard | |||||
-- is free from any claims of infringement by any third party. Xilinx expressly | |||||
-- disclaims any warranty with respect to the adequacy of the implementation, including | |||||
-- but not limited to any warranty or representation that the implementation is free | |||||
-- from claims of any third party. Futhermore, Xilinx is providing this core as a | |||||
-- courtesy to you and suggests that you contact all third parties to obtain the | |||||
-- necessary rights to use this implementation. | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Library declarations | |||||
-- | |||||
-- The Unisim Library is used to define Xilinx primitives. It is also used during | |||||
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd | |||||
-- | |||||
library IEEE; | |||||
use IEEE.STD_LOGIC_1164.ALL; | |||||
use IEEE.STD_LOGIC_ARITH.ALL; | |||||
use IEEE.STD_LOGIC_UNSIGNED.ALL; | |||||
library unisim; | |||||
use unisim.vcomponents.all; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Main Entity for KCUART_RX | |||||
-- | |||||
entity kcuart_rx is | |||||
Port ( serial_in : in std_logic; | |||||
data_out : out std_logic_vector(7 downto 0); | |||||
data_strobe : out std_logic; | |||||
en_16_x_baud : in std_logic; | |||||
clk : in std_logic); | |||||
end kcuart_rx; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Start of Main Architecture for KCUART_RX | |||||
-- | |||||
architecture low_level_definition of kcuart_rx is | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Signals used in KCUART_RX | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
signal sync_serial : std_logic; | |||||
signal stop_bit : std_logic; | |||||
signal data_int : std_logic_vector(7 downto 0); | |||||
signal data_delay : std_logic_vector(7 downto 0); | |||||
signal start_delay : std_logic; | |||||
signal start_bit : std_logic; | |||||
signal edge_delay : std_logic; | |||||
signal start_edge : std_logic; | |||||
signal decode_valid_char : std_logic; | |||||
signal valid_char : std_logic; | |||||
signal decode_purge : std_logic; | |||||
signal purge : std_logic; | |||||
signal valid_srl_delay : std_logic_vector(8 downto 0); | |||||
signal valid_reg_delay : std_logic_vector(8 downto 0); | |||||
signal decode_data_strobe : std_logic; | |||||
-- | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Attributes to define LUT contents during implementation | |||||
-- The information is repeated in the generic map for functional simulation-- | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
attribute INIT : string; | |||||
attribute INIT of start_srl : label is "0000"; | |||||
attribute INIT of edge_srl : label is "0000"; | |||||
attribute INIT of valid_lut : label is "0040"; | |||||
attribute INIT of purge_lut : label is "54"; | |||||
attribute INIT of strobe_lut : label is "8"; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Start of KCUART_RX circuit description | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
begin | |||||
-- Synchronise input serial data to system clock | |||||
sync_reg: FD | |||||
port map ( D => serial_in, | |||||
Q => sync_serial, | |||||
C => clk); | |||||
stop_reg: FD | |||||
port map ( D => sync_serial, | |||||
Q => stop_bit, | |||||
C => clk); | |||||
-- Data delays to capture data at 16 time baud rate | |||||
-- Each SRL16E is followed by a flip-flop for best timing | |||||
data_loop: for i in 0 to 7 generate | |||||
begin | |||||
lsbs: if i<7 generate | |||||
-- | |||||
attribute INIT : string; | |||||
attribute INIT of delay15_srl : label is "0000"; | |||||
-- | |||||
begin | |||||
delay15_srl: SRL16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => data_int(i+1), | |||||
CE => en_16_x_baud, | |||||
CLK => clk, | |||||
A0 => '0', | |||||
A1 => '1', | |||||
A2 => '1', | |||||
A3 => '1', | |||||
Q => data_delay(i) ); | |||||
end generate lsbs; | |||||
msb: if i=7 generate | |||||
-- | |||||
attribute INIT : string; | |||||
attribute INIT of delay15_srl : label is "0000"; | |||||
-- | |||||
begin | |||||
delay15_srl: SRL16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => stop_bit, | |||||
CE => en_16_x_baud, | |||||
CLK => clk, | |||||
A0 => '0', | |||||
A1 => '1', | |||||
A2 => '1', | |||||
A3 => '1', | |||||
Q => data_delay(i) ); | |||||
end generate msb; | |||||
data_reg: FDE | |||||
port map ( D => data_delay(i), | |||||
Q => data_int(i), | |||||
CE => en_16_x_baud, | |||||
C => clk); | |||||
end generate data_loop; | |||||
-- Assign internal signals to outputs | |||||
data_out <= data_int; | |||||
-- Data delays to capture start bit at 16 time baud rate | |||||
start_srl: SRL16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => data_int(0), | |||||
CE => en_16_x_baud, | |||||
CLK => clk, | |||||
A0 => '0', | |||||
A1 => '1', | |||||
A2 => '1', | |||||
A3 => '1', | |||||
Q => start_delay ); | |||||
start_reg: FDE | |||||
port map ( D => start_delay, | |||||
Q => start_bit, | |||||
CE => en_16_x_baud, | |||||
C => clk); | |||||
-- Data delays to capture start bit leading edge at 16 time baud rate | |||||
-- Delay ensures data is captured at mid-bit position | |||||
edge_srl: SRL16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => start_bit, | |||||
CE => en_16_x_baud, | |||||
CLK => clk, | |||||
A0 => '1', | |||||
A1 => '0', | |||||
A2 => '1', | |||||
A3 => '0', | |||||
Q => edge_delay ); | |||||
edge_reg: FDE | |||||
port map ( D => edge_delay, | |||||
Q => start_edge, | |||||
CE => en_16_x_baud, | |||||
C => clk); | |||||
-- Detect a valid character | |||||
valid_lut: LUT4 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0040") | |||||
--synthesis translate_on | |||||
port map( I0 => purge, | |||||
I1 => stop_bit, | |||||
I2 => start_edge, | |||||
I3 => edge_delay, | |||||
O => decode_valid_char ); | |||||
valid_reg: FDE | |||||
port map ( D => decode_valid_char, | |||||
Q => valid_char, | |||||
CE => en_16_x_baud, | |||||
C => clk); | |||||
-- Purge of data status | |||||
purge_lut: LUT3 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"54") | |||||
--synthesis translate_on | |||||
port map( I0 => valid_reg_delay(8), | |||||
I1 => valid_char, | |||||
I2 => purge, | |||||
O => decode_purge ); | |||||
purge_reg: FDE | |||||
port map ( D => decode_purge, | |||||
Q => purge, | |||||
CE => en_16_x_baud, | |||||
C => clk); | |||||
-- Delay of valid_char pulse of length equivalent to the time taken | |||||
-- to purge data shift register of all data which has been used. | |||||
-- Requires 9x16 + 8 delays which is achieved by packing of SRL16E with | |||||
-- up to 16 delays and utilising the dedicated flip flop in each stage. | |||||
valid_loop: for i in 0 to 8 generate | |||||
begin | |||||
lsb: if i=0 generate | |||||
-- | |||||
attribute INIT : string; | |||||
attribute INIT of delay15_srl : label is "0000"; | |||||
-- | |||||
begin | |||||
delay15_srl: SRL16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => valid_char, | |||||
CE => en_16_x_baud, | |||||
CLK => clk, | |||||
A0 => '0', | |||||
A1 => '1', | |||||
A2 => '1', | |||||
A3 => '1', | |||||
Q => valid_srl_delay(i) ); | |||||
end generate lsb; | |||||
msbs: if i>0 generate | |||||
-- | |||||
attribute INIT : string; | |||||
attribute INIT of delay16_srl : label is "0000"; | |||||
-- | |||||
begin | |||||
delay16_srl: SRL16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => valid_reg_delay(i-1), | |||||
CE => en_16_x_baud, | |||||
CLK => clk, | |||||
A0 => '1', | |||||
A1 => '1', | |||||
A2 => '1', | |||||
A3 => '1', | |||||
Q => valid_srl_delay(i) ); | |||||
end generate msbs; | |||||
data_reg: FDE | |||||
port map ( D => valid_srl_delay(i), | |||||
Q => valid_reg_delay(i), | |||||
CE => en_16_x_baud, | |||||
C => clk); | |||||
end generate valid_loop; | |||||
-- Form data strobe | |||||
strobe_lut: LUT2 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"8") | |||||
--synthesis translate_on | |||||
port map( I0 => valid_char, | |||||
I1 => en_16_x_baud, | |||||
O => decode_data_strobe ); | |||||
strobe_reg: FD | |||||
port map ( D => decode_data_strobe, | |||||
Q => data_strobe, | |||||
C => clk); | |||||
end low_level_definition; | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- END OF FILE KCUART_RX.VHD | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
@@ -0,0 +1,394 @@ | |||||
-- Constant (K) Compact UART Transmitter | |||||
-- | |||||
-- Version : 1.10 | |||||
-- Version Date : 3rd December 2003 | |||||
-- Reason : '--translate' directives changed to '--synthesis translate' directives | |||||
-- | |||||
-- Version : 1.00 | |||||
-- Version Date : 14th October 2002 | |||||
-- | |||||
-- Start of design entry : 2nd October 2002 | |||||
-- | |||||
-- Ken Chapman | |||||
-- Xilinx Ltd | |||||
-- Benchmark House | |||||
-- 203 Brooklands Road | |||||
-- Weybridge | |||||
-- Surrey KT13 ORH | |||||
-- United Kingdom | |||||
-- | |||||
-- chapman@xilinx.com | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- NOTICE: | |||||
-- | |||||
-- Copyright Xilinx, Inc. 2002. This code may be contain portions patented by other | |||||
-- third parties. By providing this core as one possible implementation of a standard, | |||||
-- Xilinx is making no representation that the provided implementation of this standard | |||||
-- is free from any claims of infringement by any third party. Xilinx expressly | |||||
-- disclaims any warranty with respect to the adequacy of the implementation, including | |||||
-- but not limited to any warranty or representation that the implementation is free | |||||
-- from claims of any third party. Futhermore, Xilinx is providing this core as a | |||||
-- courtesy to you and suggests that you contact all third parties to obtain the | |||||
-- necessary rights to use this implementation. | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Library declarations | |||||
-- | |||||
-- The Unisim Library is used to define Xilinx primitives. It is also used during | |||||
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd | |||||
-- | |||||
library IEEE; | |||||
use IEEE.STD_LOGIC_1164.ALL; | |||||
use IEEE.STD_LOGIC_ARITH.ALL; | |||||
use IEEE.STD_LOGIC_UNSIGNED.ALL; | |||||
library unisim; | |||||
use unisim.vcomponents.all; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Main Entity for KCUART_TX | |||||
-- | |||||
entity kcuart_tx is | |||||
Port ( data_in : in std_logic_vector(7 downto 0); | |||||
send_character : in std_logic; | |||||
en_16_x_baud : in std_logic; | |||||
serial_out : out std_logic; | |||||
Tx_complete : out std_logic; | |||||
clk : in std_logic); | |||||
end kcuart_tx; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Start of Main Architecture for KCUART_TX | |||||
-- | |||||
architecture low_level_definition of kcuart_tx is | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Signals used in KCUART_TX | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
signal data_01 : std_logic; | |||||
signal data_23 : std_logic; | |||||
signal data_45 : std_logic; | |||||
signal data_67 : std_logic; | |||||
signal data_0123 : std_logic; | |||||
signal data_4567 : std_logic; | |||||
signal data_01234567 : std_logic; | |||||
signal bit_select : std_logic_vector(2 downto 0); | |||||
signal next_count : std_logic_vector(2 downto 0); | |||||
signal mask_count : std_logic_vector(2 downto 0); | |||||
signal mask_count_carry : std_logic_vector(2 downto 0); | |||||
signal count_carry : std_logic_vector(2 downto 0); | |||||
signal ready_to_start : std_logic; | |||||
signal decode_Tx_start : std_logic; | |||||
signal Tx_start : std_logic; | |||||
signal decode_Tx_run : std_logic; | |||||
signal Tx_run : std_logic; | |||||
signal decode_hot_state : std_logic; | |||||
signal hot_state : std_logic; | |||||
signal hot_delay : std_logic; | |||||
signal Tx_bit : std_logic; | |||||
signal decode_Tx_stop : std_logic; | |||||
signal Tx_stop : std_logic; | |||||
signal decode_Tx_complete : std_logic; | |||||
-- | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Attributes to define LUT contents during implementation | |||||
-- The information is repeated in the generic map for functional simulation-- | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
attribute INIT : string; | |||||
attribute INIT of mux1_lut : label is "E4FF"; | |||||
attribute INIT of mux2_lut : label is "E4FF"; | |||||
attribute INIT of mux3_lut : label is "E4FF"; | |||||
attribute INIT of mux4_lut : label is "E4FF"; | |||||
attribute INIT of ready_lut : label is "10"; | |||||
attribute INIT of start_lut : label is "0190"; | |||||
attribute INIT of run_lut : label is "1540"; | |||||
attribute INIT of hot_state_lut : label is "94"; | |||||
attribute INIT of delay14_srl : label is "0000"; | |||||
attribute INIT of stop_lut : label is "0180"; | |||||
attribute INIT of complete_lut : label is "8"; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Start of KCUART_TX circuit description | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
begin | |||||
-- 8 to 1 multiplexer to convert parallel data to serial | |||||
mux1_lut: LUT4 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"E4FF") | |||||
--synthesis translate_on | |||||
port map( I0 => bit_select(0), | |||||
I1 => data_in(0), | |||||
I2 => data_in(1), | |||||
I3 => Tx_run, | |||||
O => data_01 ); | |||||
mux2_lut: LUT4 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"E4FF") | |||||
--synthesis translate_on | |||||
port map( I0 => bit_select(0), | |||||
I1 => data_in(2), | |||||
I2 => data_in(3), | |||||
I3 => Tx_run, | |||||
O => data_23 ); | |||||
mux3_lut: LUT4 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"E4FF") | |||||
--synthesis translate_on | |||||
port map( I0 => bit_select(0), | |||||
I1 => data_in(4), | |||||
I2 => data_in(5), | |||||
I3 => Tx_run, | |||||
O => data_45 ); | |||||
mux4_lut: LUT4 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"E4FF") | |||||
--synthesis translate_on | |||||
port map( I0 => bit_select(0), | |||||
I1 => data_in(6), | |||||
I2 => data_in(7), | |||||
I3 => Tx_run, | |||||
O => data_67 ); | |||||
mux5_muxf5: MUXF5 | |||||
port map( I1 => data_23, | |||||
I0 => data_01, | |||||
S => bit_select(1), | |||||
O => data_0123 ); | |||||
mux6_muxf5: MUXF5 | |||||
port map( I1 => data_67, | |||||
I0 => data_45, | |||||
S => bit_select(1), | |||||
O => data_4567 ); | |||||
mux7_muxf6: MUXF6 | |||||
port map( I1 => data_4567, | |||||
I0 => data_0123, | |||||
S => bit_select(2), | |||||
O => data_01234567 ); | |||||
-- Register serial output and force start and stop bits | |||||
pipeline_serial: FDRS | |||||
port map ( D => data_01234567, | |||||
Q => serial_out, | |||||
R => Tx_start, | |||||
S => Tx_stop, | |||||
C => clk); | |||||
-- 3-bit counter | |||||
-- Counter is clock enabled by en_16_x_baud | |||||
-- Counter will be reset when 'Tx_start' is active | |||||
-- Counter will increment when Tx_bit is active | |||||
-- Tx_run must be active to count | |||||
-- count_carry(2) indicates when terminal count (7) is reached and Tx_bit=1 (ie overflow) | |||||
count_width_loop: for i in 0 to 2 generate | |||||
-- | |||||
attribute INIT : string; | |||||
attribute INIT of count_lut : label is "8"; | |||||
-- | |||||
begin | |||||
register_bit: FDRE | |||||
port map ( D => next_count(i), | |||||
Q => bit_select(i), | |||||
CE => en_16_x_baud, | |||||
R => Tx_start, | |||||
C => clk); | |||||
count_lut: LUT2 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"8") | |||||
--synthesis translate_on | |||||
port map( I0 => bit_select(i), | |||||
I1 => Tx_run, | |||||
O => mask_count(i)); | |||||
mask_and: MULT_AND | |||||
port map( I0 => bit_select(i), | |||||
I1 => Tx_run, | |||||
LO => mask_count_carry(i)); | |||||
lsb_count: if i=0 generate | |||||
begin | |||||
count_muxcy: MUXCY | |||||
port map( DI => mask_count_carry(i), | |||||
CI => Tx_bit, | |||||
S => mask_count(i), | |||||
O => count_carry(i)); | |||||
count_xor: XORCY | |||||
port map( LI => mask_count(i), | |||||
CI => Tx_bit, | |||||
O => next_count(i)); | |||||
end generate lsb_count; | |||||
upper_count: if i>0 generate | |||||
begin | |||||
count_muxcy: MUXCY | |||||
port map( DI => mask_count_carry(i), | |||||
CI => count_carry(i-1), | |||||
S => mask_count(i), | |||||
O => count_carry(i)); | |||||
count_xor: XORCY | |||||
port map( LI => mask_count(i), | |||||
CI => count_carry(i-1), | |||||
O => next_count(i)); | |||||
end generate upper_count; | |||||
end generate count_width_loop; | |||||
-- Ready to start decode | |||||
ready_lut: LUT3 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"10") | |||||
--synthesis translate_on | |||||
port map( I0 => Tx_run, | |||||
I1 => Tx_start, | |||||
I2 => send_character, | |||||
O => ready_to_start ); | |||||
-- Start bit enable | |||||
start_lut: LUT4 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0190") | |||||
--synthesis translate_on | |||||
port map( I0 => Tx_bit, | |||||
I1 => Tx_stop, | |||||
I2 => ready_to_start, | |||||
I3 => Tx_start, | |||||
O => decode_Tx_start ); | |||||
Tx_start_reg: FDE | |||||
port map ( D => decode_Tx_start, | |||||
Q => Tx_start, | |||||
CE => en_16_x_baud, | |||||
C => clk); | |||||
-- Run bit enable | |||||
run_lut: LUT4 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"1540") | |||||
--synthesis translate_on | |||||
port map( I0 => count_carry(2), | |||||
I1 => Tx_bit, | |||||
I2 => Tx_start, | |||||
I3 => Tx_run, | |||||
O => decode_Tx_run ); | |||||
Tx_run_reg: FDE | |||||
port map ( D => decode_Tx_run, | |||||
Q => Tx_run, | |||||
CE => en_16_x_baud, | |||||
C => clk); | |||||
-- Bit rate enable | |||||
hot_state_lut: LUT3 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"94") | |||||
--synthesis translate_on | |||||
port map( I0 => Tx_stop, | |||||
I1 => ready_to_start, | |||||
I2 => Tx_bit, | |||||
O => decode_hot_state ); | |||||
hot_state_reg: FDE | |||||
port map ( D => decode_hot_state, | |||||
Q => hot_state, | |||||
CE => en_16_x_baud, | |||||
C => clk); | |||||
delay14_srl: SRL16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => hot_state, | |||||
CE => en_16_x_baud, | |||||
CLK => clk, | |||||
A0 => '1', | |||||
A1 => '0', | |||||
A2 => '1', | |||||
A3 => '1', | |||||
Q => hot_delay ); | |||||
Tx_bit_reg: FDE | |||||
port map ( D => hot_delay, | |||||
Q => Tx_bit, | |||||
CE => en_16_x_baud, | |||||
C => clk); | |||||
-- Stop bit enable | |||||
stop_lut: LUT4 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0180") | |||||
--synthesis translate_on | |||||
port map( I0 => Tx_bit, | |||||
I1 => Tx_run, | |||||
I2 => count_carry(2), | |||||
I3 => Tx_stop, | |||||
O => decode_Tx_stop ); | |||||
Tx_stop_reg: FDE | |||||
port map ( D => decode_Tx_stop, | |||||
Q => Tx_stop, | |||||
CE => en_16_x_baud, | |||||
C => clk); | |||||
-- Tx_complete strobe | |||||
complete_lut: LUT2 | |||||
--synthesis translate_off | |||||
generic map (INIT => X"8") | |||||
--synthesis translate_on | |||||
port map( I0 => count_carry(2), | |||||
I1 => en_16_x_baud, | |||||
O => decode_Tx_complete ); | |||||
Tx_complete_reg: FD | |||||
port map ( D => decode_Tx_complete, | |||||
Q => Tx_complete, | |||||
C => clk); | |||||
end low_level_definition; | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- END OF FILE KCUART_TX.VHD | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
@@ -0,0 +1,91 @@ | |||||
# Constraints for 'parallel_flash_memory_uart_programmer'. | |||||
# | |||||
# Revision C of the Spartan-3E Starter Kit. | |||||
# | |||||
# Ken Chapman - Xilinx Ltd - 28th March 2006 | |||||
# | |||||
# | |||||
# Period constraint for 50MHz operation | |||||
# | |||||
NET "clk" PERIOD = 15.0ns HIGH 50%; | |||||
# | |||||
# | |||||
# soldered 50MHz Clock. | |||||
# | |||||
NET "clk" LOC = "P122" | IOSTANDARD = LVTTL; | |||||
# | |||||
# | |||||
# | |||||
# UART connections | |||||
# | |||||
NET "tx_female" LOC = "P32" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 4; | |||||
NET "rx_female" LOC = "P29" | IOSTANDARD = LVTTL; | |||||
# | |||||
# | |||||
# Strata Flash | |||||
# 128MBit = 16,777,216 bytes requiring 24 address bits. | |||||
# | |||||
NET "strataflash_oe" LOC = "P105" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_ce" LOC = "P104" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_we" LOC = "P103" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
#NET "strataflash_byte" LOC = "C17" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
#NET "strataflash_sts" LOC = "B18" | IOSTANDARD = LVCMOS33 | PULLUP; | |||||
# | |||||
NET "strataflash_a<0>" LOC = "P98" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<1>" LOC = "P97" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<2>" LOC = "P96" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<3>" LOC = "P94" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<4>" LOC = "P93" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<5>" LOC = "P92" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<6>" LOC = "P91" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<7>" LOC = "P88" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<8>" LOC = "P87" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<9>" LOC = "P86" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<10>" LOC = "P85" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<11>" LOC = "P82" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<12>" LOC = "P81" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<13>" LOC = "P77" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<14>" LOC = "P76" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<15>" LOC = "P75" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<16>" LOC = "P74" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<17>" LOC = "P70" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<18>" LOC = "P68" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<19>" LOC = "P67" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_a<20>" LOC = "P71" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
#NET "strataflash_a<21>" LOC = "P63" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
#NET "strataflash_a<22>" LOC = "V12" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
#NET "strataflash_a<23>" LOC = "N11" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
# | |||||
NET "strataflash_d<0>" LOC = "P63" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_d<1>" LOC = "P59" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_d<2>" LOC = "P58" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_d<3>" LOC = "P54" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_d<4>" LOC = "P53" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_d<5>" LOC = "P52" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_d<6>" LOC = "P51" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
NET "strataflash_d<7>" LOC = "P50" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; | |||||
# | |||||
# | |||||
# LCD display | |||||
# (Disable LCD display to ensure no contention with StratFlash memory). | |||||
# | |||||
#NET "lcd_rw" LOC = "L17" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; | |||||
#NET "lcd_e" LOC = "M18" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; | |||||
# | |||||
# | |||||
# SPI devices | |||||
# (Disable to prevent contention with StratFlash memory data bit0). | |||||
# | |||||
#NET "spi_rom_cs" LOC = "U3" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; | |||||
#NET "spi_adc_conv" LOC = "P11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; | |||||
#NET "spi_dac_cs" LOC = "N8" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; | |||||
# | |||||
# | |||||
# Platform Flash memory | |||||
# (Disable to prevent contention with StratFlash memory data bit0). | |||||
# | |||||
#NET "platformflash_oe" LOC = "T3" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 2; | |||||
# | |||||
# End of File | |||||
# | |||||
@@ -0,0 +1,424 @@ | |||||
-- KCPSM3 reference design | |||||
-- PicoBlaze performing programming of Intel StrataFlash NOR Flash Memory. | |||||
-- | |||||
-- Design provided and tested on the Spartan-3E Starter Kit (Revision C). | |||||
-- | |||||
-- Ken Chapman - Xilinx Ltd - 28th March 2006. | |||||
-- | |||||
-- The JTAG loader utility is also available for rapid program development. | |||||
-- | |||||
-- The design is set up for a 50MHz system clock and UART communications of 115200 baud | |||||
-- 8-bit, no parity, 1 stop-bit. IMPORTANT note: Soft flow control XON/XOFF is used. | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- NOTICE: | |||||
-- | |||||
-- Copyright Xilinx, Inc. 2006. This code may be contain portions patented by other | |||||
-- third parties. By providing this core as one possible implementation of a standard, | |||||
-- Xilinx is making no representation that the provided implementation of this standard | |||||
-- is free from any claims of infringement by any third party. Xilinx expressly | |||||
-- disclaims any warranty with respect to the adequacy of the implementation, including | |||||
-- but not limited to any warranty or representation that the implementation is free | |||||
-- from claims of any third party. Furthermore, Xilinx is providing this core as a | |||||
-- courtesy to you and suggests that you contact all third parties to obtain the | |||||
-- necessary rights to use this implementation. | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Library declarations | |||||
-- | |||||
-- Standard IEEE libraries | |||||
-- | |||||
library IEEE; | |||||
use IEEE.STD_LOGIC_1164.ALL; | |||||
use IEEE.STD_LOGIC_ARITH.ALL; | |||||
use IEEE.STD_LOGIC_UNSIGNED.ALL; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- | |||||
entity parallel_flash_memory_uart_programmer is | |||||
Port ( tx_female : out std_logic; | |||||
rx_female : in std_logic; | |||||
strataflash_oe : out std_logic; | |||||
strataflash_ce : out std_logic; | |||||
strataflash_we : out std_logic; | |||||
strataflash_a : out std_logic_vector(20 downto 0); | |||||
strataflash_d : inout std_logic_vector(7 downto 0); | |||||
clk : in std_logic); | |||||
end parallel_flash_memory_uart_programmer; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Start of test architecture | |||||
-- | |||||
architecture Behavioral of parallel_flash_memory_uart_programmer is | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- declaration of KCPSM3 | |||||
-- | |||||
component kcpsm3 | |||||
Port ( address : out std_logic_vector(9 downto 0); | |||||
instruction : in std_logic_vector(17 downto 0); | |||||
port_id : out std_logic_vector(7 downto 0); | |||||
write_strobe : out std_logic; | |||||
out_port : out std_logic_vector(7 downto 0); | |||||
read_strobe : out std_logic; | |||||
in_port : in std_logic_vector(7 downto 0); | |||||
interrupt : in std_logic; | |||||
interrupt_ack : out std_logic; | |||||
reset : in std_logic; | |||||
clk : in std_logic); | |||||
end component; | |||||
-- | |||||
-- declaration of program ROM | |||||
-- | |||||
component progctrl | |||||
Port ( address : in std_logic_vector(9 downto 0); | |||||
instruction : out std_logic_vector(17 downto 0); | |||||
proc_reset : out std_logic; --JTAG Loader version | |||||
clk : in std_logic); | |||||
end component; | |||||
-- | |||||
-- declaration of UART transmitter with integral 16 byte FIFO buffer | |||||
-- Note this is a modified version of the standard 'uart_tx' in which | |||||
-- the 'data_present' signal has also been brought out to better support | |||||
-- the XON/XOFF flow control. | |||||
-- | |||||
component uart_tx_plus | |||||
Port ( data_in : in std_logic_vector(7 downto 0); | |||||
write_buffer : in std_logic; | |||||
reset_buffer : in std_logic; | |||||
en_16_x_baud : in std_logic; | |||||
serial_out : out std_logic; | |||||
buffer_data_present : out std_logic; | |||||
buffer_full : out std_logic; | |||||
buffer_half_full : out std_logic; | |||||
clk : in std_logic); | |||||
end component; | |||||
-- | |||||
-- declaration of UART Receiver with integral 16 byte FIFO buffer | |||||
-- | |||||
component uart_rx | |||||
Port ( serial_in : in std_logic; | |||||
data_out : out std_logic_vector(7 downto 0); | |||||
read_buffer : in std_logic; | |||||
reset_buffer : in std_logic; | |||||
en_16_x_baud : in std_logic; | |||||
buffer_data_present : out std_logic; | |||||
buffer_full : out std_logic; | |||||
buffer_half_full : out std_logic; | |||||
clk : in std_logic); | |||||
end component; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Signals used to connect KCPSM3 to program ROM and I/O logic | |||||
-- | |||||
signal address : std_logic_vector(9 downto 0); | |||||
signal instruction : std_logic_vector(17 downto 0); | |||||
signal port_id : std_logic_vector(7 downto 0); | |||||
signal out_port : std_logic_vector(7 downto 0); | |||||
signal in_port : std_logic_vector(7 downto 0); | |||||
signal write_strobe : std_logic; | |||||
signal read_strobe : std_logic; | |||||
signal interrupt : std_logic :='0'; | |||||
signal interrupt_ack : std_logic; | |||||
signal kcpsm3_reset : std_logic; | |||||
-- | |||||
-- Signals for connection of peripherals | |||||
-- | |||||
signal status_port : std_logic_vector(7 downto 0); | |||||
-- | |||||
-- | |||||
-- Signals for UART connections | |||||
-- | |||||
signal baud_count : integer range 0 to 35 :=0; | |||||
signal en_16_x_baud : std_logic; | |||||
signal write_to_uart : std_logic; | |||||
signal tx_data_present : std_logic; | |||||
signal tx_full : std_logic; | |||||
signal tx_half_full : std_logic; | |||||
signal read_from_uart : std_logic; | |||||
signal rx_data : std_logic_vector(7 downto 0); | |||||
signal rx_data_present : std_logic; | |||||
signal rx_full : std_logic; | |||||
signal rx_half_full : std_logic; | |||||
-- | |||||
-- | |||||
-- Signals used to generate interrupt | |||||
-- | |||||
signal previous_rx_half_full : std_logic; | |||||
signal rx_half_full_event : std_logic; | |||||
-- | |||||
-- | |||||
-- Signals to connect to StrataFLASH memory | |||||
-- | |||||
signal strataflash_read : std_logic; | |||||
signal write_data : std_logic_vector(7 downto 0); | |||||
-- | |||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Start of circuit description | |||||
-- | |||||
begin | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
-- Set 8-bit mode of operation for StrataFLASH memory | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
-- | |||||
-- The StrataFLASH memory can be used in 8-bit or 16-bit modes. Since PicoBlaze is an 8-bit | |||||
-- processor and the configuration from parallel flash is conducted using an 8-bit interface, | |||||
-- this design forces the 8-bit data mode. | |||||
-- | |||||
-- As a result, the 128Mbit memory is organised as 16,777,216 bytes accessed using a 24-bit address. | |||||
-- | |||||
-- | |||||
-- | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
-- Bidirectional data interface for StrataFLASH memory | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
-- | |||||
-- To read the StrataFLASH memory the output enable (OE) signal must be driven Low on the memory and | |||||
-- the pins on the Spartan-3E must become inputs (i.e. the output buffers must be high impedance). | |||||
-- | |||||
-- | |||||
strataflash_oe <= not(strataflash_read); --active Low output enable | |||||
-- | |||||
strataflash_d <= write_data when (strataflash_read='0') else "ZZZZZZZZ"; | |||||
-- | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
-- KCPSM3 and the program memory | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
-- | |||||
processor: kcpsm3 | |||||
port map( address => address, | |||||
instruction => instruction, | |||||
port_id => port_id, | |||||
write_strobe => write_strobe, | |||||
out_port => out_port, | |||||
read_strobe => read_strobe, | |||||
in_port => in_port, | |||||
interrupt => interrupt, | |||||
interrupt_ack => interrupt_ack, | |||||
reset => kcpsm3_reset, | |||||
clk => clk); | |||||
program_rom: progctrl | |||||
port map( address => address, | |||||
instruction => instruction, | |||||
proc_reset => kcpsm3_reset, | |||||
clk => clk); | |||||
-- | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
-- Interrupt | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
-- | |||||
-- | |||||
-- Interrupt is used to detect when the UART receiver FIFO reaches half full and this is | |||||
-- then used to send XON and XOFF flow control characters back to the PC. | |||||
-- | |||||
-- If 'rx_half_full' goes High, an interrupt is generated and the subsequent ISR will transmit | |||||
-- an XOFF character to stop the flow of new characters from the PC and allow the FIFO to start to empty. | |||||
-- | |||||
-- If 'rx_half_full' goes Low, an interrupt is generated and the subsequent ISR will transmit | |||||
-- an XON character which will allow the PC to send new characters and allow the FIFO to start to fill. | |||||
-- | |||||
interrupt_control: process(clk) | |||||
begin | |||||
if clk'event and clk='1' then | |||||
-- detect change in state of the 'rx_half_full' flag. | |||||
previous_rx_half_full <= rx_half_full; | |||||
rx_half_full_event <= previous_rx_half_full xor rx_half_full; | |||||
-- processor interrupt waits for an acknowledgement | |||||
if interrupt_ack='1' then | |||||
interrupt <= '0'; | |||||
elsif rx_half_full_event='1' then | |||||
interrupt <= '1'; | |||||
else | |||||
interrupt <= interrupt; | |||||
end if; | |||||
end if; | |||||
end process interrupt_control; | |||||
-- | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
-- KCPSM3 input ports | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
-- | |||||
-- | |||||
-- UART FIFO status signals to form a bus | |||||
-- Also the status signal (STS) from the StrataFlash memory | |||||
-- status_port <= strataflash_sts & '0' & rx_full & rx_half_full & rx_data_present & tx_full & tx_half_full & tx_data_present; | |||||
status_port <= '0' & '0' & rx_full & rx_half_full & rx_data_present & tx_full & tx_half_full & tx_data_present; | |||||
-- | |||||
-- The inputs connect via a pipelined multiplexer | |||||
-- | |||||
input_ports: process(clk) | |||||
begin | |||||
if clk'event and clk='1' then | |||||
case port_id(1 downto 0) is | |||||
-- read status signals at address 00 hex | |||||
when "00" => in_port <= status_port; | |||||
-- read UART receive data at address 01 hex | |||||
when "01" => in_port <= rx_data; | |||||
-- read StrataFLASH memory data at address 02 hex | |||||
when "10" => in_port <= strataflash_d; | |||||
-- Don't care used for all other addresses to ensure minimum logic implementation | |||||
when others => in_port <= "XXXXXXXX"; | |||||
end case; | |||||
-- Form read strobe for UART receiver FIFO buffer at address 01 hex. | |||||
-- The fact that the read strobe will occur after the actual data is read by | |||||
-- the KCPSM3 is acceptable because it is really means 'I have read you'! | |||||
if (read_strobe='1' and port_id(1 downto 0)="01") then | |||||
read_from_uart <= '1'; | |||||
else | |||||
read_from_uart <= '0'; | |||||
end if; | |||||
end if; | |||||
end process input_ports; | |||||
-- | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
-- KCPSM3 output ports | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
-- | |||||
-- adding the output registers to the processor | |||||
output_ports: process(clk) | |||||
begin | |||||
if clk'event and clk='1' then | |||||
if write_strobe='1' then | |||||
-- The 24-bit address to the StrataFLASH memory requires 3 ports. | |||||
-- Address [23:16] at port 80 hex | |||||
if port_id(7)='1' then | |||||
strataflash_a(20 downto 16) <= out_port(4 downto 0); | |||||
end if; | |||||
-- Address [15:8] at port 40 hex | |||||
if port_id(6)='1' then | |||||
strataflash_a(15 downto 8) <= out_port; | |||||
end if; | |||||
-- Address [7:0] at port 20 hex | |||||
if port_id(5)='1' then | |||||
strataflash_a(7 downto 0) <= out_port; | |||||
end if; | |||||
-- Data to be written to StrataFlash at port 10 hex | |||||
if port_id(4)='1' then | |||||
write_data <= out_port; | |||||
end if; | |||||
-- StrataFlash control signals at port 08 hex | |||||
if port_id(3)='1' then | |||||
strataflash_read <= out_port(0); --Active High and used to control data bus direction and OE | |||||
strataflash_ce <= out_port(1); --Active Low StrataFLASH device enable | |||||
strataflash_we <= out_port(2); --Active Low StrataFLASH write enable | |||||
end if; | |||||
end if; | |||||
end if; | |||||
end process output_ports; | |||||
-- | |||||
-- write to UART transmitter FIFO buffer at address 04 hex. | |||||
-- This is a combinatorial decode because the FIFO is the 'port register'. | |||||
-- | |||||
write_to_uart <= '1' when (write_strobe='1' and port_id(2)='1') else '0'; | |||||
-- | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
-- UART | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
-- | |||||
-- Connect the 8-bit, 1 stop-bit, no parity transmit and receive macros. | |||||
-- Each contains an embedded 16-byte FIFO buffer. | |||||
-- | |||||
transmit: uart_tx_plus | |||||
port map ( data_in => out_port, | |||||
write_buffer => write_to_uart, | |||||
reset_buffer => '0', | |||||
en_16_x_baud => en_16_x_baud, | |||||
serial_out => tx_female, | |||||
buffer_data_present => tx_data_present, | |||||
buffer_full => tx_full, | |||||
buffer_half_full => tx_half_full, | |||||
clk => clk ); | |||||
receive: uart_rx | |||||
port map ( serial_in => rx_female, | |||||
data_out => rx_data, | |||||
read_buffer => read_from_uart, | |||||
reset_buffer => '0', | |||||
en_16_x_baud => en_16_x_baud, | |||||
buffer_data_present => rx_data_present, | |||||
buffer_full => rx_full, | |||||
buffer_half_full => rx_half_full, | |||||
clk => clk ); | |||||
-- | |||||
-- Set baud rate to 115200 for the UART communications | |||||
-- Requires en_16_x_baud to be 1843200Hz which is a single cycle pulse every 27 cycles at 50MHz | |||||
-- | |||||
baud_timer: process(clk) | |||||
begin | |||||
if clk'event and clk='1' then | |||||
if baud_count=34 then | |||||
baud_count <= 0; | |||||
en_16_x_baud <= '1'; | |||||
else | |||||
baud_count <= baud_count + 1; | |||||
en_16_x_baud <= '0'; | |||||
end if; | |||||
end if; | |||||
end process baud_timer; | |||||
-- | |||||
---------------------------------------------------------------------------------------------------------------------------------- | |||||
end Behavioral; | |||||
------------------------------------------------------------------------------------------------------------------------------------ | |||||
-- | |||||
-- END OF FILE parallel_flash_memory_uart_programmer.vhd | |||||
-- | |||||
------------------------------------------------------------------------------------------------------------------------------------ | |||||
@@ -0,0 +1,459 @@ | |||||
-- | |||||
-- Definition of a dual port ROM for KCPSM2 or KCPSM3 program defined by progctrl.psm | |||||
-- and assmbled using KCPSM2 or KCPSM3 assembler. | |||||
-- | |||||
-- Standard IEEE libraries | |||||
-- | |||||
library IEEE; | |||||
use IEEE.STD_LOGIC_1164.ALL; | |||||
use IEEE.STD_LOGIC_ARITH.ALL; | |||||
use IEEE.STD_LOGIC_UNSIGNED.ALL; | |||||
-- | |||||
-- The Unisim Library is used to define Xilinx primitives. It is also used during | |||||
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd | |||||
-- | |||||
library unisim; | |||||
use unisim.vcomponents.all; | |||||
-- | |||||
-- | |||||
entity progctrl is | |||||
Port ( address : in std_logic_vector(9 downto 0); | |||||
instruction : out std_logic_vector(17 downto 0); | |||||
proc_reset : out std_logic; | |||||
clk : in std_logic); | |||||
end progctrl; | |||||
-- | |||||
architecture low_level_definition of progctrl is | |||||
-- | |||||
-- Declare signals internal to this module | |||||
-- | |||||
signal jaddr : std_logic_vector(10 downto 0); | |||||
signal jparity : std_logic_vector(0 downto 0); | |||||
signal jdata : std_logic_vector(7 downto 0); | |||||
signal doa : std_logic_vector(7 downto 0); | |||||
signal dopa : std_logic_vector(0 downto 0); | |||||
signal tdo1 : std_logic; | |||||
signal tdo2 : std_logic; | |||||
signal update : std_logic; | |||||
signal shift : std_logic; | |||||
signal reset : std_logic; | |||||
signal tdi : std_logic; | |||||
signal sel1 : std_logic; | |||||
signal drck1 : std_logic; | |||||
signal drck1_buf : std_logic; | |||||
signal sel2 : std_logic; | |||||
signal drck2 : std_logic; | |||||
signal capture : std_logic; | |||||
signal tap5 : std_logic; | |||||
signal tap11 : std_logic; | |||||
signal tap17 : std_logic; | |||||
-- | |||||
-- Attributes to define ROM contents during implementation synthesis. | |||||
-- The information is repeated in the generic map for functional simulation | |||||
-- | |||||
attribute INIT_00 : string; | |||||
attribute INIT_01 : string; | |||||
attribute INIT_02 : string; | |||||
attribute INIT_03 : string; | |||||
attribute INIT_04 : string; | |||||
attribute INIT_05 : string; | |||||
attribute INIT_06 : string; | |||||
attribute INIT_07 : string; | |||||
attribute INIT_08 : string; | |||||
attribute INIT_09 : string; | |||||
attribute INIT_0A : string; | |||||
attribute INIT_0B : string; | |||||
attribute INIT_0C : string; | |||||
attribute INIT_0D : string; | |||||
attribute INIT_0E : string; | |||||
attribute INIT_0F : string; | |||||
attribute INIT_10 : string; | |||||
attribute INIT_11 : string; | |||||
attribute INIT_12 : string; | |||||
attribute INIT_13 : string; | |||||
attribute INIT_14 : string; | |||||
attribute INIT_15 : string; | |||||
attribute INIT_16 : string; | |||||
attribute INIT_17 : string; | |||||
attribute INIT_18 : string; | |||||
attribute INIT_19 : string; | |||||
attribute INIT_1A : string; | |||||
attribute INIT_1B : string; | |||||
attribute INIT_1C : string; | |||||
attribute INIT_1D : string; | |||||
attribute INIT_1E : string; | |||||
attribute INIT_1F : string; | |||||
attribute INIT_20 : string; | |||||
attribute INIT_21 : string; | |||||
attribute INIT_22 : string; | |||||
attribute INIT_23 : string; | |||||
attribute INIT_24 : string; | |||||
attribute INIT_25 : string; | |||||
attribute INIT_26 : string; | |||||
attribute INIT_27 : string; | |||||
attribute INIT_28 : string; | |||||
attribute INIT_29 : string; | |||||
attribute INIT_2A : string; | |||||
attribute INIT_2B : string; | |||||
attribute INIT_2C : string; | |||||
attribute INIT_2D : string; | |||||
attribute INIT_2E : string; | |||||
attribute INIT_2F : string; | |||||
attribute INIT_30 : string; | |||||
attribute INIT_31 : string; | |||||
attribute INIT_32 : string; | |||||
attribute INIT_33 : string; | |||||
attribute INIT_34 : string; | |||||
attribute INIT_35 : string; | |||||
attribute INIT_36 : string; | |||||
attribute INIT_37 : string; | |||||
attribute INIT_38 : string; | |||||
attribute INIT_39 : string; | |||||
attribute INIT_3A : string; | |||||
attribute INIT_3B : string; | |||||
attribute INIT_3C : string; | |||||
attribute INIT_3D : string; | |||||
attribute INIT_3E : string; | |||||
attribute INIT_3F : string; | |||||
attribute INITP_00 : string; | |||||
attribute INITP_01 : string; | |||||
attribute INITP_02 : string; | |||||
attribute INITP_03 : string; | |||||
attribute INITP_04 : string; | |||||
attribute INITP_05 : string; | |||||
attribute INITP_06 : string; | |||||
attribute INITP_07 : string; | |||||
-- | |||||
-- Attributes to define ROM contents during implementation synthesis. | |||||
-- | |||||
attribute INIT_00 of ram_1024_x_18 : label is "502C4042502A4045002201310F3E019301930193023301990193C001011A0027"; | |||||
attribute INIT_01 of ram_1024_x_18 : label is "013101310F3F019350D540535003404850C2404950A34052508C405750474050"; | |||||
attribute INIT_02 of ram_1024_x_18 : label is "011F02D401930904402D09FEA000C0080006A000013E10F00131011F40070131"; | |||||
attribute INIT_03 of ram_1024_x_18 : label is "02F14007022C5C38C902004101310F2E07000800019302090193543F4F590131"; | |||||
attribute INIT_04 of ram_1024_x_18 : label is "B0004B01006700574007022C004C01E20193A00000F700EA01D000EA01204007"; | |||||
attribute INIT_05 of ram_1024_x_18 : label is "B0004F0AB0004F0D011F54584F3A011F0E2B404C00776A2B0193016D504C4B04"; | |||||
attribute INIT_06 of ram_1024_x_18 : label is "8D02B4004B0450724B007BD08D037CD00D2B405B8E01F0E0017412F0011F13F0"; | |||||
attribute INIT_07 of ram_1024_x_18 : label is "032F00EAC10111A05077208000E000EA01E8A00078D0CD0177D0CD01A00079D0"; | |||||
attribute INIT_08 of ram_1024_x_18 : label is "1900588C018D02FEA00000F700EA01D05480CA018301A900A800870100EA7130"; | |||||
attribute INIT_09 of ram_1024_x_18 : label is "110000EA01404007022C0193009D5896018D030E1700588C018D1800588C018D"; | |||||
attribute INIT_0A of ram_1024_x_18 : label is "022C00B10193170058A3018D180058A3018D190058A3018D02FEA00000F700EA"; | |||||
attribute INIT_0B of ram_1024_x_18 : label is "54B2C60154B6C5010167A900A800870100E0019605100196016D019306104007"; | |||||
attribute INIT_0C of ram_1024_x_18 : label is "07020196016700E000EA0190070008000900019601310F3D02C60193A0000193"; | |||||
attribute INIT_0D of ram_1024_x_18 : label is "400700F40193016700E0019300EA0170070008000900400700F40193016700E0"; | |||||
attribute INIT_0E of ram_1024_x_18 : label is "C1080100C110C720C840C980A000C108400201060106C1080105C720C840C980"; | |||||
attribute INIT_0F of ram_1024_x_18 : label is "A00000F450F9208000E0AE008D010D000E00A00000EA01FFA000C10801060106"; | |||||
attribute INIT_10 of ram_1024_x_18 : label is "A000550CC10101070128A0005508C001000BA0000193016710D0016710E00193"; | |||||
attribute INIT_11 of ram_1024_x_18 : label is "C000A000551BC40101150414A0005516C30101100314A0005511C201010B0219"; | |||||
attribute INIT_12 of ram_1024_x_18 : label is "51204F114F014129552D20084000A000C00151294F134F014120552420084000"; | |||||
attribute INIT_13 of ram_1024_x_18 : label is "B8004061A000803AC1015D38C00A81010130A000CF0441315135200140004129"; | |||||
attribute INIT_14 of ram_1024_x_18 : label is "02069200020602061200B80001447010A000C0F6B80080C6A000A0DFBC00407B"; | |||||
attribute INIT_15 of ram_1024_x_18 : label is "0162A00F101012000162000E000E000E000E1100A0009200B800014470108101"; | |||||
attribute INIT_16 of ram_1024_x_18 : label is "108001671090A00001311F1001311F200156A000803A80075965C00AA0001100"; | |||||
attribute INIT_17 of ram_1024_x_18 : label is "D030B8000181102003060306030603061300B80001811030A000016710700167"; | |||||
attribute INIT_18 of ram_1024_x_18 : label is "002213000022A000800AA000C0F6B80080075D8BC011B800C0E9B80080B9A000"; | |||||
attribute INIT_19 of ram_1024_x_18 : label is "0F6301310F6901310F5001930193A00001310F20A00001310F0DA00001741200"; | |||||
attribute INIT_1A of ram_1024_x_18 : label is "01310F4E019601310F6501310F7A01310F6101310F6C01310F4201310F6F0131"; | |||||
attribute INIT_1B of ram_1024_x_18 : label is "019601310F4801310F5301310F4101310F4C01310F46019601310F5201310F4F"; | |||||
attribute INIT_1C of ram_1024_x_18 : label is "01310F6D01310F6D01310F6101310F7201310F6701310F6F01310F7201310F50"; | |||||
attribute INIT_1D of ram_1024_x_18 : label is "019301310F3001310F3001310F2E01310F3101310F76019601310F7201310F65"; | |||||
attribute INIT_1E of ram_1024_x_18 : label is "01310F6701310F6E01310F6901310F7401310F6901310F6101310F57A0000193"; | |||||
attribute INIT_1F of ram_1024_x_18 : label is "0F46019601310F5301310F4301310F4D019601310F7201310F6F01310F660196"; | |||||
attribute INIT_20 of ram_1024_x_18 : label is "0F50019601310F6E01310F690220A000019301310F6501310F6C01310F690131"; | |||||
attribute INIT_21 of ram_1024_x_18 : label is "A0000193013101310F7301310F6501310F7201310F6701310F6F01310F720131"; | |||||
attribute INIT_22 of ram_1024_x_18 : label is "0F4B01310F4F0193A000019601310F6501310F7301310F6101310F7201310F45"; | |||||
attribute INIT_23 of ram_1024_x_18 : label is "0F420193013101310F6C01310F61022001310F2D01310F450193A00001930131"; | |||||
attribute INIT_24 of ram_1024_x_18 : label is "01310F7301310F6B01310F6301310F6F01310F6C01310F62022001310F2D0131"; | |||||
attribute INIT_25 of ram_1024_x_18 : label is "01310F7201310F5001310F2D01310F50019301310F3301310F2D01310F310196"; | |||||
attribute INIT_26 of ram_1024_x_18 : label is "0F5701310F2D01310F5701F701310F6D01310F6101310F7201310F6701310F6F"; | |||||
attribute INIT_27 of ram_1024_x_18 : label is "01310F2D01310F52019302CB019601310F6501310F7401310F6901310F720131"; | |||||
attribute INIT_28 of ram_1024_x_18 : label is "019601310F3601310F3501310F32019601310F6401310F6101310F6501310F52"; | |||||
attribute INIT_29 of ram_1024_x_18 : label is "01310F6901310F7601310F6501310F4401310F2D01310F49019301310F7302CB"; | |||||
attribute INIT_2A of ram_1024_x_18 : label is "0F6C01310F6501310F4801310F2D01310F48019302C6019601310F6501310F63"; | |||||
attribute INIT_2B of ram_1024_x_18 : label is "01310F7401310F6101310F7401310F5301310F2D01310F53019301310F700131"; | |||||
attribute INIT_2C of ram_1024_x_18 : label is "0F7401310F7901310F62A00001310F4401310F49A000019301310F7301310F75"; | |||||
attribute INIT_2D of ram_1024_x_18 : label is "0F7201310F6901310F6601310F6E01310F6F01310F430193A00001310F650131"; | |||||
attribute INIT_2E of ram_1024_x_18 : label is "019601310F2901310F6E01310F2F01310F5901310F280220019601310F6D0131"; | |||||
attribute INIT_2F of ram_1024_x_18 : label is "0F610193A000019301310F7401310F7201310F6F01310F6201310F410193A000"; | |||||
attribute INIT_30 of ram_1024_x_18 : label is "0F640193A00001310F3D013101310F7301310F6501310F72013101310F640131"; | |||||
attribute INIT_31 of ram_1024_x_18 : label is "00000000000000000000000000000000430B01310F6101310F7401310F610131"; | |||||
attribute INIT_32 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; | |||||
attribute INIT_33 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; | |||||
attribute INIT_34 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; | |||||
attribute INIT_35 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; | |||||
attribute INIT_36 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; | |||||
attribute INIT_37 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; | |||||
attribute INIT_38 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; | |||||
attribute INIT_39 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; | |||||
attribute INIT_3A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; | |||||
attribute INIT_3B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; | |||||
attribute INIT_3C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; | |||||
attribute INIT_3D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; | |||||
attribute INIT_3E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; | |||||
attribute INIT_3F of ram_1024_x_18 : label is "43F580016000C004001143FC001353FB20104000E00000000000000000000000"; | |||||
attribute INITP_00 of ram_1024_x_18 : label is "34DF2118674436CC99F73CFD9FFFEF33FF7C0FF7FCCA2CFFF3DDDDDDDDF3FFFF"; | |||||
attribute INITP_01 of ram_1024_x_18 : label is "BDD42CA08AAA022AFFFC03FF3FC03CFBDDD5F3F3FCF3CFEF33FFF3CF3FBCD55C"; | |||||
attribute INITP_02 of ram_1024_x_18 : label is "2CAA2CB332CCE5D8C0EA89B19A2C998999752BD3D3D2F4F4EDCB72DCB72D2F33"; | |||||
attribute INITP_03 of ram_1024_x_18 : label is "3CCCF333CCCCCCCBF33333CCCCCCCCCCF33333CCCF333333333ECB2CCE667666"; | |||||
attribute INITP_04 of ram_1024_x_18 : label is "CCFF3333333CCCCCCCCCF333CCCCCCF33F33CCEF33BCCCCCBF3333333CCEF333"; | |||||
attribute INITP_05 of ram_1024_x_18 : label is "3BCCCCCEF33333F3333333B3332CCBCCCCCCCCF333333FCCCCCCCCF3F333CCCC"; | |||||
attribute INITP_06 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000F3333B3CCCF3"; | |||||
attribute INITP_07 of ram_1024_x_18 : label is "F233480000000000000000000000000000000000000000000000000000000000"; | |||||
-- | |||||
begin | |||||
-- | |||||
--Instantiate the Xilinx primitive for a block RAM | |||||
ram_1024_x_18: RAMB16_S9_S18 | |||||
--synthesis translate_off | |||||
--INIT values repeated to define contents for functional simulation | |||||
generic map (INIT_00 => X"502C4042502A4045002201310F3E019301930193023301990193C001011A0027", | |||||
INIT_01 => X"013101310F3F019350D540535003404850C2404950A34052508C405750474050", | |||||
INIT_02 => X"011F02D401930904402D09FEA000C0080006A000013E10F00131011F40070131", | |||||
INIT_03 => X"02F14007022C5C38C902004101310F2E07000800019302090193543F4F590131", | |||||
INIT_04 => X"B0004B01006700574007022C004C01E20193A00000F700EA01D000EA01204007", | |||||
INIT_05 => X"B0004F0AB0004F0D011F54584F3A011F0E2B404C00776A2B0193016D504C4B04", | |||||
INIT_06 => X"8D02B4004B0450724B007BD08D037CD00D2B405B8E01F0E0017412F0011F13F0", | |||||
INIT_07 => X"032F00EAC10111A05077208000E000EA01E8A00078D0CD0177D0CD01A00079D0", | |||||
INIT_08 => X"1900588C018D02FEA00000F700EA01D05480CA018301A900A800870100EA7130", | |||||
INIT_09 => X"110000EA01404007022C0193009D5896018D030E1700588C018D1800588C018D", | |||||
INIT_0A => X"022C00B10193170058A3018D180058A3018D190058A3018D02FEA00000F700EA", | |||||
INIT_0B => X"54B2C60154B6C5010167A900A800870100E0019605100196016D019306104007", | |||||
INIT_0C => X"07020196016700E000EA0190070008000900019601310F3D02C60193A0000193", | |||||
INIT_0D => X"400700F40193016700E0019300EA0170070008000900400700F40193016700E0", | |||||
INIT_0E => X"C1080100C110C720C840C980A000C108400201060106C1080105C720C840C980", | |||||
INIT_0F => X"A00000F450F9208000E0AE008D010D000E00A00000EA01FFA000C10801060106", | |||||
INIT_10 => X"A000550CC10101070128A0005508C001000BA0000193016710D0016710E00193", | |||||
INIT_11 => X"C000A000551BC40101150414A0005516C30101100314A0005511C201010B0219", | |||||
INIT_12 => X"51204F114F014129552D20084000A000C00151294F134F014120552420084000", | |||||
INIT_13 => X"B8004061A000803AC1015D38C00A81010130A000CF0441315135200140004129", | |||||
INIT_14 => X"02069200020602061200B80001447010A000C0F6B80080C6A000A0DFBC00407B", | |||||
INIT_15 => X"0162A00F101012000162000E000E000E000E1100A0009200B800014470108101", | |||||
INIT_16 => X"108001671090A00001311F1001311F200156A000803A80075965C00AA0001100", | |||||
INIT_17 => X"D030B8000181102003060306030603061300B80001811030A000016710700167", | |||||
INIT_18 => X"002213000022A000800AA000C0F6B80080075D8BC011B800C0E9B80080B9A000", | |||||
INIT_19 => X"0F6301310F6901310F5001930193A00001310F20A00001310F0DA00001741200", | |||||
INIT_1A => X"01310F4E019601310F6501310F7A01310F6101310F6C01310F4201310F6F0131", | |||||
INIT_1B => X"019601310F4801310F5301310F4101310F4C01310F46019601310F5201310F4F", | |||||
INIT_1C => X"01310F6D01310F6D01310F6101310F7201310F6701310F6F01310F7201310F50", | |||||
INIT_1D => X"019301310F3001310F3001310F2E01310F3101310F76019601310F7201310F65", | |||||
INIT_1E => X"01310F6701310F6E01310F6901310F7401310F6901310F6101310F57A0000193", | |||||
INIT_1F => X"0F46019601310F5301310F4301310F4D019601310F7201310F6F01310F660196", | |||||
INIT_20 => X"0F50019601310F6E01310F690220A000019301310F6501310F6C01310F690131", | |||||
INIT_21 => X"A0000193013101310F7301310F6501310F7201310F6701310F6F01310F720131", | |||||
INIT_22 => X"0F4B01310F4F0193A000019601310F6501310F7301310F6101310F7201310F45", | |||||
INIT_23 => X"0F420193013101310F6C01310F61022001310F2D01310F450193A00001930131", | |||||
INIT_24 => X"01310F7301310F6B01310F6301310F6F01310F6C01310F62022001310F2D0131", | |||||
INIT_25 => X"01310F7201310F5001310F2D01310F50019301310F3301310F2D01310F310196", | |||||
INIT_26 => X"0F5701310F2D01310F5701F701310F6D01310F6101310F7201310F6701310F6F", | |||||
INIT_27 => X"01310F2D01310F52019302CB019601310F6501310F7401310F6901310F720131", | |||||
INIT_28 => X"019601310F3601310F3501310F32019601310F6401310F6101310F6501310F52", | |||||
INIT_29 => X"01310F6901310F7601310F6501310F4401310F2D01310F49019301310F7302CB", | |||||
INIT_2A => X"0F6C01310F6501310F4801310F2D01310F48019302C6019601310F6501310F63", | |||||
INIT_2B => X"01310F7401310F6101310F7401310F5301310F2D01310F53019301310F700131", | |||||
INIT_2C => X"0F7401310F7901310F62A00001310F4401310F49A000019301310F7301310F75", | |||||
INIT_2D => X"0F7201310F6901310F6601310F6E01310F6F01310F430193A00001310F650131", | |||||
INIT_2E => X"019601310F2901310F6E01310F2F01310F5901310F280220019601310F6D0131", | |||||
INIT_2F => X"0F610193A000019301310F7401310F7201310F6F01310F6201310F410193A000", | |||||
INIT_30 => X"0F640193A00001310F3D013101310F7301310F6501310F72013101310F640131", | |||||
INIT_31 => X"00000000000000000000000000000000430B01310F6101310F7401310F610131", | |||||
INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", | |||||
INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", | |||||
INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", | |||||
INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", | |||||
INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", | |||||
INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", | |||||
INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", | |||||
INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", | |||||
INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", | |||||
INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", | |||||
INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", | |||||
INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", | |||||
INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", | |||||
INIT_3F => X"43F580016000C004001143FC001353FB20104000E00000000000000000000000", | |||||
INITP_00 => X"34DF2118674436CC99F73CFD9FFFEF33FF7C0FF7FCCA2CFFF3DDDDDDDDF3FFFF", | |||||
INITP_01 => X"BDD42CA08AAA022AFFFC03FF3FC03CFBDDD5F3F3FCF3CFEF33FFF3CF3FBCD55C", | |||||
INITP_02 => X"2CAA2CB332CCE5D8C0EA89B19A2C998999752BD3D3D2F4F4EDCB72DCB72D2F33", | |||||
INITP_03 => X"3CCCF333CCCCCCCBF33333CCCCCCCCCCF33333CCCF333333333ECB2CCE667666", | |||||
INITP_04 => X"CCFF3333333CCCCCCCCCF333CCCCCCF33F33CCEF33BCCCCCBF3333333CCEF333", | |||||
INITP_05 => X"3BCCCCCEF33333F3333333B3332CCBCCCCCCCCF333333FCCCCCCCCF3F333CCCC", | |||||
INITP_06 => X"0000000000000000000000000000000000000000000000000000F3333B3CCCF3", | |||||
INITP_07 => X"F233480000000000000000000000000000000000000000000000000000000000") | |||||
--synthesis translate_on | |||||
port map( DIB => "0000000000000000", | |||||
DIPB => "00", | |||||
ENB => '1', | |||||
WEB => '0', | |||||
SSRB => '0', | |||||
CLKB => clk, | |||||
ADDRB => address, | |||||
DOB => instruction(15 downto 0), | |||||
DOPB => instruction(17 downto 16), | |||||
DIA => jdata, | |||||
DIPA => jparity, | |||||
ENA => sel1, | |||||
WEA => '1', | |||||
SSRA => '0', | |||||
CLKA => update, | |||||
ADDRA=> jaddr, | |||||
DOA => doa(7 downto 0), | |||||
DOPA => dopa); | |||||
v2_bscan: BSCAN_VIRTEX2 | |||||
port map( TDO1 => tdo1, | |||||
TDO2 => tdo2, | |||||
UPDATE => update, | |||||
SHIFT => shift, | |||||
RESET => reset, | |||||
TDI => tdi, | |||||
SEL1 => sel1, | |||||
DRCK1 => drck1, | |||||
SEL2 => sel2, | |||||
DRCK2 => drck2, | |||||
CAPTURE => capture); | |||||
--buffer signal used as a clock | |||||
upload_clock: BUFG | |||||
port map( I => drck1, | |||||
O => drck1_buf); | |||||
-- Assign the reset to be active whenever the uploading subsystem is active | |||||
proc_reset <= sel1; | |||||
srlC1: SRLC16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => tdi, | |||||
CE => '1', | |||||
CLK => drck1_buf, | |||||
A0 => '1', | |||||
A1 => '0', | |||||
A2 => '1', | |||||
A3 => '1', | |||||
Q => jaddr(10), | |||||
Q15 => jaddr(8)); | |||||
flop1: FD | |||||
port map ( D => jaddr(10), | |||||
Q => jaddr(9), | |||||
C => drck1_buf); | |||||
srlC2: SRLC16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => jaddr(8), | |||||
CE => '1', | |||||
CLK => drck1_buf, | |||||
A0 => '1', | |||||
A1 => '0', | |||||
A2 => '1', | |||||
A3 => '1', | |||||
Q => jaddr(7), | |||||
Q15 => tap5); | |||||
flop2: FD | |||||
port map ( D => jaddr(7), | |||||
Q => jaddr(6), | |||||
C => drck1_buf); | |||||
srlC3: SRLC16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => tap5, | |||||
CE => '1', | |||||
CLK => drck1_buf, | |||||
A0 => '1', | |||||
A1 => '0', | |||||
A2 => '1', | |||||
A3 => '1', | |||||
Q => jaddr(5), | |||||
Q15 => jaddr(3)); | |||||
flop3: FD | |||||
port map ( D => jaddr(5), | |||||
Q => jaddr(4), | |||||
C => drck1_buf); | |||||
srlC4: SRLC16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => jaddr(3), | |||||
CE => '1', | |||||
CLK => drck1_buf, | |||||
A0 => '1', | |||||
A1 => '0', | |||||
A2 => '1', | |||||
A3 => '1', | |||||
Q => jaddr(2), | |||||
Q15 => tap11); | |||||
flop4: FD | |||||
port map ( D => jaddr(2), | |||||
Q => jaddr(1), | |||||
C => drck1_buf); | |||||
srlC5: SRLC16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => tap11, | |||||
CE => '1', | |||||
CLK => drck1_buf, | |||||
A0 => '1', | |||||
A1 => '0', | |||||
A2 => '1', | |||||
A3 => '1', | |||||
Q => jaddr(0), | |||||
Q15 => jdata(7)); | |||||
flop5: FD | |||||
port map ( D => jaddr(0), | |||||
Q => jparity(0), | |||||
C => drck1_buf); | |||||
srlC6: SRLC16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => jdata(7), | |||||
CE => '1', | |||||
CLK => drck1_buf, | |||||
A0 => '1', | |||||
A1 => '0', | |||||
A2 => '1', | |||||
A3 => '1', | |||||
Q => jdata(6), | |||||
Q15 => tap17); | |||||
flop6: FD | |||||
port map ( D => jdata(6), | |||||
Q => jdata(5), | |||||
C => drck1_buf); | |||||
srlC7: SRLC16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => tap17, | |||||
CE => '1', | |||||
CLK => drck1_buf, | |||||
A0 => '1', | |||||
A1 => '0', | |||||
A2 => '1', | |||||
A3 => '1', | |||||
Q => jdata(4), | |||||
Q15 => jdata(2)); | |||||
flop7: FD | |||||
port map ( D => jdata(4), | |||||
Q => jdata(3), | |||||
C => drck1_buf); | |||||
srlC8: SRLC16E | |||||
--synthesis translate_off | |||||
generic map (INIT => X"0000") | |||||
--synthesis translate_on | |||||
port map( D => jdata(2), | |||||
CE => '1', | |||||
CLK => drck1_buf, | |||||
A0 => '1', | |||||
A1 => '0', | |||||
A2 => '1', | |||||
A3 => '1', | |||||
Q => jdata(1), | |||||
Q15 => tdo1); | |||||
flop8: FD | |||||
port map ( D => jdata(1), | |||||
Q => jdata(0), | |||||
C => drck1_buf); | |||||
end low_level_definition; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- END OF FILE progctrl.vhd | |||||
-- | |||||
------------------------------------------------------------------------------------ |
@@ -0,0 +1,146 @@ | |||||
-- UART Receiver with integral 16 byte FIFO buffer | |||||
-- | |||||
-- 8 bit, no parity, 1 stop bit | |||||
-- | |||||
-- Version : 1.00 | |||||
-- Version Date : 16th October 2002 | |||||
-- | |||||
-- Start of design entry : 16th October 2002 | |||||
-- | |||||
-- Ken Chapman | |||||
-- Xilinx Ltd | |||||
-- Benchmark House | |||||
-- 203 Brooklands Road | |||||
-- Weybridge | |||||
-- Surrey KT13 ORH | |||||
-- United Kingdom | |||||
-- | |||||
-- chapman@xilinx.com | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- NOTICE: | |||||
-- | |||||
-- Copyright Xilinx, Inc. 2002. This code may be contain portions patented by other | |||||
-- third parties. By providing this core as one possible implementation of a standard, | |||||
-- Xilinx is making no representation that the provided implementation of this standard | |||||
-- is free from any claims of infringement by any third party. Xilinx expressly | |||||
-- disclaims any warranty with respect to the adequacy of the implementation, including | |||||
-- but not limited to any warranty or representation that the implementation is free | |||||
-- from claims of any third party. Futhermore, Xilinx is providing this core as a | |||||
-- courtesy to you and suggests that you contact all third parties to obtain the | |||||
-- necessary rights to use this implementation. | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Library declarations | |||||
-- | |||||
-- The Unisim Library is used to define Xilinx primitives. It is also used during | |||||
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd | |||||
-- | |||||
library IEEE; | |||||
use IEEE.STD_LOGIC_1164.ALL; | |||||
use IEEE.STD_LOGIC_ARITH.ALL; | |||||
use IEEE.STD_LOGIC_UNSIGNED.ALL; | |||||
library unisim; | |||||
use unisim.vcomponents.all; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Main Entity for UART_RX | |||||
-- | |||||
entity uart_rx is | |||||
Port ( serial_in : in std_logic; | |||||
data_out : out std_logic_vector(7 downto 0); | |||||
read_buffer : in std_logic; | |||||
reset_buffer : in std_logic; | |||||
en_16_x_baud : in std_logic; | |||||
buffer_data_present : out std_logic; | |||||
buffer_full : out std_logic; | |||||
buffer_half_full : out std_logic; | |||||
clk : in std_logic); | |||||
end uart_rx; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Start of Main Architecture for UART_RX | |||||
-- | |||||
architecture macro_level_definition of uart_rx is | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Components used in UART_RX and defined in subsequent entities. | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Constant (K) Compact UART Receiver | |||||
-- | |||||
component kcuart_rx | |||||
Port ( serial_in : in std_logic; | |||||
data_out : out std_logic_vector(7 downto 0); | |||||
data_strobe : out std_logic; | |||||
en_16_x_baud : in std_logic; | |||||
clk : in std_logic); | |||||
end component; | |||||
-- | |||||
-- 'Bucket Brigade' FIFO | |||||
-- | |||||
component bbfifo_16x8 | |||||
Port ( data_in : in std_logic_vector(7 downto 0); | |||||
data_out : out std_logic_vector(7 downto 0); | |||||
reset : in std_logic; | |||||
write : in std_logic; | |||||
read : in std_logic; | |||||
full : out std_logic; | |||||
half_full : out std_logic; | |||||
data_present : out std_logic; | |||||
clk : in std_logic); | |||||
end component; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Signals used in UART_RX | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
signal uart_data_out : std_logic_vector(7 downto 0); | |||||
signal fifo_write : std_logic; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Start of UART_RX circuit description | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
begin | |||||
-- 8 to 1 multiplexer to convert parallel data to serial | |||||
kcuart: kcuart_rx | |||||
port map ( serial_in => serial_in, | |||||
data_out => uart_data_out, | |||||
data_strobe => fifo_write, | |||||
en_16_x_baud => en_16_x_baud, | |||||
clk => clk ); | |||||
buf: bbfifo_16x8 | |||||
port map ( data_in => uart_data_out, | |||||
data_out => data_out, | |||||
reset => reset_buffer, | |||||
write => fifo_write, | |||||
read => read_buffer, | |||||
full => buffer_full, | |||||
half_full => buffer_half_full, | |||||
data_present => buffer_data_present, | |||||
clk => clk); | |||||
end macro_level_definition; | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- END OF FILE UART_RX.VHD | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
@@ -0,0 +1,154 @@ | |||||
-- UART Transmitter with integral 16 byte FIFO buffer | |||||
-- | |||||
-- 8 bit, no parity, 1 stop bit | |||||
-- | |||||
-- Special version made 2nd November 2005 in which the data_present signal | |||||
-- was brough out as well as the half and full status signals. | |||||
-- | |||||
-- Version : 1.00 | |||||
-- Version Date : 14th October 2002 | |||||
-- | |||||
-- Start of design entry : 14th October 2002 | |||||
-- | |||||
-- Ken Chapman | |||||
-- Xilinx Ltd | |||||
-- Benchmark House | |||||
-- 203 Brooklands Road | |||||
-- Weybridge | |||||
-- Surrey KT13 ORH | |||||
-- United Kingdom | |||||
-- | |||||
-- chapman@xilinx.com | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- NOTICE: | |||||
-- | |||||
-- Copyright Xilinx, Inc. 2002. This code may be contain portions patented by other | |||||
-- third parties. By providing this core as one possible implementation of a standard, | |||||
-- Xilinx is making no representation that the provided implementation of this standard | |||||
-- is free from any claims of infringement by any third party. Xilinx expressly | |||||
-- disclaims any warranty with respect to the adequacy of the implementation, including | |||||
-- but not limited to any warranty or representation that the implementation is free | |||||
-- from claims of any third party. Futhermore, Xilinx is providing this core as a | |||||
-- courtesy to you and suggests that you contact all third parties to obtain the | |||||
-- necessary rights to use this implementation. | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Library declarations | |||||
-- | |||||
-- The Unisim Library is used to define Xilinx primitives. It is also used during | |||||
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd | |||||
-- | |||||
library IEEE; | |||||
use IEEE.STD_LOGIC_1164.ALL; | |||||
use IEEE.STD_LOGIC_ARITH.ALL; | |||||
use IEEE.STD_LOGIC_UNSIGNED.ALL; | |||||
library unisim; | |||||
use unisim.vcomponents.all; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Main Entity for uart_tx_plus | |||||
-- | |||||
entity uart_tx_plus is | |||||
Port ( data_in : in std_logic_vector(7 downto 0); | |||||
write_buffer : in std_logic; | |||||
reset_buffer : in std_logic; | |||||
en_16_x_baud : in std_logic; | |||||
serial_out : out std_logic; | |||||
buffer_data_present : out std_logic; | |||||
buffer_full : out std_logic; | |||||
buffer_half_full : out std_logic; | |||||
clk : in std_logic); | |||||
end uart_tx_plus; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Start of Main Architecture for uart_tx_plus | |||||
-- | |||||
architecture macro_level_definition of uart_tx_plus is | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Components used in uart_tx_plus and defined in subsequent entities. | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Constant (K) Compact UART Transmitter | |||||
-- | |||||
component kcuart_tx | |||||
Port ( data_in : in std_logic_vector(7 downto 0); | |||||
send_character : in std_logic; | |||||
en_16_x_baud : in std_logic; | |||||
serial_out : out std_logic; | |||||
Tx_complete : out std_logic; | |||||
clk : in std_logic); | |||||
end component; | |||||
-- | |||||
-- 'Bucket Brigade' FIFO | |||||
-- | |||||
component bbfifo_16x8 | |||||
Port ( data_in : in std_logic_vector(7 downto 0); | |||||
data_out : out std_logic_vector(7 downto 0); | |||||
reset : in std_logic; | |||||
write : in std_logic; | |||||
read : in std_logic; | |||||
full : out std_logic; | |||||
half_full : out std_logic; | |||||
data_present : out std_logic; | |||||
clk : in std_logic); | |||||
end component; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Signals used in uart_tx_plus | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
signal fifo_data_out : std_logic_vector(7 downto 0); | |||||
signal fifo_data_present : std_logic; | |||||
signal fifo_read : std_logic; | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- Start of UART_TX circuit description | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
begin | |||||
-- 8 to 1 multiplexer to convert parallel data to serial | |||||
kcuart: kcuart_tx | |||||
port map ( data_in => fifo_data_out, | |||||
send_character => fifo_data_present, | |||||
en_16_x_baud => en_16_x_baud, | |||||
serial_out => serial_out, | |||||
Tx_complete => fifo_read, | |||||
clk => clk); | |||||
buf: bbfifo_16x8 | |||||
port map ( data_in => data_in, | |||||
data_out => fifo_data_out, | |||||
reset => reset_buffer, | |||||
write => write_buffer, | |||||
read => fifo_read, | |||||
full => buffer_full, | |||||
half_full => buffer_half_full, | |||||
data_present => fifo_data_present, | |||||
clk => clk); | |||||
buffer_data_present <= fifo_data_present; | |||||
end macro_level_definition; | |||||
------------------------------------------------------------------------------------ | |||||
-- | |||||
-- END OF FILE uart_tx_plus.vhd | |||||
-- | |||||
------------------------------------------------------------------------------------ | |||||
@@ -0,0 +1,7 @@ | |||||
hexapod_gl: main.c hexapod.c | |||||
gcc -I../linux/liblicks/include main.c ../linux/liblicks/servo/servo.c -o hexapod_gl -lgl -lglut | |||||
# gcc -framework OpenGL -framework GLUT -I../linux/liblicks/include main.c ../linux/liblicks/servo/servo.c -o hexapod_gl | |||||
clean: | |||||
rm -f *~ *.o hexapod_gl |
@@ -0,0 +1,159 @@ | |||||
#include <stdio.h> | |||||
#include <stdint.h> | |||||
#include <fcntl.h> | |||||
#include "servo.h" | |||||
#define NUM_LEGS 6 | |||||
const float x_offsets[NUM_LEGS]={ 0.20, 0.00,-0.20,-0.20, 0.00, 0.20}; | |||||
const float y_offsets[NUM_LEGS]={ 0.10, 0.15, 0.10,-0.10,-0.15,-0.10}; | |||||
float phi1[6]; | |||||
float phi2[6]; | |||||
float phi3[6]; | |||||
void | |||||
draw_hexapod() { | |||||
const float c =0.05f; | |||||
const float f =0.20f; | |||||
const float t =0.325f; | |||||
const float p1=0.025f; | |||||
const float thickness=0.005f; | |||||
int i,fd; | |||||
fd=open("/tmp/servodata",O_RDONLY); | |||||
if(fd==-1) { | |||||
// perror("/tmp/servodata"); | |||||
} else { | |||||
read(fd,servo_pwm,sizeof(servo_pwm)); | |||||
close(fd); | |||||
for(i=0;i<6;i++) { | |||||
phi1[i]=servo_pwm[i*3]; | |||||
phi1[i]-=servo_offsets[i*3]; | |||||
phi2[i]=servo_pwm[i*3+1]; | |||||
phi2[i]-=servo_offsets[i*3+1]; | |||||
phi3[i]=servo_pwm[i*3+2]; | |||||
phi3[i]-=servo_offsets[i*3+2]; | |||||
phi1[i]*=0.1/8.5; | |||||
phi2[i]*=-0.1/8.5; | |||||
phi3[i]*=-0.1/8.5; | |||||
if(i>=3) { | |||||
phi2[i]=-phi2[i]; | |||||
phi3[i]=-phi3[i]; | |||||
} | |||||
} | |||||
} | |||||
glRotatef(90,0,0,1); | |||||
glRotatef(60,0,1,0); | |||||
glColor3f(0.8,0.8,0.8); | |||||
glBegin(GL_TRIANGLES); | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
glVertex3f(x_offsets[i],y_offsets[i],0); | |||||
} | |||||
glEnd(); | |||||
glBegin(GL_QUADS); | |||||
glVertex3f(x_offsets[0],y_offsets[0],0); | |||||
glVertex3f(x_offsets[2],y_offsets[2],0); | |||||
glVertex3f(x_offsets[3],y_offsets[3],0); | |||||
glVertex3f(x_offsets[5],y_offsets[5],0); | |||||
glEnd(); | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
glPushMatrix(); | |||||
// move into leg base position | |||||
glTranslatef(x_offsets[i],y_offsets[i],0); | |||||
// rotate 180 degrees if on other side | |||||
if(i>=(NUM_LEGS/2)) { | |||||
glRotatef(-180,0,0,1); | |||||
} | |||||
glRotatef(phi1[i],0,0,1); | |||||
glColor3f(1,1,0); | |||||
glBegin(GL_QUADS); | |||||
glVertex3f(0,0,0); | |||||
glVertex3f(0,c,0); | |||||
glVertex3f(thickness,c,0); | |||||
glVertex3f(thickness,0,0); | |||||
glEnd(); | |||||
glTranslatef(0,c,0); | |||||
glRotatef(90,0,1,0); | |||||
glRotatef(phi2[i],0,0,1); | |||||
glColor3f(0,0,1); | |||||
glBegin(GL_QUADS); | |||||
glVertex3f(0,0,0); | |||||
glVertex3f(0,f,0); | |||||
glVertex3f(thickness,f,0); | |||||
glVertex3f(thickness,0,0); | |||||
glVertex3f(0,f,0); | |||||
glVertex3f(0,0,0); | |||||
glVertex3f(0,0,thickness); | |||||
glVertex3f(0,f,thickness); | |||||
glVertex3f(0,f,0); | |||||
glVertex3f(thickness,f,0); | |||||
glVertex3f(0,f,thickness); | |||||
glVertex3f(thickness,f,thickness); | |||||
glVertex3f(thickness,f,0); | |||||
glVertex3f(thickness,0,0); | |||||
glVertex3f(thickness,0,thickness); | |||||
glVertex3f(thickness,f,thickness); | |||||
glVertex3f(0,0,thickness); | |||||
glVertex3f(0,f,thickness); | |||||
glVertex3f(thickness,f,thickness); | |||||
glVertex3f(thickness,0,thickness); | |||||
glEnd(); | |||||
glTranslatef(0,f,0); | |||||
glRotatef(-90-phi3[i],0,0,1); | |||||
glColor3f(1,0,0); | |||||
glBegin(GL_QUADS); | |||||
glVertex3f( p1, 0.0f, thickness/2); | |||||
glVertex3f(0.0f, -p1, thickness/2); | |||||
glVertex3f( -p1, 0.0f, thickness/2); | |||||
glVertex3f(0.0f, t, thickness/2); | |||||
glVertex3f( p1, 0.0f, thickness/2); | |||||
glVertex3f( p1, 0.0f, -thickness/2); | |||||
glVertex3f(0.0f, -p1, thickness/2); | |||||
glVertex3f(0.0f, -p1, -thickness/2); | |||||
glVertex3f(0.0f, -p1, thickness/2); | |||||
glVertex3f(0.0f, -p1, -thickness/2); | |||||
glVertex3f( -p1, 0.0f, thickness/2); | |||||
glVertex3f( -p1, 0.0f, -thickness/2); | |||||
glVertex3f( -p1, 0.0f, thickness/2); | |||||
glVertex3f( -p1, 0.0f, -thickness/2); | |||||
glVertex3f(0.0f, t, thickness/2); | |||||
glVertex3f(0.0f, t, -thickness/2); | |||||
glVertex3f(0.0f, t, thickness/2); | |||||
glVertex3f( p1, 0.0f, -thickness/2); | |||||
glVertex3f( p1, 0.0f, thickness/2); | |||||
glVertex3f(0.0f, t, -thickness/2); | |||||
glVertex3f( p1, 0.0f, -thickness/2); | |||||
glVertex3f(0.0f, -p1, -thickness/2); | |||||
glVertex3f( -p1, 0.0f, -thickness/2); | |||||
glVertex3f(0.0f, t, -thickness/2); | |||||
glEnd(); | |||||
glPopMatrix(); | |||||
} | |||||
} |
@@ -0,0 +1,79 @@ | |||||
// stolen from NeHe opengl tutorial, thanks! :) | |||||
#include <GL/gl.h> // Header File For The OpenGL32 Library | |||||
#include <GL/glu.h> // Header File For The GLu32 Library | |||||
#include <GL/glut.h> // Header File For The GLut Library | |||||
#include "hexapod.c" | |||||
#define kWindowWidth 500 | |||||
#define kWindowHeight 500 | |||||
GLvoid InitGL(GLvoid); | |||||
GLvoid DrawGLScene(GLvoid); | |||||
GLvoid ReSizeGLScene(int Width, int Height); | |||||
int main(int argc, char** argv) | |||||
{ | |||||
load_calibration("/etc/calibration.bin"); | |||||
glutInit(&argc, argv); | |||||
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); | |||||
glutInitWindowSize (kWindowWidth, kWindowHeight); | |||||
glutInitWindowPosition (100, 100); | |||||
glutCreateWindow (argv[0]); | |||||
InitGL(); | |||||
glutReshapeFunc(ReSizeGLScene); | |||||
glutDisplayFunc(DrawGLScene); | |||||
glutIdleFunc(DrawGLScene); | |||||
glutMainLoop(); | |||||
return 0; | |||||
} | |||||
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window | |||||
{ | |||||
if (height==0) // Prevent A Divide By Zero By | |||||
{ | |||||
height=1; // Making Height Equal One | |||||
} | |||||
glViewport(0, 0, width, height); // Reset The Current Viewport | |||||
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix | |||||
glLoadIdentity(); // Reset The Projection Matrix | |||||
// Calculate The Aspect Ratio Of The Window | |||||
// gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); | |||||
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix | |||||
glLoadIdentity(); // Reset The Modelview Matrix | |||||
} | |||||
GLvoid InitGL(GLvoid) // All Setup For OpenGL Goes Here | |||||
{ | |||||
// glEnable(GL_DEPTH_TEST); // Enables Depth Testing | |||||
glShadeModel(GL_SMOOTH); // Enables Smooth Shading | |||||
glDisable(GL_LIGHTING); | |||||
glColor3f(1.0f,1.0f,1.0f); | |||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background | |||||
glClearDepth(1.0f); // Depth Buffer Setup | |||||
glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do | |||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations | |||||
glViewport(0,0,500,500); | |||||
} | |||||
GLvoid DrawGLScene(GLvoid) // Here's Where We Do All The Drawing | |||||
{ | |||||
glClearColor(0.0f,0.0f,0.0f,1.0f); | |||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer | |||||
glLoadIdentity(); | |||||
// glTranslatef(0.0f,0.0f,0.2f); | |||||
draw_hexapod(); | |||||
glutSwapBuffers(); | |||||
usleep(1000); | |||||
} | |||||
@@ -0,0 +1,374 @@ | |||||
/* | |||||
* linux/arch/arm/mach-at91/board-sam9260ek.c | |||||
* | |||||
* Copyright (C) 2005 SAN People | |||||
* Copyright (C) 2006 Atmel | |||||
* | |||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||||
*/ | |||||
#include <linux/types.h> | |||||
#include <linux/init.h> | |||||
#include <linux/mm.h> | |||||
#include <linux/module.h> | |||||
#include <linux/platform_device.h> | |||||
#include <linux/spi/spi.h> | |||||
#include <linux/spi/at73c213.h> | |||||
#include <linux/clk.h> | |||||
#include <linux/gpio_keys.h> | |||||
#include <linux/input.h> | |||||
#include <asm/setup.h> | |||||
#include <asm/mach-types.h> | |||||
#include <asm/irq.h> | |||||
#include <asm/mach/arch.h> | |||||
#include <asm/mach/map.h> | |||||
#include <asm/mach/irq.h> | |||||
#include <mach/hardware.h> | |||||
#include <mach/board.h> | |||||
#include <mach/gpio.h> | |||||
#include <mach/at91sam9_smc.h> | |||||
#include <mach/at91_shdwc.h> | |||||
#include "sam9_smc.h" | |||||
#include "generic.h" | |||||
static void __init ek_map_io(void) | |||||
{ | |||||
/* Initialize processor: 18.432 MHz crystal */ | |||||
at91sam9260_initialize(18432000); | |||||
/* DGBU on ttyS0. (Rx & Tx only) */ | |||||
at91_register_uart(0, 0, 0); | |||||
/* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ | |||||
at91_register_uart(AT91SAM9260_ID_US0, 1, 0); | |||||
/* USART2 on ttyS2. (Rx, Tx, RTS, CTS) */ | |||||
at91_register_uart(AT91SAM9260_ID_US2, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); | |||||
/* set serial console to ttyS0 (ie, DBGU) */ | |||||
at91_set_serial_console(0); | |||||
} | |||||
static void __init ek_init_irq(void) | |||||
{ | |||||
at91sam9260_init_interrupts(NULL); | |||||
} | |||||
/* | |||||
* USB Host port | |||||
*/ | |||||
static struct at91_usbh_data __initdata ek_usbh_data = { | |||||
.ports = 2, | |||||
}; | |||||
/* | |||||
* USB Device port | |||||
*/ | |||||
static struct at91_udc_data __initdata ek_udc_data = { | |||||
.vbus_pin = AT91_PIN_PC5, | |||||
.pullup_pin = 0, /* pull-up driven by UDC */ | |||||
}; | |||||
/* | |||||
* Compact Flash (via Expansion Connector) | |||||
*/ | |||||
static struct at91_cf_data __initdata ek_cf_data = { | |||||
// .irq_pin = ... user defined | |||||
// .det_pin = ... user defined | |||||
// .vcc_pin = ... user defined | |||||
// .rst_pin = ... user defined | |||||
.chipselect = 4, | |||||
}; | |||||
/* | |||||
* Audio | |||||
*/ | |||||
static struct at73c213_board_info at73c213_data = { | |||||
.ssc_id = 0, | |||||
.shortname = "AT91SAM9260-EK external DAC", | |||||
}; | |||||
#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) | |||||
static void __init at73c213_set_clk(struct at73c213_board_info *info) | |||||
{ | |||||
struct clk *pck0; | |||||
struct clk *plla; | |||||
pck0 = clk_get(NULL, "pck0"); | |||||
plla = clk_get(NULL, "plla"); | |||||
/* AT73C213 MCK Clock */ | |||||
at91_set_B_periph(AT91_PIN_PC1, 0); /* PCK0 */ | |||||
clk_set_parent(pck0, plla); | |||||
clk_put(plla); | |||||
info->dac_clk = pck0; | |||||
} | |||||
#else | |||||
static void __init at73c213_set_clk(struct at73c213_board_info *info) {} | |||||
#endif | |||||
/* | |||||
* SPI devices. | |||||
*/ | |||||
static struct spi_board_info ek_spi_devices[] = { | |||||
#if !defined(CONFIG_MMC_AT91) | |||||
{ /* DataFlash chip */ | |||||
.modalias = "mtd_dataflash", | |||||
.chip_select = 1, | |||||
.max_speed_hz = 15 * 1000 * 1000, | |||||
.bus_num = 0, | |||||
}, | |||||
#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) | |||||
{ /* DataFlash card */ | |||||
.modalias = "mtd_dataflash", | |||||
.chip_select = 0, | |||||
.max_speed_hz = 15 * 1000 * 1000, | |||||
.bus_num = 0, | |||||
}, | |||||
#endif | |||||
#endif | |||||
#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) | |||||
{ /* AT73C213 DAC */ | |||||
.modalias = "at73c213", | |||||
.chip_select = 0, | |||||
.max_speed_hz = 10 * 1000 * 1000, | |||||
.bus_num = 1, | |||||
.mode = SPI_MODE_1, | |||||
.platform_data = &at73c213_data, | |||||
}, | |||||
#endif | |||||
{ | |||||
.modalias = "spidev", | |||||
.chip_select = 0, | |||||
.bus_num = 1, | |||||
.max_speed_hz = 15 * 1000 * 1000 | |||||
} | |||||
}; | |||||
/* | |||||
* MACB Ethernet device | |||||
*/ | |||||
static struct at91_eth_data __initdata ek_macb_data = { | |||||
.phy_irq_pin = AT91_PIN_PA7, | |||||
.is_rmii = 1, | |||||
}; | |||||
/* | |||||
* NAND flash | |||||
*/ | |||||
static struct mtd_partition __initdata ek_nand_partition[] = { | |||||
{ | |||||
.name = "Bootstrap", | |||||
.offset = 0, | |||||
.size = SZ_4M, | |||||
}, | |||||
{ | |||||
.name = "Partition 1", | |||||
.offset = MTDPART_OFS_NXTBLK, | |||||
.size = 60 * SZ_1M, | |||||
}, | |||||
{ | |||||
.name = "Partition 2", | |||||
.offset = MTDPART_OFS_NXTBLK, | |||||
.size = MTDPART_SIZ_FULL, | |||||
}, | |||||
}; | |||||
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) | |||||
{ | |||||
*num_partitions = ARRAY_SIZE(ek_nand_partition); | |||||
return ek_nand_partition; | |||||
} | |||||
static struct atmel_nand_data __initdata ek_nand_data = { | |||||
.ale = 21, | |||||
.cle = 22, | |||||
// .det_pin = ... not connected | |||||
.rdy_pin = AT91_PIN_PC13, | |||||
.enable_pin = AT91_PIN_PC14, | |||||
.partition_info = nand_partitions, | |||||
#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) | |||||
.bus_width_16 = 1, | |||||
#else | |||||
.bus_width_16 = 0, | |||||
#endif | |||||
}; | |||||
static struct sam9_smc_config __initdata ek_nand_smc_config = { | |||||
.ncs_read_setup = 0, | |||||
.nrd_setup = 1, | |||||
.ncs_write_setup = 0, | |||||
.nwe_setup = 1, | |||||
.ncs_read_pulse = 3, | |||||
.nrd_pulse = 3, | |||||
.ncs_write_pulse = 3, | |||||
.nwe_pulse = 3, | |||||
.read_cycle = 5, | |||||
.write_cycle = 5, | |||||
.mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, | |||||
.tdf_cycles = 2, | |||||
}; | |||||
static void __init ek_add_device_nand(void) | |||||
{ | |||||
/* setup bus-width (8 or 16) */ | |||||
if (ek_nand_data.bus_width_16) | |||||
ek_nand_smc_config.mode |= AT91_SMC_DBW_16; | |||||
else | |||||
ek_nand_smc_config.mode |= AT91_SMC_DBW_8; | |||||
/* configure chip-select 3 (NAND) */ | |||||
sam9_smc_configure(3, &ek_nand_smc_config); | |||||
at91_add_device_nand(&ek_nand_data); | |||||
} | |||||
/* | |||||
* MCI (SD/MMC) | |||||
*/ | |||||
static struct at91_mmc_data __initdata ek_mmc_data = { | |||||
.slot_b = 1, | |||||
.wire4 = 1, | |||||
// .det_pin = ... not connected | |||||
// .wp_pin = ... not connected | |||||
// .vcc_pin = ... not connected | |||||
}; | |||||
/* | |||||
* LEDs | |||||
*/ | |||||
static struct gpio_led ek_leds[] = { | |||||
{ /* "bottom" led, green, userled1 to be defined */ | |||||
.name = "ds5", | |||||
.gpio = AT91_PIN_PA6, | |||||
.active_low = 1, | |||||
.default_trigger = "none", | |||||
}, | |||||
{ /* "power" led, yellow */ | |||||
.name = "ds1", | |||||
.gpio = AT91_PIN_PA9, | |||||
.default_trigger = "heartbeat", | |||||
} | |||||
}; | |||||
/* | |||||
* GPIO Buttons | |||||
*/ | |||||
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | |||||
static struct gpio_keys_button ek_buttons[] = { | |||||
{ | |||||
.gpio = AT91_PIN_PA30, | |||||
.code = BTN_3, | |||||
.desc = "Button 3", | |||||
.active_low = 1, | |||||
.wakeup = 1, | |||||
}, | |||||
{ | |||||
.gpio = AT91_PIN_PA31, | |||||
.code = BTN_4, | |||||
.desc = "Button 4", | |||||
.active_low = 1, | |||||
.wakeup = 1, | |||||
} | |||||
}; | |||||
static struct gpio_keys_platform_data ek_button_data = { | |||||
.buttons = ek_buttons, | |||||
.nbuttons = ARRAY_SIZE(ek_buttons), | |||||
}; | |||||
static struct platform_device ek_button_device = { | |||||
.name = "gpio-keys", | |||||
.id = -1, | |||||
.num_resources = 0, | |||||
.dev = { | |||||
.platform_data = &ek_button_data, | |||||
} | |||||
}; | |||||
static void __init ek_add_device_buttons(void) | |||||
{ | |||||
at91_set_gpio_input(AT91_PIN_PA30, 1); /* btn3 */ | |||||
at91_set_deglitch(AT91_PIN_PA30, 1); | |||||
at91_set_gpio_input(AT91_PIN_PA31, 1); /* btn4 */ | |||||
at91_set_deglitch(AT91_PIN_PA31, 1); | |||||
platform_device_register(&ek_button_device); | |||||
} | |||||
#else | |||||
static void __init ek_add_device_buttons(void) {} | |||||
#endif | |||||
static void __init ek_board_init(void) | |||||
{ | |||||
/* Serial */ | |||||
at91_add_device_serial(); | |||||
/* USB Host */ | |||||
at91_add_device_usbh(&ek_usbh_data); | |||||
/* USB Device */ | |||||
at91_add_device_udc(&ek_udc_data); | |||||
/* SPI */ | |||||
at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); | |||||
/* NAND */ | |||||
ek_add_device_nand(); | |||||
/* Ethernet */ | |||||
at91_add_device_eth(&ek_macb_data); | |||||
/* MMC */ | |||||
at91_add_device_mmc(0, &ek_mmc_data); | |||||
/* I2C */ | |||||
at91_add_device_i2c(NULL, 0); | |||||
/* Compact Flash */ | |||||
at91_add_device_cf(&ek_cf_data); | |||||
/* SSC (to AT73C213) */ | |||||
at73c213_set_clk(&at73c213_data); | |||||
at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); | |||||
/* LEDs */ | |||||
at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); | |||||
/* Push Buttons */ | |||||
ek_add_device_buttons(); | |||||
/* shutdown controller, wakeup button (5 msec low) */ | |||||
at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW | |||||
| AT91_SHDW_RTTWKEN); | |||||
} | |||||
MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK") | |||||
/* Maintainer: Atmel */ | |||||
.phys_io = AT91_BASE_SYS, | |||||
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | |||||
.boot_params = AT91_SDRAM_BASE + 0x100, | |||||
.timer = &at91sam926x_timer, | |||||
.map_io = ek_map_io, | |||||
.init_irq = ek_init_irq, | |||||
.init_machine = ek_board_init, | |||||
MACHINE_END |
@@ -0,0 +1,25 @@ | |||||
CC=arm-linux-uclibc-gcc | |||||
STRIP=arm-linux-uclibc-strip | |||||
STRIP=echo | |||||
CFLAGS=-Wall -O3 -I../liblicks/include | |||||
OBJS=monitor.o | |||||
BIN=monitor | |||||
all: $(BIN) | |||||
$(BIN): $(OBJS) | |||||
$(CC) $(OBJS) -o $(BIN) -lm | |||||
$(STRIP) $(BIN) | |||||
../liblicks/liblicks.a: | |||||
make -C ../liblicks/ liblicks.a | |||||
../liblicks/liblicks-fakespi.a: | |||||
make -C ../liblicks/ liblicks-fakespi.a | |||||
clean: | |||||
rm -f *.o *~ $(BIN) | |||||
make -C ../liblicks/ clean |
@@ -0,0 +1 @@ | |||||
o`.kcWpa6nfX |
@@ -0,0 +1,159 @@ | |||||
#include <unistd.h> | |||||
#include <math.h> | |||||
#include <stdio.h> | |||||
#include <fcntl.h> | |||||
#include <termios.h> | |||||
#include <sys/time.h> | |||||
#include "servo.h" | |||||
#include "spi.h" | |||||
#include "ik.h" | |||||
void ik_to_servos(bot *); | |||||
int get_time(); | |||||
int ad_fd; | |||||
static bot idle_position = { | |||||
{0,0,-20}, // body position | |||||
{0,0,0}, // body rotation | |||||
{ // leg positions | |||||
{{ 166, 130, 0},}, // leg 0 | |||||
{{ 0, 180, 0},}, // leg 1 | |||||
{{-166, 130, 0},}, // ... | |||||
{{-166,-130, 0},}, | |||||
{{ 0,-180, 0},}, | |||||
{{ 166,-130, 0},} | |||||
} | |||||
}; | |||||
int | |||||
main(int argc, char **argv) { | |||||
struct termios t; | |||||
int flags_stdio; | |||||
int quit=0; | |||||
int frame=0; | |||||
int t_frame_start, t_frame_end; | |||||
int dump_fd; | |||||
char c; | |||||
int i,j, int_z; | |||||
int leg; | |||||
unsigned char adbuffer[12]; | |||||
unsigned char ad_max[6]={0,0,0,0,0,0}; | |||||
unsigned char ad_min[6]={255,255,255,255,255,255}; | |||||
unsigned char ad; | |||||
load_calibration("calibration.bin"); | |||||
spi_open(0,33000000); | |||||
ad_fd=open("/dev/ttyS2",O_RDWR); | |||||
if(ad_fd<0) { | |||||
printf("can't open /dev/ttyS2."); | |||||
exit(2); | |||||
} | |||||
tcgetattr(0,&t); | |||||
t.c_lflag&=~(ICANON|ECHO); | |||||
tcsetattr(0,TCSANOW,&t); | |||||
tcgetattr(ad_fd,&t); | |||||
t.c_lflag&=~(ICANON|ECHO); | |||||
tcsetattr(ad_fd,TCSANOW,&t); | |||||
flags_stdio=fcntl(0, F_GETFL,0); | |||||
flags_stdio|=O_NONBLOCK; | |||||
fcntl(0, F_SETFL,flags_stdio); | |||||
ik(&idle_position); | |||||
ik_to_servos(&idle_position); | |||||
for(j=0;j<200;j++) { | |||||
write(ad_fd,&c,1); | |||||
read(ad_fd,&adbuffer,12); | |||||
for(i=0;i<6;i++) { | |||||
if(i==adbuffer[2*i]) { | |||||
if(adbuffer[2*i+1]>10) { | |||||
if(ad_min[i]>adbuffer[2*i+1]) ad_min[i]=(adbuffer[2*i+1]+ad_min[i])/2; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
leg=0; | |||||
while(!quit) { | |||||
t_frame_start=get_time(); | |||||
write(ad_fd,&c,1); | |||||
read(ad_fd,&adbuffer,12); | |||||
for(i=0;i<6;i++) { | |||||
if(i==adbuffer[2*i]) { | |||||
ad=adbuffer[2*i+1]; | |||||
if((ad-ad_min[i])<10) { | |||||
if(idle_position.leg[i].position.z<100) idle_position.leg[i].position.z+=1; | |||||
} else if((ad-ad_min[i])>20) { | |||||
if(idle_position.leg[i].position.z>0) idle_position.leg[i].position.z-=1; | |||||
} | |||||
} | |||||
} | |||||
if(read(0,&c,1)==1) { | |||||
switch(c) { | |||||
case 27: | |||||
case 'q': | |||||
quit=1; | |||||
break; | |||||
} | |||||
} | |||||
ik(&idle_position); | |||||
t_frame_end=get_time(); | |||||
if(t_frame_end-t_frame_start>20000) { | |||||
printf("frame %d slack %d\n",frame,t_frame_end-t_frame_start); | |||||
} | |||||
while(t_frame_end<t_frame_start+20000) t_frame_end=get_time(); | |||||
ik_to_servos(&idle_position); | |||||
frame++; | |||||
} | |||||
close(ad_fd); | |||||
spi_close(); | |||||
flags_stdio=fcntl(0, F_GETFL,0); flags_stdio&=~(O_NONBLOCK); fcntl(0, | |||||
F_SETFL,flags_stdio); | |||||
tcgetattr(0,&t); | |||||
t.c_lflag|=(ICANON|ECHO|ECHOE|ISIG); | |||||
tcsetattr(0,TCSANOW,&t); | |||||
return 0; | |||||
} | |||||
void | |||||
ik_to_servos(bot *b) { | |||||
int i,j; | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
for(j=0;j<3;j++) { | |||||
if(!isnan(b->leg[i].ik_angle[j])) { | |||||
servo_pwm[i*3+j]=b->leg[i].ik_angle[j]*8.5*1800.0/M_PI+servo_offsets[i*3+j]; | |||||
} | |||||
} | |||||
} | |||||
spi_update_servos(); | |||||
} | |||||
int | |||||
get_time() { | |||||
struct timeval t; | |||||
gettimeofday(&t,NULL); | |||||
return (t.tv_sec*1000000+t.tv_usec); | |||||
} |
@@ -0,0 +1,189 @@ | |||||
#include <unistd.h> | |||||
#include <math.h> | |||||
#include <stdio.h> | |||||
#include <fcntl.h> | |||||
#include <termios.h> | |||||
#include <sys/time.h> | |||||
#include "servo.h" | |||||
#include "spi.h" | |||||
#include "ik.h" | |||||
void ik_to_servos(bot *); | |||||
int get_time(); | |||||
int ad_fd; | |||||
static bot idle_position = { | |||||
{0,0,-20}, // body position | |||||
{0,0,0}, // body rotation | |||||
{ // leg positions | |||||
{{ 166, 130, 0},}, // leg 0 | |||||
{{ 0, 180, 0},}, // leg 1 | |||||
{{-166, 130, 0},}, // ... | |||||
{{-166,-130, 0},}, | |||||
{{ 0,-180, 0},}, | |||||
{{ 166,-130, 0},} | |||||
} | |||||
}; | |||||
int | |||||
main(int argc, char **argv) { | |||||
struct termios t; | |||||
int flags_stdio; | |||||
int quit=0; | |||||
int frame=0; | |||||
int t_frame_start, t_frame_end; | |||||
int dump_fd; | |||||
char c; | |||||
int i, int_z; | |||||
int leg; | |||||
unsigned char adbuffer[12]; | |||||
unsigned char ad_max[6]={0,0,0,0,0,0}; | |||||
unsigned char ad_min[6]={255,255,255,255,255,255}; | |||||
load_calibration("calibration.bin"); | |||||
spi_open(0,33000000); | |||||
ad_fd=open("/dev/ttyS2",O_RDWR); | |||||
if(ad_fd<0) { | |||||
printf("can't open /dev/ttyS2."); | |||||
exit(2); | |||||
} | |||||
tcgetattr(0,&t); | |||||
t.c_lflag&=~(ICANON|ECHO); | |||||
tcsetattr(0,TCSANOW,&t); | |||||
tcgetattr(ad_fd,&t); | |||||
t.c_lflag&=~(ICANON|ECHO); | |||||
tcsetattr(ad_fd,TCSANOW,&t); | |||||
flags_stdio=fcntl(0, F_GETFL,0); | |||||
flags_stdio|=O_NONBLOCK; | |||||
fcntl(0, F_SETFL,flags_stdio); | |||||
leg=0; | |||||
while(!quit) { | |||||
write(ad_fd,&c,1); | |||||
read(ad_fd,&adbuffer,12); | |||||
printf("\f"); | |||||
printf(" val rval min max avg diff z\n"); | |||||
for(i=0;i<6;i++) { | |||||
printf("%d: %3d %3d %3d %3d %3d %3d %3.2f\n",adbuffer[2*i],adbuffer[2*i+1],adbuffer[2*i+1]-ad_min[i],ad_min[i], ad_max[i],(ad_min[i]+ad_max[i])/2,ad_max[i]-ad_min[i],idle_position.leg[i].position.z); | |||||
if(ad_min[i]>adbuffer[2*i+1]) ad_min[i]=adbuffer[2*i+1]; | |||||
if(ad_max[i]<adbuffer[2*i+1]) ad_max[i]=adbuffer[2*i+1]; | |||||
} | |||||
printf("\nleg (+/-): %d\nd: dump to ad.bin\n",leg); | |||||
if(read(0,&c,1)==1) { | |||||
switch(c) { | |||||
case 27: | |||||
case 'q': | |||||
quit=1; | |||||
break; | |||||
case 'a': | |||||
idle_position.leg[leg].position.z++; | |||||
break; | |||||
case 'z': | |||||
idle_position.leg[leg].position.z--; | |||||
break; | |||||
case '+': | |||||
if(leg<5) leg++; | |||||
break; | |||||
case '-': | |||||
if(leg>0) leg--; | |||||
break; | |||||
case 'r': | |||||
for(i=0;i<6;i++) { | |||||
for(int_z=0;int_z<20;int_z++) { | |||||
idle_position.leg[i].position.z=int_z; | |||||
t_frame_start=get_time(); | |||||
ik(&idle_position); | |||||
t_frame_end=get_time(); | |||||
while(t_frame_end<t_frame_start+50000) t_frame_end=get_time(); | |||||
ik_to_servos(&idle_position); | |||||
write(ad_fd,&c,1); | |||||
read(ad_fd,&adbuffer,12); | |||||
if(ad_min[i]>adbuffer[2*i+1]) ad_min[i]=adbuffer[2*i+1]; | |||||
if(ad_max[i]<adbuffer[2*i+1]) ad_max[i]=adbuffer[2*i+1]; | |||||
} | |||||
for(int_z=20;int_z>0;int_z--) { | |||||
idle_position.leg[i].position.z=int_z; | |||||
t_frame_start=get_time(); | |||||
ik(&idle_position); | |||||
t_frame_end=get_time(); | |||||
while(t_frame_end<t_frame_start+50000) t_frame_end=get_time(); | |||||
ik_to_servos(&idle_position); | |||||
write(ad_fd,&c,1); | |||||
read(ad_fd,&adbuffer,12); | |||||
if(ad_min[i]>adbuffer[2*i+1]) ad_min[i]=adbuffer[2*i+1]; | |||||
if(ad_max[i]<adbuffer[2*i+1]) ad_max[i]=adbuffer[2*i+1]; | |||||
} | |||||
} | |||||
case 'd': | |||||
dump_fd=open("ad.bin",O_WRONLY|O_CREAT|O_TRUNC); | |||||
if(dump_fd>=0) { | |||||
write(dump_fd,ad_min,sizeof(ad_min)); | |||||
write(dump_fd,ad_max,sizeof(ad_max)); | |||||
} | |||||
} | |||||
} | |||||
t_frame_start=get_time(); | |||||
ik(&idle_position); | |||||
t_frame_end=get_time(); | |||||
if(t_frame_end-t_frame_start>20000) { | |||||
printf("frame %d slack %d\n",frame,t_frame_end-t_frame_start); | |||||
} | |||||
while(t_frame_end<t_frame_start+20000) t_frame_end=get_time(); | |||||
ik_to_servos(&idle_position); | |||||
frame++; | |||||
} | |||||
close(ad_fd); | |||||
spi_close(); | |||||
flags_stdio=fcntl(0, F_GETFL,0); flags_stdio&=~(O_NONBLOCK); fcntl(0, | |||||
F_SETFL,flags_stdio); | |||||
tcgetattr(0,&t); | |||||
t.c_lflag|=(ICANON|ECHO|ECHOE|ISIG); | |||||
tcsetattr(0,TCSANOW,&t); | |||||
return 0; | |||||
} | |||||
void | |||||
ik_to_servos(bot *b) { | |||||
int i,j; | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
for(j=0;j<3;j++) { | |||||
if(!isnan(b->leg[i].ik_angle[j])) { | |||||
servo_pwm[i*3+j]=b->leg[i].ik_angle[j]*8.5*1800.0/M_PI+servo_offsets[i*3+j]; | |||||
} | |||||
} | |||||
} | |||||
spi_update_servos(); | |||||
} | |||||
int | |||||
get_time() { | |||||
struct timeval t; | |||||
gettimeofday(&t,NULL); | |||||
return (t.tv_sec*1000000+t.tv_usec); | |||||
} |
@@ -0,0 +1,19 @@ | |||||
#CC=arm-linux-uclibc-gcc | |||||
#STRIP=arm-linux-uclibc-strip | |||||
#STRIP=echo | |||||
#CFLAGS=-Wall -Os -pipe -mtune=arm9tdmi -march=armv5te -mabi=apcs-gnu -msoft-float -I../liblicks/include | |||||
CFLAGS=-I../liblicks/include | |||||
OBJS=main.o ../liblicks/liblicks.a | |||||
BIN=calibration | |||||
$(BIN): $(OBJS) | |||||
$(CC) $(OBJS) -o $(BIN) -lm | |||||
$(STRIP) $(BIN) | |||||
clean: | |||||
rm -f *.o *~ $(BIN) | |||||
@@ -0,0 +1,19 @@ | |||||
#CC=arm-linux-uclibc-gcc | |||||
#STRIP=arm-linux-uclibc-strip | |||||
#STRIP=echo | |||||
#CFLAGS=-Wall -Os -pipe -mtune=arm9tdmi -march=armv5te -mabi=apcs-gnu -msoft-float -I../liblicks/include | |||||
OBJS=main.o ../liblicks/liblicks.a | |||||
BIN=calibration | |||||
$(BIN): $(OBJS) | |||||
$(CC) $(OBJS) -o $(BIN) -lm | |||||
$(STRIP) $(BIN) | |||||
clean: | |||||
rm -f *.o *~ $(BIN) | |||||
@@ -0,0 +1,133 @@ | |||||
#include <termios.h> | |||||
#include <stdint.h> | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <math.h> | |||||
#include <sys/time.h> | |||||
#include <fcntl.h> | |||||
#include <servo.h> | |||||
#include <ik.h> | |||||
#include <spi.h> | |||||
int servo_power[NUM_SERVOS]; | |||||
int | |||||
main(int argc, char **argv) { | |||||
int fd; | |||||
int i,j,l,s; | |||||
int frame; | |||||
uint32_t time; | |||||
char c; | |||||
uint16_t pwm; | |||||
struct termios t; | |||||
int step=1; | |||||
printf("welcome.\n"); | |||||
spi_open(0,33000000); | |||||
for(i=0;i<NUM_SERVOS;i++) { servo_pwm[i]=0; servo_power[i]=0; } | |||||
spi_update_servos(); | |||||
load_calibration("calibration.bin"); | |||||
tcgetattr(0,&t); | |||||
t.c_lflag&=~(ICANON|ECHO|ECHOE|ISIG); | |||||
tcsetattr(0,TCSANOW,&t); | |||||
l=0; | |||||
do { | |||||
printf("\f"); | |||||
for(i=0;i<NUM_SERVOS;i++) { | |||||
if(!(i%3)) { | |||||
printf("\n"); | |||||
if((i/3)==l) { | |||||
if(servo_power[i]) { | |||||
printf("!> "); | |||||
} else { | |||||
printf(" > "); | |||||
} | |||||
} else { | |||||
if(servo_power[i]) { | |||||
printf("! "); | |||||
} else { | |||||
printf(" "); | |||||
} | |||||
} | |||||
} | |||||
printf("%04x (%d) ",servo_offsets[i],servo_offsets[i]); | |||||
} | |||||
printf("\n\nazsxdc: move servo\n+-: select leg(%d)\n[]: increase/decrease step size (%d)\np: power on/off leg\n12: save min/max value\nw: dump\nf: save to calibration.bin\nq: quit\n> ",l,step); | |||||
c=getchar(); | |||||
printf("%c (%02x)\n",c,c); | |||||
switch(c) { | |||||
case 'a': | |||||
servo_offsets[l*3]+=step; | |||||
break; | |||||
case 'z': | |||||
servo_offsets[l*3]-=step; | |||||
break; | |||||
case 's': | |||||
servo_offsets[l*3+1]+=step; | |||||
break; | |||||
case 'x': | |||||
servo_offsets[l*3+1]-=step; | |||||
break; | |||||
case 'd': | |||||
servo_offsets[l*3+2]+=step; | |||||
break; | |||||
case 'c': | |||||
servo_offsets[l*3+2]-=step; | |||||
break; | |||||
case '+': | |||||
if((l+1)<NUM_LEGS) l++; | |||||
break; | |||||
case '-': | |||||
if(l>0) l--; | |||||
break; | |||||
case '[': | |||||
if(step>=10) step/=10; | |||||
break; | |||||
case ']': | |||||
step*=10; | |||||
break; | |||||
case 'w': | |||||
printf("/* Servo current values */\n\nuint16_t servo_base[]= {"); | |||||
for(i=0;i<NUM_SERVOS;i++) { | |||||
if(!(i%3)) printf("\n"); | |||||
printf(" 0x%04x,",servo_pwm[i]); | |||||
} | |||||
printf("\n};\n\n"); | |||||
printf("/* press any key */\n"); | |||||
getchar(); | |||||
break; | |||||
case 'f': | |||||
unlink("calibration.bin.bak"); | |||||
rename("calibration.bin","calibration.bin.bak"); | |||||
fd=open("calibration.bin",O_WRONLY|O_CREAT|O_TRUNC); | |||||
write(fd,servo_offsets,sizeof(servo_offsets)); | |||||
close(fd); | |||||
break; | |||||
case 'p': | |||||
if(!servo_power[l*3]) { | |||||
for(i=0;i<3;i++) servo_power[l*3+i]=1; | |||||
} else { | |||||
for(i=0;i<3;i++) servo_power[l*3+i]=0; | |||||
} | |||||
} | |||||
for(i=0;i<NUM_SERVOS;i++) { | |||||
servo_pwm[i]=servo_power[i]*servo_offsets[i]; | |||||
} | |||||
spi_update_servos(); | |||||
} while(c!='q'); | |||||
spi_close(); | |||||
tcgetattr(0,&t); | |||||
t.c_lflag|=(ICANON|ECHO|ECHOE|ISIG); | |||||
tcsetattr(0,TCSANOW,&t); | |||||
} | |||||
@@ -0,0 +1,17 @@ | |||||
CC=arm-linux-uclibc-gcc | |||||
STRIP=arm-linux-uclibc-strip | |||||
#STRIP=echo | |||||
CFLAGS=-O3 -I../libfcks/include | |||||
OBJS=main.o ../libfcks/libfcks.a | |||||
demo: $(OBJS) | |||||
$(CC) $(OBJS) -o demo -lm | |||||
$(STRIP) demo | |||||
../libfcks/libfcks.a: | |||||
make -C ../libfcks/ | |||||
clean: | |||||
rm -f *.o *~ demo | |||||
@@ -0,0 +1,457 @@ | |||||
#include <stdint.h> | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <math.h> | |||||
#include <sys/types.h> | |||||
#include <fcntl.h> | |||||
#include <sys/stat.h> | |||||
#include <sys/time.h> | |||||
#include <servo.h> | |||||
#include <spi.h> | |||||
#include <ik_double.h> | |||||
#warning code uses old leg numbering! | |||||
void move_to(struct bot_double*, struct bot_double*, int); | |||||
void demo(); | |||||
int get_time(); | |||||
static struct bot_double startup_position = { | |||||
{0,0,0}, // body offset | |||||
{0,0,0}, // world position | |||||
{0,0,0}, // body rotation | |||||
{ | |||||
{ // leg 0 | |||||
{ 80, 40, 0}, // base offset | |||||
{200,120,10}, // end effector position | |||||
{ 0, 0, 0} // leg angles | |||||
},{ // leg 1 | |||||
{ 0, 60, 0}, | |||||
{ 0,200,10}, | |||||
{ 0, 0, 0}, // leg angles | |||||
},{ | |||||
{-80, 40, 0}, | |||||
{-200,120,10}, | |||||
{ 0, 0, 0} // leg angles | |||||
},{ | |||||
{ 80,-40, 0}, | |||||
{200,-120,10}, | |||||
{ 0, 0, 0} // leg angles | |||||
},{ | |||||
{ 0,-60, 0}, | |||||
{0,-200,10}, | |||||
{ 0, 0, 0} // leg angles | |||||
},{ | |||||
{-80,-40, 0}, | |||||
{-200,-120,10}, | |||||
{ 0, 0, 0} // leg angles | |||||
}} | |||||
}; | |||||
static struct bot_double idle_position = { | |||||
{0,0,0}, // body offset | |||||
{0,0,0}, // world position | |||||
{0,0,0}, // body rotation | |||||
{ | |||||
{ // leg 0 | |||||
{ 80, 40, 0}, // base offset | |||||
{150,120,120}, // end effector position | |||||
{ 0, 0, 0} // leg angles | |||||
},{ // leg 1 | |||||
{ 0, 60, 0}, | |||||
{ 0,160,120}, | |||||
{ 0, 0, 0}, // leg angles | |||||
},{ | |||||
{-80, 40, 0}, // leg 2 | |||||
{-150,120,120}, | |||||
{ 0, 0, 0} // leg angles | |||||
},{ | |||||
{ 80,-40, 0}, // leg 3 | |||||
{150,-120,120}, | |||||
{ 0, 0, 0} // leg angles | |||||
},{ | |||||
{ 0,-60, 0}, | |||||
{0,-160,120}, | |||||
{ 0, 0, 0} // leg angles | |||||
},{ | |||||
{-80,-40, 0}, | |||||
{-150,-120,120}, | |||||
{ 0, 0, 0} // leg angles | |||||
}} | |||||
}; | |||||
static struct bot_double current_position; | |||||
static struct bot_double target_position; | |||||
int | |||||
main(int argc, char **argv) { | |||||
int i,j; | |||||
int frame; | |||||
uint32_t time; | |||||
printf("welcome.\n"); | |||||
spi_open(0,33000000); | |||||
for(i=0;i<NUM_SERVOS;i++) servo[i]=0; | |||||
spi_update_servos(servo); | |||||
ik_double(&startup_position); | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
for(j=0;j<3;j++) { | |||||
servo[i*3+j]=servo_directions[i*3+j]*(startup_position.leg[i].angle[j])*1800.0/M_PI+servo_offsets[i*3+j]; | |||||
} | |||||
} | |||||
spi_update_servos(servo); | |||||
demo(); | |||||
spi_close(); | |||||
} | |||||
void | |||||
move_to(struct bot_double *current_position, struct bot_double *target_position, int num_frames) { | |||||
struct bot_double frame_position; | |||||
int frame; | |||||
unsigned int frame_start, frame_end; | |||||
struct timespec delay; | |||||
int leg,i,j; | |||||
memcpy(&frame_position,current_position,sizeof(struct bot_double)); | |||||
for(frame=1;frame<=num_frames;frame++) { | |||||
frame_start=get_time(); | |||||
frame_position.position.x=current_position->position.x+frame*(target_position->position.x-current_position->position.x)/num_frames; | |||||
frame_position.position.y=current_position->position.y+frame*(target_position->position.y-current_position->position.y)/num_frames; | |||||
frame_position.position.z=current_position->position.z+frame*(target_position->position.z-current_position->position.z)/num_frames; | |||||
frame_position.orientation.rx=current_position->orientation.rx+frame*(target_position->orientation.rx-current_position->orientation.rx)/num_frames; | |||||
frame_position.orientation.ry=current_position->orientation.ry+frame*(target_position->orientation.ry-current_position->orientation.ry)/num_frames; | |||||
frame_position.orientation.rz=current_position->orientation.rz+frame*(target_position->orientation.rz-current_position->orientation.rz)/num_frames; | |||||
for(leg=0;leg<NUM_LEGS;leg++) { | |||||
frame_position.leg[leg].position.x=current_position->leg[leg].position.x+frame*(target_position->leg[leg].position.x-current_position->leg[leg].position.x)/num_frames; | |||||
frame_position.leg[leg].position.y=current_position->leg[leg].position.y+frame*(target_position->leg[leg].position.y-current_position->leg[leg].position.y)/num_frames; | |||||
frame_position.leg[leg].position.z=current_position->leg[leg].position.z+frame*(target_position->leg[leg].position.z-current_position->leg[leg].position.z)/num_frames; | |||||
} | |||||
ik_double(&frame_position); | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
for(j=0;j<3;j++) { | |||||
servo[i*3+j]=servo_directions[i*3+j]*(frame_position.leg[i].angle[j])*1800.0/M_PI+servo_offsets[i*3+j]; | |||||
} | |||||
} | |||||
frame_end=get_time(); | |||||
if(frame_end-frame_start>20000) { | |||||
printf("frame %d delay %d\n",frame,frame_end-frame_start); | |||||
} | |||||
while(frame_end-frame_start<20000) { | |||||
// delay.tv_sec=0; | |||||
// delay.tv_nsec=(frame_end-frame_start)*1000; | |||||
// nanosleep(&delay,NULL); | |||||
frame_end=get_time(); | |||||
} | |||||
spi_update_servos(servo); | |||||
} | |||||
memcpy(current_position,target_position,sizeof(struct bot_double)); | |||||
} | |||||
void | |||||
move_to_parabolic(struct bot_double *current_position, struct bot_double *target_position, int num_frames, double dx, double dy, double dz, double a, int leg_mask) { | |||||
struct bot_double frame_position; | |||||
int frame; | |||||
int frame_start, frame_end; | |||||
int leg,i,j; | |||||
double t,d; | |||||
memcpy(&frame_position,current_position,sizeof(struct bot_double)); | |||||
for(frame=1;frame<=num_frames;frame++) { | |||||
frame_start=get_time(); | |||||
t=2.0*frame/num_frames-1.0; | |||||
d=a-(a*t*t); | |||||
frame_position.position.x=current_position->position.x+frame*(target_position->position.x-current_position->position.x)/num_frames; | |||||
frame_position.position.y=current_position->position.y+frame*(target_position->position.y-current_position->position.y)/num_frames; | |||||
frame_position.position.z=current_position->position.z+frame*(target_position->position.z-current_position->position.z)/num_frames; | |||||
frame_position.orientation.rx=current_position->orientation.rx+frame*(target_position->orientation.rx-current_position->orientation.rx)/num_frames; | |||||
frame_position.orientation.ry=current_position->orientation.ry+frame*(target_position->orientation.ry-current_position->orientation.ry)/num_frames; | |||||
frame_position.orientation.rz=current_position->orientation.rz+frame*(target_position->orientation.rz-current_position->orientation.rz)/num_frames; | |||||
for(leg=0;leg<NUM_LEGS;leg++) { | |||||
if(!((1<<leg)&leg_mask)) { | |||||
frame_position.leg[leg].position.x=current_position->leg[leg].position.x+frame*(target_position->leg[leg].position.x-current_position->leg[leg].position.x)/num_frames; | |||||
frame_position.leg[leg].position.y=current_position->leg[leg].position.y+frame*(target_position->leg[leg].position.y-current_position->leg[leg].position.y)/num_frames; | |||||
frame_position.leg[leg].position.z=current_position->leg[leg].position.z+frame*(target_position->leg[leg].position.z-current_position->leg[leg].position.z)/num_frames; | |||||
} else { | |||||
frame_position.leg[leg].position.x=dx*d + current_position->leg[leg].position.x + frame*(target_position->leg[leg].position.x - current_position->leg[leg].position.x)/num_frames; | |||||
frame_position.leg[leg].position.y=dy*d + current_position->leg[leg].position.y + frame*(target_position->leg[leg].position.y - current_position->leg[leg].position.y)/num_frames; | |||||
frame_position.leg[leg].position.z=dz*d + current_position->leg[leg].position.z + frame*(target_position->leg[leg].position.z - current_position->leg[leg].position.z)/num_frames; | |||||
} | |||||
} | |||||
ik_double(&frame_position); | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
for(j=0;j<3;j++) { | |||||
servo[i*3+j]=servo_directions[i*3+j]*(frame_position.leg[i].angle[j])*1800.0/M_PI+servo_offsets[i*3+j]; | |||||
} | |||||
} | |||||
frame_end=get_time(); | |||||
if(frame_end-frame_start>20000) { | |||||
printf("frame %d delay %d\n",frame,frame_end-frame_start); | |||||
} | |||||
while(frame_end-frame_start<20000) { | |||||
// delay.tv_sec=0; | |||||
// delay.tv_nsec=(frame_end-frame_start)*1000; | |||||
// nanosleep(&delay,NULL); | |||||
frame_end=get_time(); | |||||
} | |||||
spi_update_servos(servo); | |||||
} | |||||
memcpy(current_position,target_position,sizeof(struct bot_double)); | |||||
} | |||||
void | |||||
walk(double dx, double dy, double alpha, int frames, int mode) { | |||||
int leg_mask; | |||||
int i; | |||||
double step_height=30; | |||||
struct bot_double start_position; | |||||
memcpy(&target_position, ¤t_position,sizeof(struct bot_double)); | |||||
memcpy(&start_position,¤t_position,sizeof(struct bot_double)); | |||||
leg_mask=0; | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
if(i%2) { | |||||
leg_mask|=(1<<i); | |||||
target_position.leg[i].position.x=dx+(current_position.leg[i].position.x*cos(alpha/2)-current_position.leg[i].position.y*sin(alpha/2)); | |||||
target_position.leg[i].position.y=dy+(current_position.leg[i].position.x*sin(alpha/2)+current_position.leg[i].position.y*cos(alpha/2)); | |||||
} | |||||
} | |||||
move_to_parabolic(¤t_position,&target_position,frames,0,0,-1,step_height,leg_mask); | |||||
target_position.position.x=start_position.position.x+dx/2; | |||||
target_position.position.y=start_position.position.y+dy/2; | |||||
target_position.orientation.rz=start_position.orientation.rz+alpha/2; | |||||
move_to(¤t_position,&target_position,frames); | |||||
leg_mask=0; | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
if(!(i%2)) { | |||||
leg_mask|=(1<<i); | |||||
target_position.leg[i].position.x=dx+(current_position.leg[i].position.x*cos(alpha/2)-current_position.leg[i].position.y*sin(alpha/2)); | |||||
target_position.leg[i].position.y=dy+(current_position.leg[i].position.x*sin(alpha/2)+current_position.leg[i].position.y*cos(alpha/2)); | |||||
} | |||||
} | |||||
move_to_parabolic(¤t_position,&target_position,frames,0,0,-1,step_height,leg_mask); | |||||
target_position.position.x=start_position.position.x+dx; | |||||
target_position.position.y=start_position.position.y+dy; | |||||
target_position.orientation.rz=start_position.orientation.rz+alpha; | |||||
move_to(¤t_position,&target_position,frames); | |||||
memcpy(&target_position,¤t_position,sizeof(struct bot_double)); | |||||
} | |||||
void | |||||
demo() { | |||||
int i,j; | |||||
// stand up | |||||
memcpy(¤t_position,&startup_position,sizeof(struct bot_double)); | |||||
memcpy(&target_position,¤t_position,sizeof(struct bot_double)); | |||||
// lift up | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
target_position.leg[i].position.z=130; | |||||
} | |||||
move_to(¤t_position,&target_position,50); | |||||
// move legs to idle position | |||||
for(i=0;i<(NUM_LEGS/2);i++) { | |||||
memcpy(&target_position.leg[i],&idle_position.leg[i],sizeof(struct leg_double)); | |||||
memcpy(&target_position.leg[NUM_LEGS-1-i],&idle_position.leg[NUM_LEGS-1-i],sizeof(struct leg_double)); | |||||
move_to_parabolic(¤t_position,&target_position,25,0,0,-1,30,(1<<i)|(1<<(NUM_LEGS-1-i))); | |||||
} | |||||
// walk a square | |||||
move_to(¤t_position,&target_position,25); | |||||
walk(0,50,0,20,0); | |||||
target_position.position.z=20; | |||||
move_to(¤t_position,&target_position,25); | |||||
walk(-50,0,0,20,0); | |||||
target_position.position.z=40; | |||||
move_to(¤t_position,&target_position,25); | |||||
walk(0,-50,0,20,0); | |||||
target_position.position.z=-20; | |||||
move_to(¤t_position,&target_position,50); | |||||
walk(50,0,0,20,0); | |||||
// downward spiral | |||||
sleep(1); | |||||
target_position.position.z=0; | |||||
target_position.orientation.rx=5*M_PI/180.0; | |||||
move_to(¤t_position,&target_position,25); | |||||
for(j=0;j<3;j++) { | |||||
for(i=0;i<16;i++) { | |||||
target_position.orientation.rx=sin(M_PI*i/8.0)*5.0*M_PI/180.0; | |||||
target_position.orientation.ry=cos(M_PI*i/8.0)*5.0*M_PI/180.0; | |||||
target_position.position.z=i+j*16; | |||||
move_to(¤t_position,&target_position,8); | |||||
} | |||||
} | |||||
target_position.orientation.rx=0; | |||||
target_position.orientation.ry=0; | |||||
target_position.position.z=0; | |||||
move_to(¤t_position,&target_position,25); | |||||
// shake it, baby | |||||
for(i=0;i<4;i++) { | |||||
target_position.position.z=10*i; | |||||
if(i%2) { | |||||
target_position.orientation.rz=5.0*M_PI/180.0; | |||||
} else { | |||||
target_position.orientation.rz=-5.0*M_PI/180; | |||||
} | |||||
move_to(¤t_position,&target_position,25); | |||||
} | |||||
target_position.orientation.rz=0; | |||||
move_to(¤t_position,&target_position,5); | |||||
sleep(1); | |||||
// and some more.. | |||||
for(i=3;i>=0;i--) { | |||||
target_position.position.z=10*i; | |||||
if(i%2) { | |||||
target_position.position.y=20; | |||||
} else { | |||||
target_position.position.y=-20; | |||||
} | |||||
move_to(¤t_position,&target_position,25); | |||||
} | |||||
target_position.position.y=0; | |||||
move_to(¤t_position,&target_position,25); | |||||
// lift middle legs | |||||
target_position.leg[1].position.z-=80; | |||||
target_position.leg[1].position.y+=20; | |||||
target_position.leg[4].position.z-=80; | |||||
target_position.leg[4].position.y-=20; | |||||
move_to(¤t_position,&target_position,100); | |||||
target_position.leg[1].position.y+=80; | |||||
target_position.leg[4].position.y-=80; | |||||
move_to(¤t_position,&target_position,100); | |||||
target_position.position.z+=30; | |||||
move_to(¤t_position,&target_position,25); | |||||
target_position.position.z-=60; | |||||
move_to(¤t_position,&target_position,50); | |||||
target_position.position.z+=30; | |||||
move_to(¤t_position,&target_position,25); | |||||
target_position.leg[1].position.y-=80; | |||||
target_position.leg[4].position.y+=80; | |||||
move_to(¤t_position,&target_position,100); | |||||
memcpy(&target_position,&idle_position,sizeof(struct bot_double)); | |||||
move_to(¤t_position,&target_position,50); | |||||
/* | |||||
walk(50,50,-15*91,25,0); | |||||
walk(50,50,-15*91,25,0); | |||||
walk(-50,-50,15*91,25,0); | |||||
walk(-50,-50,15*91,25,0); | |||||
walk(50,-50,15*91,25,0); | |||||
walk(50,-50,15*91,25,0); | |||||
walk(-50,50,-15*91,25,0); | |||||
walk(-50,50,-15*91,25,0); | |||||
*/ | |||||
// lean back and wave | |||||
target_position.position.x=-40; | |||||
move_to(¤t_position,&target_position,25); | |||||
sleep(1); | |||||
target_position.leg[0].position.x=180; | |||||
target_position.leg[0].position.y=150; | |||||
target_position.leg[0].position.z=-120; | |||||
target_position.leg[3].position.x=180; | |||||
target_position.leg[3].position.y=-150; | |||||
target_position.leg[3].position.z=-120; | |||||
move_to(¤t_position,&target_position,50); | |||||
for(i=0;i<3;i++) { | |||||
target_position.leg[0].position.x+=20; | |||||
target_position.leg[0].position.y-=60; | |||||
target_position.leg[3].position.x+=20; | |||||
target_position.leg[3].position.y+=60; | |||||
move_to(¤t_position,&target_position,12); | |||||
target_position.leg[0].position.y+=60; | |||||
target_position.leg[0].position.x-=20; | |||||
target_position.leg[3].position.y-=60; | |||||
target_position.leg[3].position.x-=20; | |||||
move_to(¤t_position,&target_position,12); | |||||
} | |||||
sleep(1); | |||||
memcpy(&target_position,&idle_position,sizeof(struct bot_double)); | |||||
target_position.position.x=-40; | |||||
move_to(¤t_position,&target_position,50); | |||||
target_position.position.x=0; | |||||
move_to(¤t_position,&target_position,25); | |||||
target_position.position.z=100; | |||||
move_to(¤t_position,&target_position,50); | |||||
for(i=0;i<NUM_SERVOS;i++) { servo[i]=0; } | |||||
spi_update_servos(servo); | |||||
} | |||||
int | |||||
get_time() { | |||||
struct timeval t; | |||||
gettimeofday(&t,NULL); | |||||
return (t.tv_sec*1000000+t.tv_usec); | |||||
} |
@@ -0,0 +1,22 @@ | |||||
CC=arm-linux-uclibc-gcc | |||||
STRIP=arm-linux-uclibc-strip | |||||
STRIP=echo | |||||
CFLAGS=-Wall -Os -pipe -mtune=arm9tdmi -march=armv5te -mabi=apcs-gnu -msoft-float -I../liblicks/include | |||||
OBJS=main.o ../liblicks/liblicks.a | |||||
BIN=home | |||||
$(BIN): $(OBJS) | |||||
$(CC) $(OBJS) -o $(BIN) -lm | |||||
$(STRIP) $(BIN) | |||||
../liblicks/liblicks.a: | |||||
make -C ../liblicks/ liblicks.a | |||||
../liblicks/liblicks-fakespi.a: | |||||
make -C ../liblicks/ liblicks-fakespi.a | |||||
clean: | |||||
rm -f *.o *~ $(BIN) | |||||
make -C ../liblicks/ clean |
@@ -0,0 +1,78 @@ | |||||
#include <unistd.h> | |||||
#include <math.h> | |||||
#include <stdio.h> | |||||
#include <fcntl.h> | |||||
#include <termios.h> | |||||
#include <sys/time.h> | |||||
#include "servo.h" | |||||
#include "spi.h" | |||||
#include "ik.h" | |||||
#include "dynamic_sequencer.h" | |||||
void ik_to_servos(bot *); | |||||
int get_time(); | |||||
static bot idle_position = { | |||||
{0,0,0}, // world position | |||||
{0,0,0}, // world orientation | |||||
{0,0,-20}, // body position | |||||
{0,0,0}, // body orientation | |||||
{ // leg positions | |||||
{{ 166, 110, 0},}, // leg 0 | |||||
{{ 0, 160, 0},}, // leg 1 | |||||
{{-166, 110, 0},}, // ... | |||||
{{-166,-110, 0},}, | |||||
{{ 0,-160, 0},}, | |||||
{{ 166,-110, 0},} | |||||
} | |||||
}; | |||||
int | |||||
main(int argc, char **argv) { | |||||
struct termios t; | |||||
int flags_stdio; | |||||
vector3d startup_vector={0,0,-100}; | |||||
vector3d v; | |||||
sequencer_walk_parameters wp; | |||||
int quit=0; | |||||
int frame=0; | |||||
int t_frame_start, t_frame_end; | |||||
char c; | |||||
int rotmove; | |||||
load_calibration("/etc/calibration.bin"); | |||||
spi_open(0,33000000); | |||||
ik(&idle_position); | |||||
ik_to_servos(&idle_position); | |||||
spi_close(); | |||||
return 0; | |||||
} | |||||
void | |||||
ik_to_servos(bot *b) { | |||||
int i,j; | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
for(j=0;j<3;j++) { | |||||
if(!isnan(b->leg[i].ik_angle[j])) { | |||||
servo_pwm[i*3+j]=b->leg[i].ik_angle[j]*8.5*1800.0/M_PI+servo_offsets[i*3+j]; | |||||
} | |||||
} | |||||
} | |||||
spi_update_servos(); | |||||
} | |||||
@@ -0,0 +1,23 @@ | |||||
CC=arm-linux-uclibc-gcc | |||||
STRIP=arm-linux-uclibc-strip | |||||
STRIP=echo | |||||
CFLAGS=-Wall -Os -pipe -mtune=arm9tdmi -march=armv5te -mabi=apcs-gnu -msoft-float -I../liblicks/include | |||||
OBJS=main.o ../liblicks/liblicks.a | |||||
BIN=ikcontrol | |||||
$(BIN): $(OBJS) | |||||
$(CC) $(OBJS) -o $(BIN) -lm | |||||
$(STRIP) $(BIN) | |||||
../liblicks/liblicks.a: | |||||
make -C ../liblicks/ liblicks.a | |||||
../liblicks/liblicks-fakespi.a: | |||||
make -C ../liblicks/ liblicks-fakespi.a | |||||
clean: | |||||
rm -f *.o *~ $(BIN) | |||||
make -C ../liblicks/ clean |
@@ -0,0 +1,57 @@ | |||||
#include <assert.h> | |||||
#include <stdlib.h> | |||||
#include <stdio.h> | |||||
#include <string.h> | |||||
#include <unistd.h> | |||||
#include <math.h> | |||||
#include "linalg.h" | |||||
#include "licks_message.h" | |||||
licks_message message; | |||||
int | |||||
main(int argc, char **argv) { | |||||
if(argc==1) { | |||||
printf("%s <command> <args...>\n",argv[0]); | |||||
exit(0); | |||||
} | |||||
if(!strcmp(argv[1],"power")) { | |||||
if(argc!=3) { | |||||
printf("%s power {1|0}\n",argv[0]); | |||||
exit(0); | |||||
}; | |||||
message.type=MSG_POWER; | |||||
message.i=atoi(argv[2]); | |||||
} else if(!strcmp(argv[1],"quit")) { | |||||
message.type=MSG_QUIT; | |||||
} else if(!strcmp(argv[1],"move")) { | |||||
if(argc!=6) { | |||||
printf("%s move x y z duration \n",argv[0]); | |||||
exit(0); | |||||
}; | |||||
message.type=MSG_MOVE_BODY; | |||||
message.move_parameters.v.x=atoi(argv[2]); | |||||
message.move_parameters.v.y=atoi(argv[3]); | |||||
message.move_parameters.v.z=atoi(argv[4]); | |||||
message.move_parameters.duration=atoi(argv[5]); | |||||
} else if(!strcmp(argv[1],"walk")) { | |||||
if(argc!=7) { | |||||
printf("%s walk x y a h d\n",argv[0]); | |||||
exit(0); | |||||
}; | |||||
message.type=MSG_WALK; | |||||
message.walk_parameters.step_direction.x=atoi(argv[2]); | |||||
message.walk_parameters.step_direction.y=atoi(argv[3]); | |||||
message.walk_parameters.step_rotation=(M_PI/1800.0)*atoi(argv[4]); | |||||
message.walk_parameters.step_height=atoi(argv[5]); | |||||
message.walk_parameters.step_duration=atoi(argv[6]); | |||||
} | |||||
licks_socket_open("/tmp/ikcontrol"); | |||||
send_message(&message,ikd_path); | |||||
licks_socket_close(); | |||||
return 0; | |||||
} |
@@ -0,0 +1,22 @@ | |||||
#CC=arm-linux-uclibc-gcc | |||||
#STRIP=arm-linux-uclibc-strip | |||||
STRIP=echo | |||||
#CFLAGS=-Wall -Os -pipe -mtune=arm9tdmi -march=armv5te -mabi=apcs-gnu -msoft-float -I../liblicks/include | |||||
CFLAGS=-I../liblicks/include | |||||
OBJS=main.o ../liblicks/liblicks.a | |||||
BIN=ikd | |||||
$(BIN): $(OBJS) | |||||
$(CC) $(OBJS) -o $(BIN) -lm | |||||
$(STRIP) $(BIN) | |||||
../liblicks/liblicks.a: | |||||
make -C ../liblicks/ liblicks.a | |||||
clean: | |||||
rm -f *.o *~ $(BIN) | |||||
make -C ../liblicks/ clean | |||||
@@ -0,0 +1,29 @@ | |||||
LiCKS Messages (to ikd): | |||||
First character is licks_message.type | |||||
H connection handhake, can be used as ping | |||||
P(0|1) servo power off/on | |||||
Bd x y z r p y move body, d=duration of movement in frames, | |||||
(x,y,z) = movement vector, | |||||
(r,p,y) = roll/pitch/yaw rotation vector | |||||
Ld n x y z move leg n | |||||
Gd x y z phi h set gait parameters; d=duration of one step, | |||||
(x,y,z) = step vector, | |||||
phi = step z-rotation, | |||||
h = step height | |||||
Q(0|1) query off/on | |||||
X exit ikd | |||||
LiCKS Answer Messages (from ikd, will be sent periodically when query mode is on): | |||||
licks_message.type == 'A' | |||||
AH2U2 connection handshake answer | |||||
ABx y z r p y (x,y,z) = body position, (r,p,y) = body rotation | |||||
ALn x y z a1 a2 a3 n = leg number, (x,y,z) = leg endpoint, (a1,a2,a3) = ik angles | |||||
AGd x y z phi h gait parameters, see above | |||||
ASp q status, p = power, q = query mode |
@@ -0,0 +1,73 @@ | |||||
#include <stdlib.h> | |||||
#include <stdio.h> | |||||
#include <string.h> | |||||
#include <sys/types.h> | |||||
#include <sys/socket.h> | |||||
#include <sys/select.h> | |||||
#include <sys/un.h> | |||||
#include <netinet/in.h> | |||||
#include "message.h" | |||||
int unix_socket_fd; | |||||
fd_set select_fd_set; | |||||
struct timeval timeout; | |||||
struct sockaddr_un localaddr; | |||||
struct sockaddr_un remoteaddr; | |||||
socklen_t remoteaddr_len; | |||||
struct licks_message message; | |||||
char *ikd_path="/tmp/ikd"; // might move to a header | |||||
int | |||||
main(int argc, char **argv) { | |||||
int l,i,quit; | |||||
unix_socket_fd=socket(PF_LOCAL,SOCK_DGRAM,0); | |||||
if(unix_socket_fd==-1) { | |||||
perror("socket"); | |||||
exit(0); | |||||
} | |||||
printf("socket %d\n",unix_socket_fd); | |||||
// localaddr.sun_len=strlen(ikd_path); | |||||
localaddr.sun_family=AF_LOCAL; | |||||
strcpy(localaddr.sun_path,ikd_path); | |||||
unlink(ikd_path); | |||||
if(bind(unix_socket_fd,(struct sockaddr *)&localaddr,sizeof(struct sockaddr_un))) { | |||||
perror("bind"); | |||||
exit(0); | |||||
} | |||||
printf("bound\n"); | |||||
quit=0; | |||||
while(!quit) { | |||||
FD_ZERO(&select_fd_set); | |||||
FD_SET(unix_socket_fd,&select_fd_set); | |||||
timeout.tv_sec=1; | |||||
timeout.tv_usec=0; | |||||
if(!select(unix_socket_fd+1,&select_fd_set,NULL,NULL,&timeout)) { | |||||
printf("timeout\n"); | |||||
} else { | |||||
remoteaddr_len=sizeof(struct sockaddr_un); | |||||
l=recvfrom(unix_socket_fd,&message,sizeof(struct licks_message),0,(struct sockaddr *)&remoteaddr,&remoteaddr_len); | |||||
printf("recvfrom: %d\n",l); | |||||
// printf("sun_len: %d\n",remoteaddr.sun_len); | |||||
printf("sun_addr: %s\n",remoteaddr.sun_path); | |||||
printf("message type: %d\n",message.type); | |||||
for(i=0;i<32;i++) { | |||||
if(!(i%8)) { printf("\n"); } | |||||
printf("%02x ",message.char_array[i]); | |||||
} | |||||
printf("\n\nsending reply\n\n"); | |||||
message.type=MSG_REPLY; | |||||
l=sendto(unix_socket_fd,&message,sizeof(struct licks_message),0,(struct sockaddr *)&remoteaddr,sizeof(struct sockaddr_un)); | |||||
} | |||||
} | |||||
close(unix_socket_fd); | |||||
unlink(ikd_path); | |||||
return 0; | |||||
} |
@@ -0,0 +1,232 @@ | |||||
#include <unistd.h> | |||||
#include <math.h> | |||||
#include <stdio.h> | |||||
#include <fcntl.h> | |||||
#include <termios.h> | |||||
#include <string.h> | |||||
#include <stdlib.h> | |||||
#include <sched.h> | |||||
#include <sys/time.h> | |||||
#include <sys/types.h> | |||||
#include <sys/socket.h> | |||||
#include <sys/poll.h> | |||||
#include <sys/un.h> | |||||
#include <sys/resource.h> | |||||
#include "servo.h" | |||||
#include "spi.h" | |||||
#include "ik.h" | |||||
#include "dynamic_sequencer.h" | |||||
#include "licks_message.h" | |||||
struct sched_param sched_p; | |||||
struct timespec timeout; | |||||
static licks_message message; | |||||
void ik_to_servos(bot *); | |||||
long get_time(); | |||||
static bot bot_position = { | |||||
{0,0,0}, // world position | |||||
{0,0,0}, // world orientation | |||||
{0,0,-20}, // body position | |||||
{0,0,0}, // body orientation | |||||
{ // leg positions | |||||
{{ 166, 110, 0},}, // leg 0 | |||||
{{ 0, 160, 0},}, // leg 1 | |||||
{{-166, 110, 0},}, // ... | |||||
{{-166,-110, 0},}, | |||||
{{ 0,-160, 0},}, | |||||
{{ 166,-110, 0},} | |||||
} | |||||
}; | |||||
int | |||||
main(int argc, char **argv) { | |||||
sequencer_walk_parameters wp; | |||||
vector3d move_vector, rotate_vector; | |||||
char *endptr; | |||||
int i,l,d; | |||||
int power=0; | |||||
int quit=0; | |||||
int frame=0; | |||||
int query=0; | |||||
long t_frame_start, t_frame; | |||||
char *sender; | |||||
licks_socket_open(); | |||||
load_calibration("/etc/calibration.bin"); | |||||
spi_open(0,15000000); | |||||
#ifdef LINUX | |||||
setpriority(PRIO_PROCESS,0,-99); | |||||
sched_p.sched_priority=99; | |||||
if(sched_setscheduler(0,SCHED_FIFO,&sched_p)==-1) { | |||||
perror("sched_setscheduler"); | |||||
} | |||||
#endif | |||||
sequencer_init(); | |||||
wp.step_direction.x=0; | |||||
wp.step_direction.y=0; | |||||
wp.step_direction.z=0; | |||||
wp.step_rotation=0; | |||||
wp.step_duration=25; | |||||
wp.step_height=20; | |||||
sequencer_walk(&wp); | |||||
while(!quit) { | |||||
t_frame_start=get_time(); | |||||
sequencer_run_frame(&bot_position); | |||||
ik(&bot_position); | |||||
if(power) { | |||||
ik_to_servos(&bot_position); | |||||
} else { | |||||
for(i=0;i<NUM_SERVOS;i++) servo_pwm[i]=0; | |||||
spi_update_servos(); | |||||
} | |||||
t_frame=get_time()-t_frame_start; | |||||
while(licks_socket_poll()>0) { | |||||
sender=receive_message(&message); | |||||
switch(message.type) { | |||||
case MSG_HELO: | |||||
printf("HELO received\n"); | |||||
message.type='A'; | |||||
sprintf(message.parameters,"AH2U2"); | |||||
send_reply(&message); | |||||
break; | |||||
case MSG_QUIT: | |||||
quit=1; | |||||
break; | |||||
case MSG_POWER: | |||||
if(message.parameters[0]=='1') power=1; else power=0; | |||||
break; | |||||
case MSG_QUERY: | |||||
printf("query\n"); | |||||
if(message.parameters[0]=='1') query=1; else query=0; | |||||
break; | |||||
case MSG_BODY: | |||||
d=strtol(&(message.parameters[0]),&endptr,0); | |||||
move_vector.x=strtod(endptr+1,&endptr); | |||||
move_vector.y=strtod(endptr+1,&endptr); | |||||
move_vector.z=strtod(endptr+1,&endptr); | |||||
rotate_vector.x=strtod(endptr+1,&endptr); | |||||
rotate_vector.y=strtod(endptr+1,&endptr); | |||||
rotate_vector.z=strtod(endptr+1,&endptr); | |||||
sequencer_move_body(0,d,&move_vector); | |||||
sequencer_rotate_body(0,d,&rotate_vector); | |||||
break; | |||||
case MSG_LEG: | |||||
d=strtol(&(message.parameters[0]),&endptr,0); | |||||
l=strtol(endptr+1,&endptr,0); | |||||
move_vector.x=strtod(endptr+1,&endptr); | |||||
move_vector.y=strtod(endptr+1,&endptr); | |||||
move_vector.z=strtod(endptr+1,&endptr); | |||||
sequencer_move_leg(0,d,l,&move_vector); | |||||
break; | |||||
case MSG_GAIT: | |||||
printf("gait\n"); | |||||
wp.step_duration=strtol(message.parameters,&endptr,0); | |||||
wp.step_direction.x=strtod(endptr+1,&endptr); | |||||
wp.step_direction.y=strtod(endptr+1,&endptr); | |||||
wp.step_direction.z=strtod(endptr+1,&endptr); | |||||
wp.step_rotation=strtod(endptr+1,&endptr); | |||||
wp.step_height=strtol(endptr+1,&endptr,0); | |||||
break; | |||||
} | |||||
} | |||||
if(query&&((frame%10)==0)) { | |||||
message.type='A'; | |||||
snprintf(message.parameters,255, | |||||
"B%4.2f %4.2f %4.2f %2.3f %2.3f %2.3f", | |||||
bot_position.body_position.x, | |||||
bot_position.body_position.y, | |||||
bot_position.body_position.z, | |||||
bot_position.body_orientation.x, | |||||
bot_position.body_orientation.y, | |||||
bot_position.body_orientation.z); | |||||
send_reply(&message); | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
snprintf(message.parameters,255, | |||||
"L%d %4.2f %4.2f %4.2f %2.4f %2.4f %2.4f", i, | |||||
bot_position.leg[i].position.x, | |||||
bot_position.leg[i].position.y, | |||||
bot_position.leg[i].position.z, | |||||
bot_position.leg[i].ik_angle[0], | |||||
bot_position.leg[i].ik_angle[1], | |||||
bot_position.leg[i].ik_angle[2] | |||||
); | |||||
send_reply(&message); | |||||
} | |||||
snprintf(message.parameters,255, | |||||
"G%d %4.2f %4.2f %4.2f %2.4f %4.2f", | |||||
wp.step_duration, | |||||
wp.step_direction.x, | |||||
wp.step_direction.y, | |||||
wp.step_direction.z, | |||||
wp.step_rotation, | |||||
wp.step_height | |||||
); | |||||
send_reply(&message); | |||||
} | |||||
t_frame=get_time()-t_frame_start; | |||||
timeout.tv_sec=0; | |||||
timeout.tv_nsec=1000*(14000-t_frame); | |||||
nanosleep(&timeout,NULL); | |||||
while((t_frame=get_time()-t_frame_start)<20000); | |||||
// if(t_frame>21000) printf("slack: %d\n",t_frame); | |||||
frame++; | |||||
} | |||||
spi_close(); | |||||
licks_socket_close(); | |||||
return 0; | |||||
} | |||||
void | |||||
ik_to_servos(bot *b) { | |||||
int i,j; | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
for(j=0;j<3;j++) { | |||||
if(!isnan(b->leg[i].ik_angle[j])) { | |||||
servo_pwm[i*3+j]=b->leg[i].ik_angle[j]*8.5*1800.0/M_PI+servo_offsets[i*3+j]; | |||||
} | |||||
} | |||||
} | |||||
spi_update_servos(); | |||||
} | |||||
long | |||||
get_time() { | |||||
struct timeval t; | |||||
gettimeofday(&t,NULL); | |||||
return (t.tv_sec*1000000+t.tv_usec); | |||||
} | |||||
@@ -0,0 +1,15 @@ | |||||
#ifndef LICK_MESSAGE_H | |||||
#define LICKS_MESSAGE_H | |||||
#define MSG_REPLY 1 | |||||
#define MSG_CHAR_ARRAY 2 | |||||
struct licks_message { | |||||
int type; | |||||
union { | |||||
char char_array[32]; | |||||
}; | |||||
}; | |||||
#endif |
@@ -0,0 +1,79 @@ | |||||
#include <stdlib.h> | |||||
#include <stdio.h> | |||||
#include <string.h> | |||||
#include <unistd.h> | |||||
#include <sys/types.h> | |||||
#include <sys/socket.h> | |||||
#include <sys/un.h> | |||||
#include <netinet/in.h> | |||||
#include "message.h" | |||||
int unix_socket_fd; | |||||
struct licks_message message; | |||||
struct sockaddr_un localaddr; | |||||
struct sockaddr_un remoteaddr; | |||||
socklen_t remoteaddr_len; | |||||
char *ikd_path="/tmp/ikd"; | |||||
int | |||||
main(int argc, char **argv) { | |||||
int l,i; | |||||
// create socket | |||||
unix_socket_fd=socket(PF_LOCAL,SOCK_DGRAM,0); | |||||
if(unix_socket_fd==-1) { | |||||
perror("socket"); | |||||
exit(0); | |||||
} | |||||
printf("socket %d\n",unix_socket_fd); | |||||
// bind to socket, localaddr is the pid | |||||
sprintf(localaddr.sun_path,"/tmp/client%d",getpid()); | |||||
localaddr.sun_family=AF_LOCAL; | |||||
// localaddr.sun_len=strlen(localaddr.sun_path)+1; | |||||
if(bind(unix_socket_fd,(struct sockaddr *)&localaddr,sizeof(struct sockaddr_un))) { | |||||
perror("bind"); | |||||
exit(0); | |||||
} | |||||
printf("bound\n"); | |||||
message.type=MSG_CHAR_ARRAY; | |||||
for(i=0;i<32;i++) { | |||||
message.char_array[i]=i; | |||||
} | |||||
remoteaddr.sun_family=AF_LOCAL; | |||||
// remoteaddr.sun_len=strlen(ikd_path); | |||||
strcpy(remoteaddr.sun_path,ikd_path); | |||||
l=sendto(unix_socket_fd,&message,sizeof(message),0,(struct sockaddr *)&remoteaddr,sizeof(struct sockaddr_un)); | |||||
printf("sendto: %d\n",l); | |||||
if(l==-1) { | |||||
perror("sendto"); | |||||
} | |||||
remoteaddr_len=sizeof(struct sockaddr_un); | |||||
l=recvfrom(unix_socket_fd,&message,sizeof(struct licks_message),0,(struct sockaddr *)&remoteaddr,&remoteaddr_len); | |||||
printf("recvfrom: %d\n",l); | |||||
// printf("sun_len: %d\n",remoteaddr.sun_len); | |||||
printf("sun_addr: %s\n",remoteaddr.sun_path); | |||||
printf("message type: %d\n",message.type); | |||||
for(i=0;i<32;i++) { | |||||
if(!(i%8)) { printf("\n"); } | |||||
printf("%02x ",message.char_array[i]); | |||||
} | |||||
printf("\n"); | |||||
close(unix_socket_fd); | |||||
unlink(localaddr.sun_path); | |||||
return 0; | |||||
} |
@@ -0,0 +1,23 @@ | |||||
CC=arm-linux-uclibc-gcc | |||||
STRIP=arm-linux-uclibc-strip | |||||
STRIP=echo | |||||
CFLAGS=-Wall -O3 -I../liblicks/include | |||||
OBJS=main.o ../liblicks/liblicks.a | |||||
BIN=iktest | |||||
$(BIN): $(OBJS) | |||||
$(CC) $(OBJS) -o $(BIN) -lm | |||||
$(STRIP) $(BIN) | |||||
../liblicks/liblicks.a: | |||||
make -C ../liblicks/ liblicks.a | |||||
../liblicks/liblicks-fakespi.a: | |||||
make -C ../liblicks/ liblicks-fakespi.a | |||||
clean: | |||||
rm -f *.o *~ $(BIN) | |||||
make -C ../liblicks/ clean |
@@ -0,0 +1,65 @@ | |||||
#include <stdint.h> | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <math.h> | |||||
#include <sys/time.h> | |||||
#include "ik.h" | |||||
#include "servo.h" | |||||
#include "spi.h" | |||||
int get_time(); | |||||
static bot idle_position = { | |||||
{0,0,-130}, // body position | |||||
{0,0,0}, // body rotation | |||||
{ // leg positions | |||||
{{ 166, 110, 0},}, // leg 0 | |||||
{{ 0, 160, 0},}, // leg 1 | |||||
{{-166, 110, 0},}, // ... | |||||
{{-166,-110, 0},}, | |||||
{{ 0,-160, 0},}, | |||||
{{ 166,-110, 0},} | |||||
} | |||||
}; | |||||
int | |||||
main(int argc, char **argv) { | |||||
int i,j; | |||||
int start_time; | |||||
int end_time; | |||||
spi_open(0,0); | |||||
ik(&idle_position); | |||||
for(i=0;i<24;i++) servo_pwm[i]=0; | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
printf("leg %d\n",i); | |||||
for(j=0;j<3;j++) { | |||||
printf(" a[%d]=%.3f (%.3f deg)\n",j,idle_position.leg[i].ik_angle[j],idle_position.leg[i].ik_angle[j]*180/M_PI); | |||||
if(!isnan(idle_position.leg[i].ik_angle[j])) { | |||||
getchar(); | |||||
servo_pwm[i*3+j]=(idle_position.leg[i].ik_angle[j]*8.5*1800/M_PI)+servo_offsets[i*3+j]; | |||||
spi_update_servos(); | |||||
} | |||||
} | |||||
} | |||||
printf("benchmarking..."); | |||||
start_time=get_time(); | |||||
for(i=0;i<1000;i++) { | |||||
ik(&idle_position); | |||||
} | |||||
end_time=get_time(); | |||||
printf(" %d\n",end_time-start_time); | |||||
spi_close(); | |||||
} | |||||
int | |||||
get_time() { | |||||
struct timeval t; | |||||
gettimeofday(&t,NULL); | |||||
return (t.tv_sec*1000000+t.tv_usec); | |||||
} |
@@ -0,0 +1,4 @@ | |||||
jscontrol: jscontrol.c | |||||
gcc jscontrol.c -o jscontrol -I ../liblicks/include/ | |||||
@@ -0,0 +1,182 @@ | |||||
#include <stdio.h> | |||||
#include <fcntl.h> | |||||
#include <sys/types.h> | |||||
#include <sys/stat.h> | |||||
#include <linux/joystick.h> | |||||
#include <netinet/in.h> | |||||
#include "licks_message.h" | |||||
int joystick_fd = -1; | |||||
struct js_event event; | |||||
char *jsdev="/dev/input/js0"; | |||||
int udp_socket_fd; | |||||
struct sockaddr_in localaddr; | |||||
struct sockaddr_in remoteaddr; | |||||
licks_net_message m; | |||||
#define MODE_IDLE 0 | |||||
#define MODE_TRANSLATE 1 | |||||
#define MODE_ROTATE 2 | |||||
#define MODE_WALK 3 | |||||
int | |||||
main(int argc, char **argv) { | |||||
int quit=0; | |||||
int power=0; | |||||
int joy_x,joy_y,joy_z,joy_rz; | |||||
int mode; | |||||
if((joystick_fd=open(jsdev,O_RDONLY|O_NONBLOCK))<0) { | |||||
perror("open"); | |||||
exit(0); | |||||
} | |||||
udp_socket_fd=socket(PF_INET,SOCK_DGRAM,0); | |||||
if(udp_socket_fd==-1) { | |||||
perror("socket"); | |||||
exit(0); | |||||
} | |||||
localaddr.sin_family=AF_INET; | |||||
localaddr.sin_port=htons(1337); | |||||
inet_aton("0.0.0.0",&localaddr.sin_addr); | |||||
remoteaddr.sin_family=AF_INET; | |||||
remoteaddr.sin_port=htons(1337); | |||||
inet_aton("192.168.1.43",&remoteaddr.sin_addr); | |||||
if(bind(udp_socket_fd,(struct sockaddr *)&localaddr,sizeof(struct sockaddr_in))) { | |||||
perror("bind"); | |||||
exit(0); | |||||
} | |||||
joy_x=0; joy_y=0; joy_z=0; joy_rz=0; | |||||
mode=MODE_IDLE; | |||||
while(!quit) { | |||||
while(read(joystick_fd,&event,sizeof(struct js_event))==sizeof(struct js_event)) { | |||||
switch(event.type) { | |||||
case JS_EVENT_AXIS: | |||||
switch(event.number) { | |||||
case 0: | |||||
joy_x=event.value; | |||||
break; | |||||
case 1: | |||||
joy_y=event.value; | |||||
break; | |||||
case 2: | |||||
joy_z=event.value; | |||||
break; | |||||
case 3: | |||||
joy_rz=event.value; | |||||
break; | |||||
} | |||||
break; | |||||
case JS_EVENT_BUTTON: | |||||
printf("button %d value %d\n",event.number,event.value); | |||||
if(event.value) { | |||||
switch(event.number) { | |||||
case 6: | |||||
mode=MODE_ROTATE; | |||||
break; | |||||
case 7: | |||||
mode=MODE_TRANSLATE; | |||||
break; | |||||
case 9: | |||||
power=1-power; | |||||
m.type=MSG_POWER; | |||||
m.i=power; | |||||
sendto(udp_socket_fd,&m,sizeof(licks_net_message),0,(struct sockaddr *)&remoteaddr,sizeof(struct sockaddr_in)); | |||||
break; | |||||
default: | |||||
mode=MODE_WALK; | |||||
} | |||||
} else { | |||||
mode=MODE_WALK; | |||||
} | |||||
break; | |||||
} | |||||
} | |||||
switch(mode) { | |||||
case MODE_TRANSLATE: | |||||
m.type=MSG_MOVE_BODY; | |||||
if(abs(joy_y)>5000) { | |||||
m.move_parameters.v.x=-joy_y/100; | |||||
} else { | |||||
m.move_parameters.v.x=0; | |||||
} | |||||
if(abs(joy_x)>5000) { | |||||
m.move_parameters.v.y=-joy_x/100; | |||||
} else { | |||||
m.move_parameters.v.y=0; | |||||
} | |||||
if(abs(joy_z)>5000) { | |||||
m.move_parameters.v.z=joy_z/100; | |||||
} else { | |||||
m.move_parameters.v.z=0; | |||||
} | |||||
m.move_parameters.duration=1; | |||||
sendto(udp_socket_fd,&m,sizeof(licks_net_message),0,(struct sockaddr *)&remoteaddr,sizeof(struct sockaddr_in)); | |||||
break; | |||||
case MODE_ROTATE: | |||||
m.type=MSG_ROTATE_BODY; | |||||
if(abs(joy_x)>5000) { | |||||
m.move_parameters.v.x=-joy_x/100; | |||||
} else { | |||||
m.move_parameters.v.x=0; | |||||
} | |||||
if(abs(joy_y)>5000) { | |||||
m.move_parameters.v.y=joy_y/100; | |||||
} else { | |||||
m.move_parameters.v.y=0; | |||||
} | |||||
if(abs(joy_rz)>5000) { | |||||
m.move_parameters.v.z=-joy_rz/100; | |||||
} else { | |||||
m.move_parameters.v.z=0; | |||||
} | |||||
m.move_parameters.duration=1; | |||||
sendto(udp_socket_fd,&m,sizeof(licks_net_message),0,(struct sockaddr *)&remoteaddr,sizeof(struct sockaddr_in)); | |||||
break; | |||||
case MODE_WALK: | |||||
m.type=MSG_WALK; | |||||
if(abs(joy_y)>5000) { | |||||
m.move_parameters.v.x=-joy_y/2; | |||||
} else { | |||||
m.move_parameters.v.x=0; | |||||
} | |||||
if(abs(joy_x)>5000) { | |||||
m.move_parameters.v.y=-joy_x/2; | |||||
} else { | |||||
m.move_parameters.v.y=0; | |||||
} | |||||
if(abs(joy_rz)>5000) { | |||||
m.move_parameters.v.z=joy_rz/327.6; | |||||
} else { | |||||
m.move_parameters.v.z=0; | |||||
} | |||||
sendto(udp_socket_fd,&m,sizeof(licks_net_message),0,(struct sockaddr *)&remoteaddr,sizeof(struct sockaddr_in)); | |||||
break; | |||||
} | |||||
usleep(10000); | |||||
} | |||||
close(udp_socket_fd); | |||||
close(joystick_fd); | |||||
} |
@@ -0,0 +1,26 @@ | |||||
#CC=arm-linux-uclibc-gcc | |||||
#AR=arm-linux-uclibc-ar | |||||
#LD=arm-linux-uclibc-ld | |||||
#CFLAGS=-Iinclude -Wall -Os -pipe -mtune=arm9tdmi -march=armv5te -mabi=apcs-gnu -msoft-float | |||||
CFLAGS=-Iinclude -Wall -pipe | |||||
#OBJS=spi/spi.o servo/servo.o ik/ik.o linalg/linalg.o dynamic_sequencer/dynamic_sequencer.o licks_message/licks_message.o | |||||
OBJS=fakespi/spi.o servo/servo.o ik/ik.o linalg/linalg.o dynamic_sequencer/dynamic_sequencer.o licks_message/licks_message.o | |||||
#FAKEOBJS=servo/servo.o fakespi/spi.o | |||||
all: liblicks.a | |||||
liblicks.a: $(OBJS) | |||||
rm -f liblicks.a | |||||
$(AR) q liblicks.a $(OBJS) | |||||
#liblicks-fakespi.a: $(FAKEOBJS) | |||||
# rm -f liblicks-fakespi.a | |||||
# $(AR) q liblicks-fakespi.a $(FAKEOBJS) | |||||
clean: | |||||
rm -f $(OBJS) $(FAKEOBJS) | |||||
rm -f *~ | |||||
rm -f liblicks.a liblicks-fakespi.a |
@@ -0,0 +1,302 @@ | |||||
#include <stdio.h> | |||||
#include <math.h> | |||||
#include "ik.h" | |||||
#include "dynamic_sequencer.h" | |||||
#define MAX_ENTRIES 100 | |||||
void sequencer_walk_callback(sequencer_entry *, bot *); | |||||
static sequencer_entry sequencer_list[MAX_ENTRIES]; | |||||
void | |||||
sequencer_init() { | |||||
int i; | |||||
for(i=0;i<MAX_ENTRIES;i++) { | |||||
sequencer_list[i].command=seq_nop; | |||||
} | |||||
} | |||||
void | |||||
sequencer_dump() { | |||||
int i; | |||||
for(i=0;i<MAX_ENTRIES;i++) { | |||||
printf("i: %d frame_delay: %d frame_t: %d frame_duration: %d cmd:",i,sequencer_list[i].frame_delay, sequencer_list[i].frame_t, sequencer_list[i].frame_duration); | |||||
switch(sequencer_list[i].command) { | |||||
case seq_nop: printf("nop\n"); break; | |||||
case seq_move_body: printf("move body\n"); break; | |||||
case seq_move_leg: printf("move leg %d %f %f %f\n",sequencer_list[i].arg_int,sequencer_list[i].arg_vector3d.x,sequencer_list[i].arg_vector3d.y,sequencer_list[i].arg_vector3d.z); break; | |||||
} | |||||
} | |||||
} | |||||
void | |||||
sequencer_run_frame(bot *b) { | |||||
int i; | |||||
double t; | |||||
vector3d temp; | |||||
int leg; | |||||
for(i=0;i<MAX_ENTRIES;i++) { | |||||
if(sequencer_list[i].command!=seq_nop) { | |||||
if(sequencer_list[i].frame_delay) { | |||||
sequencer_list[i].frame_delay--; | |||||
} else { | |||||
if(sequencer_list[i].frame_t>sequencer_list[i].frame_duration) sequencer_list[i].command=seq_nop; | |||||
switch(sequencer_list[i].command) { | |||||
case seq_walk: | |||||
sequencer_walk_callback(&sequencer_list[i], b); | |||||
break; | |||||
case seq_move_body: | |||||
add_vector3d(&b->body_position,&sequencer_list[i].arg_vector3d,&b->body_position); | |||||
break; | |||||
case seq_rotate_body: | |||||
add_vector3d(&b->body_orientation,&sequencer_list[i].arg_vector3d,&b->body_orientation); | |||||
break; | |||||
case seq_move_leg: | |||||
add_vector3d(&b->leg[sequencer_list[i].arg_int].position,&sequencer_list[i].arg_vector3d,&b->leg[sequencer_list[i].arg_int].position); | |||||
break; | |||||
case seq_move_leg_parabolic: | |||||
t = (2.0*sequencer_list[i].frame_t/sequencer_list[i].frame_duration)- 1.0; | |||||
t = 1.0 - (t*t); | |||||
scalar_mult_vector3d(&sequencer_list[i].arg_vector3d,t-sequencer_list[i].arg_double,&temp); | |||||
sequencer_list[i].arg_double=t; | |||||
add_vector3d(&b->leg[sequencer_list[i].arg_int].position,&temp,&b->leg[sequencer_list[i].arg_int].position); | |||||
break; | |||||
case seq_rotate_leg: | |||||
if(sequencer_list[i].frame_t==0) { | |||||
rot_x_vector3d(&b->leg[sequencer_list[i].arg_int].position,sequencer_list[i].arg_vector3d.x,&temp); | |||||
rot_y_vector3d(&temp,sequencer_list[i].arg_vector3d.y,&temp); | |||||
rot_z_vector3d(&temp,-sequencer_list[i].arg_vector3d.z,&temp); | |||||
sub_vector3d(&temp,&b->leg[sequencer_list[i].arg_int].position,&temp); | |||||
scalar_mult_vector3d(&temp,1.0/sequencer_list[i].frame_duration,&sequencer_list[i].arg_vector3d); | |||||
printf("x: %f y: %f z: %f\n",temp.x, temp.y, temp.z); | |||||
} | |||||
add_vector3d(&b->leg[sequencer_list[i].arg_int].position,&sequencer_list[i].arg_vector3d,&b->leg[sequencer_list[i].arg_int].position); | |||||
break; | |||||
} | |||||
sequencer_list[i].frame_t++; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
sequencer_entry * | |||||
sequencer_new_entry() { | |||||
int i=0; | |||||
for(i=0;i<MAX_ENTRIES;i++) { | |||||
if(sequencer_list[i].command==seq_nop) { | |||||
sequencer_list[i].frame_t=0; | |||||
return &sequencer_list[i]; | |||||
} | |||||
} | |||||
return 0; | |||||
} | |||||
void | |||||
sequencer_move_body(int frame_delay, int frame_duration, vector3d *d) { | |||||
sequencer_entry *e; | |||||
e=sequencer_new_entry(); | |||||
if(e) { | |||||
e->command=seq_move_body; | |||||
e->frame_delay=frame_delay; | |||||
e->frame_duration=frame_duration; | |||||
scalar_mult_vector3d(d,1.0/frame_duration,&e->arg_vector3d); | |||||
} | |||||
} | |||||
void | |||||
sequencer_rotate_body(int frame_delay, int frame_duration, vector3d *d) { | |||||
sequencer_entry *e; | |||||
e=sequencer_new_entry(); | |||||
if(e) { | |||||
e->command=seq_rotate_body; | |||||
e->frame_delay=frame_delay; | |||||
e->frame_duration=frame_duration; | |||||
scalar_mult_vector3d(d,1.0/frame_duration,&e->arg_vector3d); | |||||
} | |||||
} | |||||
void | |||||
sequencer_rotate_deg_body(int frame_delay, int frame_duration, vector3d *d) { | |||||
sequencer_entry *e; | |||||
e=sequencer_new_entry(); | |||||
if(e) { | |||||
e->command=seq_rotate_body; | |||||
e->frame_delay=frame_delay; | |||||
e->frame_duration=frame_duration; | |||||
scalar_mult_vector3d(d,(M_PI/180.0)/frame_duration,&e->arg_vector3d); | |||||
} | |||||
} | |||||
void | |||||
sequencer_move_leg(int frame_delay, int frame_duration, int i, vector3d *d) { | |||||
sequencer_entry *e; | |||||
e=sequencer_new_entry(); | |||||
if(e) { | |||||
e->command=seq_move_leg; | |||||
e->frame_delay=frame_delay; | |||||
e->frame_duration=frame_duration; | |||||
e->arg_int=i; | |||||
scalar_mult_vector3d(d,1.0/frame_duration,&e->arg_vector3d); | |||||
} | |||||
} | |||||
void | |||||
sequencer_rotate_leg(int frame_delay, int frame_duration, int i, vector3d *d) { | |||||
sequencer_entry *e; | |||||
e=sequencer_new_entry(); | |||||
if(e) { | |||||
e->command=seq_rotate_leg; | |||||
e->frame_delay=frame_delay; | |||||
e->frame_duration=frame_duration; | |||||
e->arg_int=i; | |||||
e->arg_double=0; | |||||
e->arg_vector3d.x=d->x; | |||||
e->arg_vector3d.y=d->y; | |||||
e->arg_vector3d.z=d->z; | |||||
} | |||||
} | |||||
void | |||||
sequencer_move_leg_parabolic(int frame_delay, int frame_duration, int i, vector3d *d) { | |||||
sequencer_entry *e; | |||||
e=sequencer_new_entry(); | |||||
if(e) { | |||||
e->command=seq_move_leg_parabolic; | |||||
e->frame_delay=frame_delay; | |||||
e->frame_duration=frame_duration; | |||||
e->arg_int=i; | |||||
e->arg_double=0; | |||||
e->arg_vector3d.x=d->x; | |||||
e->arg_vector3d.y=d->y; | |||||
e->arg_vector3d.z=d->z; | |||||
} | |||||
} | |||||
void | |||||
sequencer_walk(sequencer_walk_parameters *p) { | |||||
sequencer_entry *e; | |||||
if(e=sequencer_new_entry()) { | |||||
e->command=seq_walk; | |||||
e->arg_pointer=p; | |||||
e->arg_int=0; | |||||
e->frame_delay=0; | |||||
e->frame_t=0; | |||||
e->frame_duration=1; | |||||
} | |||||
} | |||||
void | |||||
sequencer_walk_callback(sequencer_entry *e, bot *b) { | |||||
sequencer_walk_parameters *p; | |||||
p=e->arg_pointer; | |||||
vector3d v; | |||||
int l; | |||||
e->frame_t=-1; | |||||
e->frame_duration=1; | |||||
e->frame_delay=p->step_duration; | |||||
switch(e->arg_int) { | |||||
case 0: | |||||
if(((p->step_direction.x*p->step_direction.x)+(p->step_direction.y*p->step_direction.y))>=1.0||(abs(p->step_rotation)>0.01)) { | |||||
e->arg_int=1; | |||||
for(l=0;l<NUM_LEGS;l++) { | |||||
if(l&1) { | |||||
rot_z_vector3d(&b->leg[l].position,p->step_rotation,&v); | |||||
add_vector3d(&v,&p->step_direction,&v); | |||||
} else { | |||||
rot_z_vector3d(&b->leg[l].position,-p->step_rotation,&v); | |||||
sub_vector3d(&v,&p->step_direction,&v); | |||||
} | |||||
sub_vector3d(&v,&b->leg[l].position,&v); | |||||
sequencer_move_leg(0,p->step_duration,l,&v); | |||||
if(l&1) { | |||||
v.x=0; | |||||
v.y=0; | |||||
v.z=-p->step_height; | |||||
sequencer_move_leg_parabolic(0,p->step_duration,l,&v); | |||||
} | |||||
} | |||||
} | |||||
break; | |||||
case 1: | |||||
for(l=0;l<NUM_LEGS;l++) { | |||||
if(l&1) { | |||||
sub_vector3d(&b->leg[l].position,&p->last_step_direction,&v); | |||||
rot_z_vector3d(&v,-(p->last_step_rotation+p->step_rotation),&v); | |||||
sub_vector3d(&v,&p->step_direction,&v); | |||||
} else { | |||||
add_vector3d(&b->leg[l].position,&p->last_step_direction,&v); | |||||
rot_z_vector3d(&v,(p->last_step_rotation+p->step_rotation),&v); | |||||
add_vector3d(&v,&p->step_direction,&v); | |||||
} | |||||
sub_vector3d(&v,&b->leg[l].position,&v); | |||||
sequencer_move_leg(0,p->step_duration,l,&v); | |||||
if(!(l&1)) { | |||||
v.x=0; | |||||
v.y=0; | |||||
v.z=-p->step_height; | |||||
sequencer_move_leg_parabolic(0,p->step_duration,l,&v); | |||||
} | |||||
} | |||||
if(((p->step_direction.x*p->step_direction.x)+(p->step_direction.y*p->step_direction.y))>=1.0||(abs(p->step_rotation)>0.01)) { | |||||
e->arg_int=2; | |||||
} else { | |||||
e->arg_int=0; | |||||
} | |||||
break; | |||||
case 2: | |||||
for(l=0;l<NUM_LEGS;l++) { | |||||
if(l&1) { | |||||
add_vector3d(&b->leg[l].position,&p->last_step_direction,&v); | |||||
rot_z_vector3d(&v,(p->last_step_rotation+p->step_rotation),&v); | |||||
add_vector3d(&v,&p->step_direction,&v); | |||||
} else { | |||||
sub_vector3d(&b->leg[l].position,&p->last_step_direction,&v); | |||||
rot_z_vector3d(&v,-(p->step_rotation+p->last_step_rotation),&v); | |||||
sub_vector3d(&v,&p->step_direction,&v); | |||||
} | |||||
sub_vector3d(&v,&b->leg[l].position,&v); | |||||
sequencer_move_leg(0,p->step_duration,l,&v); | |||||
if(l&1) { | |||||
v.x=0; | |||||
v.y=0; | |||||
v.z=-p->step_height; | |||||
sequencer_move_leg_parabolic(0,p->step_duration,l,&v); | |||||
} | |||||
} | |||||
if((((p->step_direction.x*p->step_direction.x)+(p->step_direction.y*p->step_direction.y))>=1.0)||(abs(p->step_rotation)>0.01)) { | |||||
e->arg_int=1; | |||||
} else { | |||||
e->arg_int=0; | |||||
} | |||||
break; | |||||
} | |||||
copy_vector3d(&p->step_direction,&p->last_step_direction); | |||||
p->last_step_rotation=p->step_rotation; | |||||
} |
@@ -0,0 +1,36 @@ | |||||
#include <unistd.h> | |||||
#include <stdlib.h> | |||||
#include <stdint.h> | |||||
#include <stdio.h> | |||||
#include <string.h> | |||||
#include <fcntl.h> | |||||
#include "spi.h" | |||||
#include "servo.h" | |||||
void | |||||
spi_open(uint8_t mode, uint32_t speed) { | |||||
} | |||||
void | |||||
spi_close() { | |||||
} | |||||
void | |||||
spi_update_servos() { | |||||
int fd; | |||||
fd=open("/tmp/servodata",O_WRONLY|O_CREAT,0700); | |||||
if(fd!=-1) { | |||||
write(fd,servo_pwm,sizeof(servo_pwm)); | |||||
close(fd); | |||||
} | |||||
} | |||||
void | |||||
spi_set_led(uint8_t led) { | |||||
} | |||||
void | |||||
spi_set_laser(uint8_t led) { | |||||
} | |||||
@@ -0,0 +1,62 @@ | |||||
#include <math.h> | |||||
#include "ik.h" | |||||
bot_configuration conf = { | |||||
{ | |||||
{ 80, 40, 0}, | |||||
{ 0, 60, 0}, | |||||
{-80, 40, 0}, | |||||
{-80,-40, 0}, | |||||
{ 0,-60, 0}, | |||||
{ 80,-40, 0} | |||||
} | |||||
}; | |||||
void | |||||
ik(bot *b) { | |||||
int i; | |||||
vector3d v; | |||||
double r; | |||||
double r2z2,sr2z2; | |||||
double acos_1,acos_2; | |||||
const double c=20; | |||||
const double f=80; | |||||
const double t=130; | |||||
const double f2=f*f; | |||||
const double t2=t*t; | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
sub_vector3d(&b->leg[i].position,&b->body_position,&v); | |||||
rot_x_vector3d(&v,b->body_orientation.x,&v); | |||||
rot_y_vector3d(&v,b->body_orientation.y,&v); | |||||
rot_z_vector3d(&v,b->body_orientation.z,&v); | |||||
sub_vector3d(&v,&conf.leg_offset[i],&v); | |||||
if(i<NUM_LEGS/2) { | |||||
b->leg[i].ik_angle[0]=-atan2(v.x,v.y); | |||||
} else { | |||||
b->leg[i].ik_angle[0]=atan2(v.x,-v.y); | |||||
} | |||||
r=sqrt(v.x*v.x+v.y*v.y)-c; | |||||
r2z2=r*r+v.z*v.z; | |||||
sr2z2=sqrt(r2z2); | |||||
acos_1=(r2z2+f2-t2)/(2*f*sr2z2); | |||||
acos_2=(r2z2-f2-t2)/(2*f*t); | |||||
if(i<NUM_LEGS/2) { | |||||
b->leg[i].ik_angle[1]=M_PI/2 - (acos(acos_1) + atan2(r,v.z)); | |||||
b->leg[i].ik_angle[2]=-acos(acos_2)+M_PI/2; | |||||
} else { | |||||
b->leg[i].ik_angle[1]=-M_PI/2 + (acos(acos_1) + atan2(r,v.z)); | |||||
b->leg[i].ik_angle[2]=acos(acos_2)-M_PI/2; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,62 @@ | |||||
#include <math.h> | |||||
#include "ik.h" | |||||
bot_configuration conf = { | |||||
{ | |||||
{ 80, 40, 0}, | |||||
{ 0, 60, 0}, | |||||
{-80, 40, 0}, | |||||
{-80,-40, 0}, | |||||
{ 0,-60, 0}, | |||||
{ 80,-40, 0} | |||||
} | |||||
}; | |||||
void | |||||
ik(bot *b) { | |||||
int i; | |||||
vector3d v; | |||||
double r; | |||||
double r2z2,sr2z2; | |||||
double acos_1,acos_2; | |||||
const double c=20; | |||||
const double f=80; | |||||
const double t=130; | |||||
const double f2=f*f; | |||||
const double t2=t*t; | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
sub_vector3d(&b->leg[i].position,&b->body_position,&v); | |||||
rot_x_vector3d(&v,b->body_orientation.x,&v); | |||||
rot_y_vector3d(&v,b->body_orientation.y,&v); | |||||
rot_z_vector3d(&v,b->body_orientation.z,&v); | |||||
sub_vector3d(&v,&conf.leg_offset[i],&v); | |||||
if(i<NUM_LEGS/2) { | |||||
b->leg[i].ik_angle[0]=-atan2(v.x,v.y); | |||||
} else { | |||||
b->leg[i].ik_angle[0]=atan2(v.x,-v.y); | |||||
} | |||||
r=sqrt(v.x*v.x+v.y*v.y)-c; | |||||
r2z2=r*r+v.z*v.z; | |||||
sr2z2=sqrt(r2z2); | |||||
acos_1=(r2z2+f2-t2)/(2*f*sr2z2); | |||||
acos_2=(r2z2-f2-t2)/(2*f*t); | |||||
if(i<NUM_LEGS/2) { | |||||
b->leg[i].ik_angle[1]=M_PI/2 - (acos(acos_1) + atan2(r,v.z)); | |||||
b->leg[i].ik_angle[2]=-acos(acos_2)+M_PI/2; | |||||
} else { | |||||
b->leg[i].ik_angle[1]=-M_PI/2 + (acos(acos_1) + atan2(r,v.z)); | |||||
b->leg[i].ik_angle[2]=acos(acos_2)-M_PI/2; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,51 @@ | |||||
#ifndef LICKS_DYNAMIC_SEQUENCER_H | |||||
#define LICKS_DYNAMIC_SEQUENCER_H | |||||
#include <stdint.h> | |||||
#include "linalg.h" | |||||
#include "ik.h" | |||||
typedef enum { seq_nop=0, seq_move_body, seq_rotate_body, seq_move_leg, seq_rotate_leg, seq_move_leg_parabolic, seq_walk } sequencer_command; | |||||
typedef struct { | |||||
sequencer_command command; | |||||
uint32_t frame_delay; | |||||
uint32_t frame_duration; | |||||
uint32_t frame_t; | |||||
vector3d arg_vector3d; | |||||
int arg_int; | |||||
double arg_double; | |||||
void *arg_pointer; | |||||
void *arg_pointer2; | |||||
} sequencer_entry; | |||||
typedef struct { | |||||
double step_height; | |||||
int step_duration; | |||||
vector3d step_direction; | |||||
double step_rotation; | |||||
vector3d last_step_direction; | |||||
double last_step_rotation; | |||||
} sequencer_walk_parameters; | |||||
extern void sequencer_init(); | |||||
extern void sequencer_dump(); | |||||
extern void sequencer_run_frame(bot *b); | |||||
extern sequencer_entry *sequencer_new_entry(); | |||||
extern void sequencer_move_body(int,int,vector3d *); | |||||
extern void sequencer_rotate_body(int,int,vector3d *); | |||||
extern void sequencer_rotate_deg_body(int,int,vector3d *); | |||||
extern void sequencer_move_leg(int,int,int,vector3d *); | |||||
extern void sequencer_rotate_leg(int, int, int, vector3d *); | |||||
extern void sequencer_move_leg_parabolic(int,int,int,vector3d *); | |||||
extern void sequencer_tripod_walk(int,int,vector3d *, double,double, int); | |||||
extern void sequencer_walk(sequencer_walk_parameters *p); | |||||
#endif | |||||
@@ -0,0 +1,30 @@ | |||||
#ifndef LICKS_IK_H | |||||
#define LICKS_IK_H | |||||
#include "linalg.h" | |||||
#define NUM_LEGS 6 | |||||
typedef struct { | |||||
vector3d leg_offset[NUM_LEGS]; | |||||
} bot_configuration; | |||||
typedef struct { | |||||
vector3d position; | |||||
double ik_angle[3]; | |||||
} leg; | |||||
typedef struct { | |||||
vector3d world_position; | |||||
vector3d world_orientation; | |||||
vector3d body_position; | |||||
vector3d body_orientation; | |||||
leg leg[NUM_LEGS]; | |||||
} bot; | |||||
extern void ik(bot *); | |||||
extern bot_configuration conf; | |||||
#endif | |||||
@@ -0,0 +1,27 @@ | |||||
#ifndef LICK_MESSAGE_H | |||||
#define LICKS_MESSAGE_H | |||||
#include "dynamic_sequencer.h" | |||||
#include <sys/types.h> | |||||
#define MSG_QUIT 'X' | |||||
#define MSG_HELO 'H' | |||||
#define MSG_REPLY 'A' | |||||
#define MSG_POWER 'P' | |||||
#define MSG_GAIT 'G' | |||||
#define MSG_BODY 'B' | |||||
#define MSG_LEG 'L' | |||||
#define MSG_QUERY 'Q' | |||||
typedef struct { | |||||
char type; | |||||
char parameters[255]; | |||||
} licks_message; | |||||
extern void licks_socket_open(); | |||||
extern void licks_socket_close(); | |||||
extern int licks_socket_poll(); | |||||
//extern void send_message(licks_message *, char *); | |||||
extern void send_reply(licks_message *); | |||||
extern char *receive_message(licks_message *); | |||||
#endif |
@@ -0,0 +1,25 @@ | |||||
#ifndef LICK_MESSAGE_H | |||||
#define LICKS_MESSAGE_H | |||||
#include "dynamic_sequencer.h" | |||||
#include <sys/types.h> | |||||
#define MSG_QUIT 'X' | |||||
#define MSG_POWER 'P' | |||||
#define MSG_GAIT 'G' | |||||
#define MSG_BODY 'B' | |||||
#define MSG_LEG 'L' | |||||
#define MSG_QUERY 'Q' | |||||
typedef struct { | |||||
char type; | |||||
char parameters[255]; | |||||
} licks_message; | |||||
extern void licks_socket_open(); | |||||
extern void licks_socket_close(); | |||||
extern int licks_socket_poll(); | |||||
//extern void send_message(licks_message *, char *); | |||||
extern void send_reply(licks_message *); | |||||
extern char *receive_message(licks_message *); | |||||
#endif |
@@ -0,0 +1,22 @@ | |||||
#ifndef LICKS_LINALG_H | |||||
#define LICKS_LINALG_H | |||||
typedef struct { | |||||
double x,y,z; | |||||
} vector3d; | |||||
typedef struct { | |||||
double x[3],y[3],z[3]; | |||||
} matrix3x3d; | |||||
extern void copy_vector3d(vector3d *v1, vector3d *v2); | |||||
extern void add_vector3d(vector3d *v1, vector3d *v2, vector3d *result); | |||||
extern void sub_vector3d(vector3d *v1, vector3d *v2, vector3d *result); | |||||
extern void scalar_mult_vector3d(vector3d *v1, double s, vector3d *result); | |||||
extern void cross_mult_vector3d(vector3d *v1, vector3d *v2, vector3d *result); | |||||
extern void matrix_mult_vector3d(vector3d *v1, matrix3x3d *M, vector3d *result); | |||||
extern void rot_x_vector3d(vector3d *v, double a, vector3d *result); | |||||
extern void rot_y_vector3d(vector3d *v, double a, vector3d *result); | |||||
extern void rot_z_vector3d(vector3d *v, double a, vector3d *result); | |||||
#endif |
@@ -0,0 +1,13 @@ | |||||
#ifndef LICKS_SERVO_H | |||||
#define LICKS_SERVO_H | |||||
#include <stdint.h> | |||||
#define NUM_SERVOS 24 | |||||
extern uint32_t servo_pwm[NUM_SERVOS]; // low level PWM values. This block will be sent via SPI | |||||
extern uint32_t servo_offsets[NUM_SERVOS]; // low level calibration | |||||
extern void load_calibration(char *); | |||||
#endif |
@@ -0,0 +1,44 @@ | |||||
#ifndef LICKS_SPI_H | |||||
#define LICKS_SPI_H | |||||
#include <stdint.h> | |||||
#define SPI_IDLE 0x00 | |||||
#define SPI_WAIT 0x01 | |||||
#define SPI_BUSY 0x02 | |||||
#define SPI_DONE 0x03 | |||||
#define SPI_ERR 0x04 | |||||
#define CMD_NOP 0x00 | |||||
#define CMD_CONTINUE 0x01 | |||||
#define CMD_FINISH 0x02 | |||||
#define CMD_CLEAR 0x8A | |||||
#define CMD_SET_SERVOS 0x10 | |||||
#define CMD_SET_LED 0x11 | |||||
#define CMD_SET_LASER 0x12 | |||||
#define CMD_GET_SERVOS 0x20 | |||||
extern void spi_open(uint8_t, uint32_t); | |||||
extern void spi_update_servos(); | |||||
extern void set_led(uint8_t); | |||||
extern void set_laser(uint8_t); | |||||
extern void spi_close(); | |||||
struct spi_message { | |||||
uint8_t cmd; | |||||
uint8_t length; | |||||
uint8_t checksum; | |||||
uint8_t data[255]; | |||||
}; | |||||
struct spi_result { | |||||
uint8_t status; | |||||
uint8_t length; | |||||
uint8_t checksum; | |||||
uint8_t data[255]; | |||||
}; | |||||
#endif |
@@ -0,0 +1,84 @@ | |||||
#include <unistd.h> | |||||
#include <math.h> | |||||
#include <stdio.h> | |||||
#include <fcntl.h> | |||||
#include <termios.h> | |||||
#include <string.h> | |||||
#include <stdlib.h> | |||||
#include <sched.h> | |||||
#include <sys/time.h> | |||||
#include <sys/types.h> | |||||
#include <sys/socket.h> | |||||
#include <sys/poll.h> | |||||
#include <sys/resource.h> | |||||
#include <arpa/inet.h> | |||||
#include <netinet/in.h> | |||||
#include "licks_message.h" | |||||
int socket_fd; | |||||
struct pollfd poll_pollfd; | |||||
struct timespec timeout_ts; | |||||
struct sockaddr_in localaddr; | |||||
struct sockaddr_in remoteaddr; | |||||
socklen_t remoteaddr_len; | |||||
const int port=1337; | |||||
void | |||||
licks_socket_open() { | |||||
socket_fd=socket(PF_INET,SOCK_DGRAM,0); | |||||
if(socket_fd==-1) { | |||||
perror("socket"); | |||||
exit(0); | |||||
} | |||||
printf("socket %d\n",socket_fd); | |||||
localaddr.sin_family=AF_INET; | |||||
localaddr.sin_port=htons(port); | |||||
inet_aton("0.0.0.0",&localaddr.sin_addr); | |||||
if(bind(socket_fd,(struct sockaddr *)&localaddr,sizeof(struct sockaddr_in))) { | |||||
perror("bind"); | |||||
exit(0); | |||||
} | |||||
// printf("bound to %s\n",localaddr.sun_path); | |||||
poll_pollfd.fd=socket_fd; | |||||
poll_pollfd.events=POLLIN; | |||||
remoteaddr.sin_family=AF_INET; | |||||
} | |||||
int | |||||
licks_socket_poll() { | |||||
return poll(&poll_pollfd,1,0); | |||||
} | |||||
void | |||||
licks_socket_close() { | |||||
close(socket_fd); | |||||
} | |||||
//void | |||||
//send_message(licks_message *m, char *to) { | |||||
// strcpy(remoteaddr.sin_path,to); | |||||
// sendto(socket_fd,m,sizeof(licks_message),0,(struct sockaddr *)&remoteaddr,sizeof(struct sockaddr_in)); | |||||
//} | |||||
void | |||||
send_reply(licks_message *m) { | |||||
sendto(socket_fd,m,strlen(m),0,(struct sockaddr *)&remoteaddr,sizeof(struct sockaddr_in)); | |||||
} | |||||
char * | |||||
receive_message(licks_message *m) { | |||||
size_t real_len; | |||||
remoteaddr_len=sizeof(struct sockaddr_in); | |||||
memset(m,0,sizeof(licks_message)); | |||||
real_len=recvfrom(socket_fd,m,sizeof(licks_message)-1,0,(struct sockaddr *)&remoteaddr,&remoteaddr_len); | |||||
return 0; | |||||
} | |||||
@@ -0,0 +1,84 @@ | |||||
#include <unistd.h> | |||||
#include <math.h> | |||||
#include <stdio.h> | |||||
#include <fcntl.h> | |||||
#include <termios.h> | |||||
#include <string.h> | |||||
#include <stdlib.h> | |||||
#include <sched.h> | |||||
#include <sys/time.h> | |||||
#include <sys/types.h> | |||||
#include <sys/socket.h> | |||||
#include <sys/poll.h> | |||||
#include <sys/resource.h> | |||||
#include <arpa/inet.h> | |||||
#include <netinet/in.h> | |||||
#include "licks_message.h" | |||||
int socket_fd; | |||||
struct pollfd poll_pollfd; | |||||
struct timespec timeout_ts; | |||||
struct sockaddr_in localaddr; | |||||
struct sockaddr_in remoteaddr; | |||||
socklen_t remoteaddr_len; | |||||
const int port=1337; | |||||
void | |||||
licks_socket_open() { | |||||
socket_fd=socket(PF_INET,SOCK_DGRAM,0); | |||||
if(socket_fd==-1) { | |||||
perror("socket"); | |||||
exit(0); | |||||
} | |||||
printf("socket %d\n",socket_fd); | |||||
localaddr.sin_family=AF_INET; | |||||
localaddr.sin_port=htons(port); | |||||
inet_aton("0.0.0.0",&localaddr.sin_addr); | |||||
if(bind(socket_fd,(struct sockaddr *)&localaddr,sizeof(struct sockaddr_in))) { | |||||
perror("bind"); | |||||
exit(0); | |||||
} | |||||
// printf("bound to %s\n",localaddr.sun_path); | |||||
poll_pollfd.fd=socket_fd; | |||||
poll_pollfd.events=POLLIN; | |||||
remoteaddr.sin_family=AF_INET; | |||||
} | |||||
int | |||||
licks_socket_poll() { | |||||
return poll(&poll_pollfd,1,0); | |||||
} | |||||
void | |||||
licks_socket_close() { | |||||
close(socket_fd); | |||||
} | |||||
//void | |||||
//send_message(licks_message *m, char *to) { | |||||
// strcpy(remoteaddr.sin_path,to); | |||||
// sendto(socket_fd,m,sizeof(licks_message),0,(struct sockaddr *)&remoteaddr,sizeof(struct sockaddr_in)); | |||||
//} | |||||
void | |||||
send_reply(licks_message *m) { | |||||
sendto(socket_fd,m,strlen(m),0,(struct sockaddr *)&remoteaddr,sizeof(struct sockaddr_in)); | |||||
} | |||||
char * | |||||
receive_message(licks_message *m) { | |||||
size_t real_len; | |||||
remoteaddr_len=sizeof(struct sockaddr_in); | |||||
memset( | |||||
real_len=recvfrom(socket_fd,m,sizeof(licks_message)-1,0,(struct sockaddr *)&remoteaddr,&remoteaddr_len); | |||||
return 0; | |||||
} | |||||
@@ -0,0 +1,76 @@ | |||||
#include <math.h> | |||||
#include "linalg.h" | |||||
void | |||||
copy_vector3d(vector3d *v1, vector3d *v2) { | |||||
v2->x=v1->x; | |||||
v2->y=v1->y; | |||||
v2->z=v1->z; | |||||
} | |||||
void | |||||
add_vector3d(vector3d *v1, vector3d *v2, vector3d *result) { | |||||
result->x = v1->x + v2->x; | |||||
result->y = v1->y + v2->y; | |||||
result->z = v1->z + v2->z; | |||||
} | |||||
void | |||||
sub_vector3d(vector3d *v1, vector3d *v2, vector3d *result) { | |||||
result->x = v1->x - v2->x; | |||||
result->y = v1->y - v2->y; | |||||
result->z = v1->z - v2->z; | |||||
} | |||||
void | |||||
scalar_mult_vector3d(vector3d *v1, double s, vector3d *result) { | |||||
result->x = v1->x * s; | |||||
result->y = v1->y * s; | |||||
result->z = v1->z * s; | |||||
} | |||||
void | |||||
cross_mult_vector3d(vector3d *v1, vector3d *v2, vector3d *result) { | |||||
vector3d t; | |||||
t.x = v1->y * v2->z - v1->z * v2->y; | |||||
t.y = v1->z * v2->x - v1->x * v2->z; | |||||
t.z = v1->x * v2->y - v1->y * v2->z; | |||||
copy_vector3d(&t,result); | |||||
} | |||||
void | |||||
matrix_mult_vector3d(vector3d *v1, matrix3x3d *M, vector3d *result) { | |||||
vector3d t; | |||||
t.x = v1->x * M->x[0] + v1->y * M->y[0] + v1->z * M->z[0]; | |||||
t.y = v1->x * M->x[1] + v1->y * M->y[1] + v1->z * M->z[1]; | |||||
t.z = v1->x * M->x[2] + v1->y * M->y[2] + v1->z * M->z[2]; | |||||
copy_vector3d(&t,result); | |||||
} | |||||
void | |||||
rot_x_vector3d(vector3d *v, double a, vector3d *result) { | |||||
vector3d t; | |||||
t.x = v->x; | |||||
t.y = v->y * cos(a) + v->z * sin(a); | |||||
t.z =-v->y * sin(a) + v->z * cos(a); | |||||
copy_vector3d(&t,result); | |||||
} | |||||
void | |||||
rot_y_vector3d(vector3d *v, double a, vector3d *result) { | |||||
vector3d t; | |||||
t.x = v->x * cos(a) - v->z * sin(a); | |||||
t.y = v->y; | |||||
t.z = v->x * sin(a) + v->z * cos(a); | |||||
copy_vector3d(&t, result); | |||||
} | |||||
void | |||||
rot_z_vector3d(vector3d *v, double a, vector3d *result) { | |||||
vector3d t; | |||||
t.x = v->x * cos(a) + v->y * sin(a); | |||||
t.y =-v->x * sin(a) + v->y * cos(a); | |||||
t.z = v->z; | |||||
copy_vector3d(&t, result); | |||||
} |
@@ -0,0 +1,39 @@ | |||||
#include "servo.h" | |||||
#include <string.h> | |||||
#include <stdio.h> | |||||
#include <fcntl.h> | |||||
#define NUM_SERVOS 24 | |||||
uint32_t servo_pwm[NUM_SERVOS]={}; | |||||
uint32_t servo_offsets[NUM_SERVOS]={ | |||||
0x432b, 0x3311, 0x2a88, | |||||
0x3311, 0x2f77, 0x28b5, | |||||
0x225d, 0x31bd, 0x2bed, | |||||
0x3cf6, 0x322b, 0x3c65, | |||||
0x344b, 0x2d96, 0x2ed1, | |||||
0x279c, 0x2ffa, 0x39df, | |||||
0x0000, 0x0000, 0x0000, | |||||
0x0000, 0x0000, 0x0000, | |||||
}; | |||||
void | |||||
load_calibration(char *filename) { | |||||
unsigned int load_buffer[NUM_SERVOS]; | |||||
int bytes_read; | |||||
int fd; | |||||
fd=open(filename,O_RDONLY); | |||||
if(fd!=-1) { | |||||
bytes_read=read(fd,load_buffer,sizeof(load_buffer)); | |||||
if(bytes_read==sizeof(load_buffer)) { | |||||
memcpy(servo_offsets,load_buffer,sizeof(load_buffer)); | |||||
} else { | |||||
printf("load_calibration(%s): short read\n",filename); | |||||
} | |||||
close(fd); | |||||
} else { | |||||
perror(filename); | |||||
} | |||||
} |
@@ -0,0 +1,132 @@ | |||||
#include <stdlib.h> | |||||
#include <stdint.h> | |||||
#include <string.h> | |||||
#include <sys/types.h> | |||||
#include <fcntl.h> | |||||
#include <sys/stat.h> | |||||
#include <linux/spi/spidev.h> | |||||
#include "spi.h" | |||||
#include "servo.h" | |||||
static struct spi_message spi_message; | |||||
static struct spi_result spi_result; | |||||
static int spi_fd; | |||||
static uint8_t spi_mode; | |||||
static uint32_t spi_speed; | |||||
void | |||||
spi_open(uint8_t mode, uint32_t speed) { | |||||
spi_fd=open("/dev/spidev1.0",O_RDWR); | |||||
if(spi_fd==-1) { | |||||
perror("spidev1.0"); | |||||
exit(20); | |||||
} | |||||
} | |||||
void | |||||
spi_close() { | |||||
close(spi_fd); | |||||
} | |||||
void | |||||
spi_update_servos() { | |||||
int i; | |||||
spi_result.status=SPI_BUSY; // assume busy | |||||
while(spi_result.status) { | |||||
if((spi_result.status==SPI_ERR)||(spi_result.status=SPI_DONE)) { | |||||
spi_message.cmd=CMD_FINISH; | |||||
write(spi_fd,&spi_message,1); | |||||
} else if((spi_result.status==SPI_WAIT)) { | |||||
spi_message.cmd=CMD_CONTINUE; | |||||
write(spi_fd,&spi_message,1); | |||||
} | |||||
read(spi_fd,&spi_result,1); | |||||
} | |||||
spi_message.cmd=CMD_SET_SERVOS; | |||||
spi_message.length=sizeof(servo_pwm); | |||||
memcpy(spi_message.data,servo_pwm,sizeof(servo_pwm)); | |||||
spi_message.checksum=0x00; | |||||
for(i=0;i<spi_message.length;i++) { | |||||
spi_message.checksum^=spi_message.data[i]; | |||||
} | |||||
write(spi_fd,&spi_message,sizeof(spi_message)); | |||||
while(spi_result.status!=SPI_WAIT) read(spi_fd,&spi_result,1); | |||||
spi_message.cmd=CMD_CONTINUE; | |||||
write(spi_fd,&spi_message,1); | |||||
read(spi_fd,&spi_result,1); | |||||
while(spi_result.status==SPI_BUSY) read(spi_fd,&spi_result,1); | |||||
} | |||||
void | |||||
spi_set_led(uint8_t led) { | |||||
int i; | |||||
spi_result.status=SPI_BUSY; // assume busy | |||||
while(spi_result.status) { | |||||
if((spi_result.status==SPI_ERR)||(spi_result.status=SPI_DONE)) { | |||||
spi_message.cmd=CMD_FINISH; | |||||
write(spi_fd,&spi_message,1); | |||||
} else if((spi_result.status==SPI_WAIT)) { | |||||
spi_message.cmd=CMD_CONTINUE; | |||||
write(spi_fd,&spi_message,1); | |||||
} | |||||
read(spi_fd,&spi_result,1); | |||||
} | |||||
spi_message.cmd=CMD_SET_LED; | |||||
spi_message.length=1; | |||||
spi_message.data[0]=led; | |||||
spi_message.checksum=0x00; | |||||
for(i=0;i<spi_message.length;i++) { | |||||
spi_message.checksum^=spi_message.data[i]; | |||||
} | |||||
write(spi_fd,&spi_message,sizeof(spi_message)); | |||||
while(spi_result.status!=SPI_WAIT) read(spi_fd,&spi_result,1); | |||||
spi_message.cmd=CMD_CONTINUE; | |||||
write(spi_fd,&spi_message,1); | |||||
read(spi_fd,&spi_result,1); | |||||
while(spi_result.status==SPI_BUSY) read(spi_fd,&spi_result,1); | |||||
} | |||||
void | |||||
spi_set_laser(uint8_t led) { | |||||
int i; | |||||
spi_result.status=SPI_BUSY; // assume busy | |||||
while(spi_result.status) { | |||||
if((spi_result.status==SPI_ERR)||(spi_result.status=SPI_DONE)) { | |||||
spi_message.cmd=CMD_FINISH; | |||||
write(spi_fd,&spi_message,1); | |||||
} else if((spi_result.status==SPI_WAIT)) { | |||||
spi_message.cmd=CMD_CONTINUE; | |||||
write(spi_fd,&spi_message,1); | |||||
} | |||||
read(spi_fd,&spi_result,1); | |||||
} | |||||
spi_message.cmd=CMD_SET_LASER; | |||||
spi_message.length=1; | |||||
spi_message.data[0]=led; | |||||
spi_message.checksum=0x00; | |||||
for(i=0;i<spi_message.length;i++) { | |||||
spi_message.checksum^=spi_message.data[i]; | |||||
} | |||||
write(spi_fd,&spi_message,sizeof(spi_message)); | |||||
while(spi_result.status!=SPI_WAIT) read(spi_fd,&spi_result,1); | |||||
spi_message.cmd=CMD_CONTINUE; | |||||
write(spi_fd,&spi_message,1); | |||||
read(spi_fd,&spi_result,1); | |||||
while(spi_result.status==SPI_BUSY) read(spi_fd,&spi_result,1); | |||||
} |
@@ -0,0 +1,19 @@ | |||||
CV=/home/wuselfuzz/opencv-dist/usr | |||||
BR=/home/wuselfuzz/buildroot-2009.11 | |||||
CVLIB=$(CV)/lib | |||||
CVINC=$(CV)/include/opencv | |||||
CFLAGS=-I$(CVINC) -msoft-float | |||||
LIBS=-L/home/wuselfuzz/opencv-dist/usr/lib -lhighgui -lcvaux -lcv -lcxcore -lgomp | |||||
#LIBS=$(CVLIB)/libcv.a $(CVLIB)/libhighgui.a $(CVLIB)/libcvaux.a $(CVLIB)/libml.a $(CVLIB)/libcxcore.a -lgomp -lz | |||||
CXX=arm-linux-g++ | |||||
LD=arm-linux-g++ | |||||
main: main.o | |||||
$(LD) -o main main.o $(LIBS) | |||||
main.o: main.cpp | |||||
$(CXX) $(CFLAGS) -c -o main.o main.cpp | |||||
clean: | |||||
rm main.o main *~ | |||||
@@ -0,0 +1,21 @@ | |||||
#include "cv.h" | |||||
#include "highgui.h" | |||||
int main(int argc, char **argv) { | |||||
CvCapture* cap; | |||||
cap=cvCaptureFromCAM(-1); | |||||
IplImage* img=cvQueryFrame(cap); | |||||
IplImage* img_result=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1); | |||||
IplImage* img_result2=cvCreateImage(cvGetSize(img),IPL_DEPTH_16S,1); | |||||
cvCvtColor(img,img_result,CV_RGB2GRAY); | |||||
cvSobel(img_result,img_result2,1,1,3); | |||||
cvSaveImage("cap.png",img); | |||||
cvSaveImage("result.png",img_result2); | |||||
// cvAddWeighted(img_result,2./3.,b,1./3.,0,img_result); | |||||
// cvSobel(img_result,img_result,1,1,3); | |||||
cvReleaseCapture(&cap); | |||||
} |
@@ -0,0 +1,23 @@ | |||||
CC=arm-linux-uclibc-gcc | |||||
STRIP=arm-linux-uclibc-strip | |||||
STRIP=echo | |||||
CFLAGS=-Wall -Os -pipe -mtune=arm9tdmi -march=armv5te -mabi=apcs-gnu -msoft-float -I../liblicks/include | |||||
OBJS=main.o ../liblicks/liblicks.a | |||||
BIN=sequencertest | |||||
$(BIN): $(OBJS) | |||||
$(CC) $(OBJS) -o $(BIN) -lm | |||||
$(STRIP) $(BIN) | |||||
../liblicks/liblicks.a: | |||||
make -C ../liblicks/ liblicks.a | |||||
../liblicks/liblicks-fakespi.a: | |||||
make -C ../liblicks/ liblicks-fakespi.a | |||||
clean: | |||||
rm -f *.o *~ $(BIN) | |||||
make -C ../liblicks/ clean |
@@ -0,0 +1,144 @@ | |||||
#include <unistd.h> | |||||
#include <math.h> | |||||
#include <stdio.h> | |||||
#include <fcntl.h> | |||||
#include <termios.h> | |||||
#include <sys/time.h> | |||||
#include "servo.h" | |||||
#include "spi.h" | |||||
#include "ik.h" | |||||
#include "dynamic_sequencer.h" | |||||
void ik_to_servos(bot *); | |||||
int get_time(); | |||||
static bot idle_position = { | |||||
{0,0,0}, // world position | |||||
{0,0,0}, // world orientation | |||||
{0,0,-30}, // body position | |||||
{0,0,0}, // body orientation | |||||
{ // leg positions | |||||
{{ 166, 110, 0},}, // leg 0 | |||||
{{ 0, 160, 0},}, // leg 1 | |||||
{{-166, 110, 0},}, // ... | |||||
{{-166,-110, 0},}, | |||||
{{ 0,-160, 0},}, | |||||
{{ 166,-110, 0},} | |||||
} | |||||
}; | |||||
int | |||||
main(int argc, char **argv) { | |||||
struct termios t; | |||||
int flags_stdio; | |||||
vector3d startup_vector={0,0,-100}; | |||||
vector3d v; | |||||
sequencer_walk_parameters wp; | |||||
int quit=0; | |||||
int frame=0; | |||||
int t_frame_start, t_frame_end; | |||||
char c; | |||||
load_calibration("/etc/calibration.bin"); | |||||
spi_open(0,33000000); | |||||
tcgetattr(0,&t); | |||||
t.c_lflag&=~(ICANON|ECHO); | |||||
tcsetattr(0,TCSANOW,&t); | |||||
flags_stdio=fcntl(0, F_GETFL,0); | |||||
flags_stdio|=O_NONBLOCK; | |||||
fcntl(0, F_SETFL,flags_stdio); | |||||
sequencer_init(); | |||||
sequencer_move_body(0,100,&startup_vector); | |||||
wp.step_direction.x=0; | |||||
wp.step_direction.y=0; | |||||
wp.step_direction.z=0; | |||||
wp.step_rotation=0; | |||||
wp.step_duration=25; | |||||
wp.step_height=20; | |||||
sequencer_walk(&wp); | |||||
while(!quit) { | |||||
if(read(0,&c,1)==1) { | |||||
switch(c) { | |||||
case 27: | |||||
quit=1; | |||||
break; | |||||
case 'w': wp.step_direction.x+=5; break; | |||||
case 's': wp.step_direction.x-=5; break; | |||||
case 'a': wp.step_direction.y+=5; break; | |||||
case 'd': wp.step_direction.y-=5; break; | |||||
case 'q': wp.step_rotation-=1.0*M_PI/180.0; break; | |||||
case 'e': wp.step_rotation+=1.0*M_PI/180.0; break; | |||||
case 'x': wp.step_direction.x=0; wp.step_direction.y=0; wp.step_rotation=0; break; | |||||
case 'r': v.x=0; v.y=0; v.z=-10; sequencer_move_body(0,10,&v); break; | |||||
case 'f': v.x=0; v.y=0; v.z=10; sequencer_move_body(0,10,&v); break; | |||||
} | |||||
printf("x: %f y: %f h: %f d: %i rot: %f\n",wp.step_direction.x, wp.step_direction.y, wp.step_height, wp.step_duration, wp.step_rotation); | |||||
} | |||||
t_frame_start=get_time(); | |||||
sequencer_run_frame(&idle_position); | |||||
ik(&idle_position); | |||||
t_frame_end=get_time(); | |||||
if(t_frame_end-t_frame_start>20000) { | |||||
printf("frame %d slack %d\n",frame,t_frame_end-t_frame_start); | |||||
} | |||||
while(t_frame_end<t_frame_start+20000) t_frame_end=get_time(); | |||||
ik_to_servos(&idle_position); | |||||
frame++; | |||||
} | |||||
spi_close(); | |||||
flags_stdio=fcntl(0, F_GETFL,0); flags_stdio&=~(O_NONBLOCK); fcntl(0, | |||||
F_SETFL,flags_stdio); | |||||
tcgetattr(0,&t); | |||||
t.c_lflag|=(ICANON|ECHO|ECHOE|ISIG); | |||||
tcsetattr(0,TCSANOW,&t); | |||||
return 0; | |||||
} | |||||
void | |||||
ik_to_servos(bot *b) { | |||||
int i,j; | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
for(j=0;j<3;j++) { | |||||
if(!isnan(b->leg[i].ik_angle[j])) { | |||||
servo_pwm[i*3+j]=b->leg[i].ik_angle[j]*8.5*1800.0/M_PI+servo_offsets[i*3+j]; | |||||
} | |||||
} | |||||
} | |||||
spi_update_servos(); | |||||
} | |||||
int | |||||
get_time() { | |||||
struct timeval t; | |||||
gettimeofday(&t,NULL); | |||||
return (t.tv_sec*1000000+t.tv_usec); | |||||
} |
@@ -0,0 +1,24 @@ | |||||
CC=gcc | |||||
CC=arm-linux-uclibc-gcc | |||||
STRIP=arm-linux-uclibc-strip | |||||
#STRIP=echo | |||||
CFLAGS=-Wall -Os -pipe -mtune=arm9tdmi -march=armv5te -mabi=apcs-gnu -msoft-float -I../liblicks/include | |||||
OBJS=main.o ../liblicks/liblicks.a | |||||
BIN=servooff | |||||
$(BIN): $(OBJS) | |||||
$(CC) $(OBJS) -o $(BIN) -lm | |||||
$(STRIP) $(BIN) | |||||
../liblicks/liblicks.a: | |||||
make -C ../liblicks/ liblicks.a | |||||
../liblicks/liblicks-fakespi.a: | |||||
make -C ../liblicks/ liblicks-fakespi.a | |||||
clean: | |||||
rm -f *.o *~ $(BIN) | |||||
make -C ../liblicks/ clean |
@@ -0,0 +1,11 @@ | |||||
#include <servo.h> | |||||
#include "spi.h" | |||||
int | |||||
main(int argc, char **argv) { | |||||
int i; | |||||
spi_open(0,33000000); | |||||
for(i=0;i<NUM_SERVOS;i++) servo_pwm[i]=0; | |||||
spi_update_servos(); | |||||
spi_close(); | |||||
} |
@@ -0,0 +1,23 @@ | |||||
CC=arm-linux-uclibc-gcc | |||||
STRIP=arm-linux-uclibc-strip | |||||
STRIP=echo | |||||
CFLAGS=-Wall -Os -pipe -mtune=arm9tdmi -march=armv5te -mabi=apcs-gnu -msoft-float -I../liblicks/include | |||||
OBJS=main.o ../liblicks/liblicks.a | |||||
BIN=simple_control | |||||
$(BIN): $(OBJS) | |||||
$(CC) $(OBJS) -o $(BIN) -lm | |||||
$(STRIP) $(BIN) | |||||
../liblicks/liblicks.a: | |||||
make -C ../liblicks/ liblicks.a | |||||
../liblicks/liblicks-fakespi.a: | |||||
make -C ../liblicks/ liblicks-fakespi.a | |||||
clean: | |||||
rm -f *.o *~ $(BIN) | |||||
make -C ../liblicks/ clean |
@@ -0,0 +1,147 @@ | |||||
#include <unistd.h> | |||||
#include <math.h> | |||||
#include <stdio.h> | |||||
#include <fcntl.h> | |||||
#include <termios.h> | |||||
#include <sys/time.h> | |||||
#include "servo.h" | |||||
#include "spi.h" | |||||
#include "ik.h" | |||||
#include "dynamic_sequencer.h" | |||||
void ik_to_servos(bot *); | |||||
int get_time(); | |||||
static bot idle_position = { | |||||
{0,0,0}, // world position | |||||
{0,0,0}, // world orientation | |||||
{0,0,-30}, // body position | |||||
{0,0,0}, // body orientation | |||||
{ // leg positions | |||||
{{ 166, 110, 0},}, // leg 0 | |||||
{{ 0, 160, 0},}, // leg 1 | |||||
{{-166, 110, 0},}, // ... | |||||
{{-166,-110, 0},}, | |||||
{{ 0,-160, 0},}, | |||||
{{ 166,-110, 0},} | |||||
} | |||||
}; | |||||
int | |||||
main(int argc, char **argv) { | |||||
struct termios t; | |||||
int flags_stdio; | |||||
vector3d startup_vector={0,0,-100}; | |||||
vector3d v; | |||||
sequencer_walk_parameters wp; | |||||
int quit=0; | |||||
int frame=0; | |||||
int t_frame_start, t_frame_end; | |||||
char c; | |||||
load_calibration("/etc/calibration.bin"); | |||||
spi_open(0,33000000); | |||||
tcgetattr(0,&t); | |||||
t.c_lflag&=~(ICANON|ECHO); | |||||
tcsetattr(0,TCSANOW,&t); | |||||
flags_stdio=fcntl(0, F_GETFL,0); | |||||
flags_stdio|=O_NONBLOCK; | |||||
fcntl(0, F_SETFL,flags_stdio); | |||||
sequencer_init(); | |||||
sequencer_move_body(0,100,&startup_vector); | |||||
wp.step_direction.x=0; | |||||
wp.step_direction.y=0; | |||||
wp.step_direction.z=0; | |||||
wp.step_rotation=0; | |||||
wp.step_duration=25; | |||||
wp.step_height=30; | |||||
sequencer_walk(&wp); | |||||
while(!quit) { | |||||
if(read(0,&c,1)==1) { | |||||
switch(c) { | |||||
case 27: | |||||
quit=1; | |||||
break; | |||||
case 'w': wp.step_direction.x+=5; break; | |||||
case 's': wp.step_direction.x-=5; break; | |||||
case 'a': wp.step_direction.y+=5; break; | |||||
case 'd': wp.step_direction.y-=5; break; | |||||
case 'q': wp.step_rotation-=1.0*M_PI/180.0; break; | |||||
case 'e': wp.step_rotation+=1.0*M_PI/180.0; break; | |||||
case 'x': wp.step_direction.x=0; wp.step_direction.y=0; wp.step_rotation=0; break; | |||||
case 'r': v.x=0; v.y=0; v.z=-10; sequencer_move_body(0,10,&v); break; | |||||
case 'f': v.x=0; v.y=0; v.z=10; sequencer_move_body(0,10,&v); break; | |||||
} | |||||
// wp.step_height=fmax(10,2*sqrt(wp.step_direction.x*wp.step_direction.x+wp.step_direction.y*wp.step_direction.y)); | |||||
wp.step_duration=fmax(30,2*sqrt(wp.step_direction.x*wp.step_direction.x+wp.step_direction.y*wp.step_direction.y)); | |||||
printf("x: %f y: %f h: %f d: %i rot: %f\n",wp.step_direction.x, wp.step_direction.y, wp.step_height, wp.step_duration, wp.step_rotation); | |||||
} | |||||
sequencer_run_frame(&idle_position); | |||||
t_frame_start=get_time(); | |||||
ik(&idle_position); | |||||
t_frame_end=get_time(); | |||||
printf("t: %d\n",t_frame_end-t_frame_start); | |||||
if(t_frame_end-t_frame_start>20000) { | |||||
printf("frame %d slack %d\n",frame,t_frame_end-t_frame_start); | |||||
} | |||||
while(t_frame_end<t_frame_start+20000) t_frame_end=get_time(); | |||||
ik_to_servos(&idle_position); | |||||
frame++; | |||||
} | |||||
spi_close(); | |||||
flags_stdio=fcntl(0, F_GETFL,0); flags_stdio&=~(O_NONBLOCK); fcntl(0, | |||||
F_SETFL,flags_stdio); | |||||
tcgetattr(0,&t); | |||||
t.c_lflag|=(ICANON|ECHO|ECHOE|ISIG); | |||||
tcsetattr(0,TCSANOW,&t); | |||||
return 0; | |||||
} | |||||
void | |||||
ik_to_servos(bot *b) { | |||||
int i,j; | |||||
for(i=0;i<NUM_LEGS;i++) { | |||||
for(j=0;j<3;j++) { | |||||
if(!isnan(b->leg[i].ik_angle[j])) { | |||||
servo_pwm[i*3+j]=b->leg[i].ik_angle[j]*8.5*1800.0/M_PI+servo_offsets[i*3+j]; | |||||
} | |||||
} | |||||
} | |||||
spi_update_servos(); | |||||
} | |||||
int | |||||
get_time() { | |||||
struct timeval t; | |||||
gettimeofday(&t,NULL); | |||||
return (t.tv_sec*1000000+t.tv_usec); | |||||
} |
@@ -0,0 +1,24 @@ | |||||
CC=arm-linux-uclibc-gcc | |||||
STRIP=arm-linux-uclibc-strip | |||||
STRIP=echo | |||||
CFLAGS=-Wall -Os -pipe -mtune=arm9tdmi -march=armv5te -mabi=apcs-gnu -msoft-float -I../liblicks/include | |||||
CFLAGS="-I../liblicks/include" | |||||
OBJS=main.o ../liblicks/liblicks.a | |||||
BIN=udpproxy | |||||
$(BIN): $(OBJS) | |||||
$(CC) $(OBJS) -o $(BIN) -lm | |||||
$(STRIP) $(BIN) | |||||
../liblicks/liblicks.a: | |||||
make -C ../liblicks/ liblicks.a | |||||
../liblicks/liblicks-fakespi.a: | |||||
make -C ../liblicks/ liblicks-fakespi.a | |||||
clean: | |||||
rm -f *.o *~ $(BIN) | |||||
make -C ../liblicks/ clean |
@@ -0,0 +1,83 @@ | |||||
#include <assert.h> | |||||
#include <stdlib.h> | |||||
#include <stdio.h> | |||||
#include <string.h> | |||||
#include <unistd.h> | |||||
#include <math.h> | |||||
#include <arpa/inet.h> | |||||
#include <sys/socket.h> | |||||
#include <netinet/in.h> | |||||
#include "linalg.h" | |||||
#include "licks_message.h" | |||||
licks_message message; | |||||
licks_net_message net_message; | |||||
int udp_socket_fd; | |||||
struct sockaddr_in localaddr; | |||||
struct sockaddr_in remoteaddr; | |||||
int | |||||
main(int argc, char **argv) { | |||||
int quit=0; | |||||
udp_socket_fd=socket(PF_INET,SOCK_DGRAM,0); | |||||
if(udp_socket_fd==-1) { | |||||
perror("socket"); | |||||
exit(0); | |||||
} | |||||
localaddr.sin_family=AF_INET; | |||||
localaddr.sin_port=htons(1337); | |||||
inet_aton("0.0.0.0",&localaddr.sin_addr);; | |||||
if(bind(udp_socket_fd,(struct sockaddr *)&localaddr,sizeof(struct sockaddr_in))) { | |||||
perror("bind"); | |||||
exit(0); | |||||
} | |||||
licks_socket_open("/tmp/udpproxy"); | |||||
while(!quit) { | |||||
read(udp_socket_fd,&net_message,sizeof(licks_net_message)); | |||||
switch(net_message.type) { | |||||
case MSG_QUIT: | |||||
message.type=MSG_QUIT; | |||||
send_message(&message,ikd_path); | |||||
break; | |||||
case MSG_POWER: | |||||
message.type=MSG_POWER; | |||||
message.i=net_message.i; | |||||
send_message(&message,ikd_path); | |||||
break; | |||||
case MSG_MOVE_BODY: | |||||
message.type=MSG_MOVE_BODY; | |||||
message.move_parameters.v.x=net_message.move_parameters.v.x/1000.0; | |||||
message.move_parameters.v.y=net_message.move_parameters.v.y/1000.0; | |||||
message.move_parameters.v.z=net_message.move_parameters.v.z/1000.0; | |||||
message.move_parameters.duration=net_message.move_parameters.duration; | |||||
send_message(&message,ikd_path); | |||||
break; | |||||
case MSG_WALK: | |||||
message.type=MSG_WALK; | |||||
message.walk_parameters.step_direction.x=net_message.move_parameters.v.x/1000.0; | |||||
message.walk_parameters.step_direction.y=net_message.move_parameters.v.y/1000.0; | |||||
message.walk_parameters.step_rotation=net_message.move_parameters.v.z/1000.0; | |||||
send_message(&message,ikd_path); | |||||
break; | |||||
case MSG_ROTATE_BODY: | |||||
message.type=MSG_ROTATE_BODY; | |||||
message.move_parameters.v.x=net_message.move_parameters.v.x/3276.8; | |||||
message.move_parameters.v.y=net_message.move_parameters.v.y/3276.8; | |||||
message.move_parameters.v.z=net_message.move_parameters.v.z/3276.8; | |||||
message.move_parameters.duration=net_message.move_parameters.duration; | |||||
send_message(&message,ikd_path); | |||||
break; | |||||
} | |||||
} | |||||
licks_socket_close(); | |||||
close(udp_socket_fd); | |||||
return 0; | |||||
} |
@@ -0,0 +1,40 @@ | |||||
PREFIX=mips-elf- | |||||
CC=$(PREFIX)gcc | |||||
AS=$(PREFIX)as | |||||
OBJCOPY=$(PREFIX)objcopy | |||||
CFLAGS=-Os -Wall -msoft-float -fomit-frame-pointer -I../libplasma/include -I../libhex/include -DPLASMA_PWM | |||||
LDFLAGS=-nostdlib -msoft-float -Wl,-Ttext,0x10000008 | |||||
#LIBS=-lm -lgcc -lc | |||||
LIBS=-lgcc | |||||
OBJ=init.o main.o | |||||
all: image | |||||
transfer: image | |||||
./transfer.sh | |||||
image: main.bin loader.bin | |||||
cat loader.bin main.bin > image | |||||
main.bin: main.elf | |||||
$(OBJCOPY) -O binary main.elf main.bin | |||||
loader.bin: create_loader.sh main.elf | |||||
./create_loader.sh | |||||
$(AS) -o loader.o loader.s | |||||
$(OBJCOPY) -O binary loader.o loader.bin | |||||
init.o: init.s | |||||
$(AS) -o init.o init.s | |||||
main.elf: $(OBJ) | |||||
$(CC) $(LDFLAGS) -o main.elf $(OBJ) $(LIBS) | |||||
clean: | |||||
rm -f *.o *.bin | |||||
rm -f *~ | |||||
rm -f main.elf | |||||
rm -f image | |||||
rm -rf ../libhex/src/*.o ../libplasma/src/*.o |
@@ -0,0 +1,19 @@ | |||||
#!/bin/bash | |||||
GP=`mips-elf-nm ./main.elf | grep _gp | grep -v gpio | cut -b 1-8` | |||||
cat > loader.s << EOF | |||||
.text | |||||
.align 2 | |||||
.globl _start | |||||
.ent _start | |||||
_start: | |||||
.frame \$sp,16,\$31 # vars= 16, regs= 0/0, args= 0, gp= 0 | |||||
.mask 0x00000000,0 | |||||
.fmask 0x00000000,0 | |||||
.set noreorder | |||||
.set nomacro | |||||
li \$gp,0x$GP | |||||
.end _start | |||||
EOF |
@@ -0,0 +1,24 @@ | |||||
.text | |||||
.align 2 | |||||
.globl _start | |||||
.ent _start | |||||
_start: | |||||
.frame $sp,16,$31 # vars= 16, regs= 0/0, args= 0, gp= 0 | |||||
.mask 0x00000000,0 | |||||
.fmask 0x00000000,0 | |||||
.set noreorder | |||||
.set nomacro | |||||
nop | |||||
li $sp,0x100fffff | |||||
move $4,$0 | |||||
move $5,$0 | |||||
jal main | |||||
nop | |||||
end: | |||||
j $0 | |||||
nop | |||||
.set macro | |||||
.set reorder | |||||
.end _start |
@@ -0,0 +1,14 @@ | |||||
.text | |||||
.align 2 | |||||
.globl _start | |||||
.ent _start | |||||
_start: | |||||
.frame $sp,16,$31 # vars= 16, regs= 0/0, args= 0, gp= 0 | |||||
.mask 0x00000000,0 | |||||
.fmask 0x00000000,0 | |||||
.set noreorder | |||||
.set nomacro | |||||
li $gp,0x100093a0 | |||||
.end _start |
@@ -0,0 +1,137 @@ | |||||
#define SPI_IDLE 0x00 | |||||
#define SPI_WAIT 0x01 | |||||
#define SPI_BUSY 0x02 | |||||
#define SPI_DONE 0x03 | |||||
#define SPI_ERR 0x04 | |||||
#define CMD_NOP 0x00 | |||||
#define CMD_CONTINUE 0x01 | |||||
#define CMD_FINISH 0x02 | |||||
#define CMD_CLEAR 0x8A | |||||
#define CMD_SET_SERVOS 0x10 | |||||
#define CMD_SET_LED 0x11 | |||||
#define CMD_SET_LASER 0x12 | |||||
#define CMD_GET_SERVOS 0x20 | |||||
struct spi_buffer { | |||||
unsigned int cmd; | |||||
unsigned int length; | |||||
unsigned int checksum; | |||||
unsigned int data[255]; | |||||
}; | |||||
volatile unsigned int *pwm=(unsigned int *)0x40000000; | |||||
volatile struct spi_buffer *spi_buffer=(struct spi_buffer *)0x50000000; | |||||
volatile unsigned int *gpio_set=(unsigned int *)0x20000030; | |||||
volatile unsigned int *gpio_clear=(unsigned int *)0x20000040; | |||||
volatile unsigned int *gpio_in=(unsigned int *)0x20000050; | |||||
volatile unsigned int *counter=(unsigned int *)0x20000060; | |||||
int main() { | |||||
int i,length; | |||||
unsigned char cmd; | |||||
unsigned char checksum; | |||||
unsigned char led=0, pulsing_led=0; | |||||
for(i=0;i<24;i++) pwm[i]=0; | |||||
while(1) { | |||||
if(((*counter)>>17)&0x100) { | |||||
pulsing_led=((*counter)>>18)&0x7f; | |||||
} else { | |||||
pulsing_led=0x7f-(((*counter)>>18)&0xff); | |||||
} | |||||
if(led>((*counter)&0xff)) { *gpio_set=0x01; } else { *gpio_clear=0x01; } | |||||
if(pulsing_led>((*counter)&0xff)) { *gpio_set=0x02; } else { *gpio_clear=0x02; } | |||||
cmd=spi_buffer->cmd; | |||||
switch(cmd) { | |||||
case CMD_FINISH: | |||||
spi_buffer->cmd=SPI_IDLE; | |||||
break; | |||||
case CMD_CLEAR: | |||||
spi_buffer->cmd=SPI_BUSY; | |||||
spi_buffer->length=0x00; | |||||
spi_buffer->checksum=0x00; | |||||
for(i=1;i<2000;i++) { | |||||
spi_buffer->data[i]=0x00; | |||||
} | |||||
for(i=0;i<24;i++) { | |||||
pwm[i]=0; | |||||
} | |||||
spi_buffer->cmd=SPI_IDLE; | |||||
break; | |||||
case CMD_SET_SERVOS: | |||||
spi_buffer->cmd=SPI_WAIT; | |||||
while(spi_buffer->cmd!=CMD_CONTINUE); | |||||
spi_buffer->cmd=SPI_BUSY; | |||||
checksum=0; | |||||
length=spi_buffer->length; | |||||
for(i=0;i<length;i++) { | |||||
checksum^=spi_buffer->data[i]; | |||||
} | |||||
if(checksum != spi_buffer->checksum ) { | |||||
spi_buffer->cmd=SPI_ERR; | |||||
} else { | |||||
for(i=0;i<24;i++) { | |||||
pwm[i]=(spi_buffer->data[4*i+1]<<8)|spi_buffer->data[4*i]; | |||||
} | |||||
spi_buffer->cmd=SPI_DONE; | |||||
} | |||||
break; | |||||
case CMD_SET_LED: | |||||
spi_buffer->cmd=SPI_WAIT; | |||||
while(spi_buffer->cmd!=CMD_CONTINUE); | |||||
spi_buffer->cmd=SPI_BUSY; | |||||
checksum=0; | |||||
length=spi_buffer->length; | |||||
for(i=0;i<length;i++) { | |||||
checksum^=spi_buffer->data[i]; | |||||
} | |||||
if(checksum != spi_buffer->checksum ) { | |||||
spi_buffer->cmd=SPI_ERR; | |||||
} else { | |||||
led=spi_buffer->data[0]; | |||||
spi_buffer->cmd=SPI_DONE; | |||||
} | |||||
case CMD_SET_LASER: | |||||
spi_buffer->cmd=SPI_WAIT; | |||||
while(spi_buffer->cmd!=CMD_CONTINUE); | |||||
spi_buffer->cmd=SPI_BUSY; | |||||
checksum=0; | |||||
length=spi_buffer->length; | |||||
for(i=0;i<length;i++) { | |||||
checksum^=spi_buffer->data[i]; | |||||
} | |||||
if(checksum != spi_buffer->checksum ) { | |||||
spi_buffer->cmd=SPI_ERR; | |||||
} else { | |||||
if(spi_buffer->data[0]) { | |||||
*gpio_set=0x04; | |||||
} else { | |||||
*gpio_clear=0x04; | |||||
} | |||||
spi_buffer->cmd=SPI_DONE; | |||||
} | |||||
/* case CMD_GET_SERVOS: | |||||
spi_buffer->cmd=SPI_BUSY; | |||||
spi_buffer->length=0x00; | |||||
spi_buffer->checksum=0x00; | |||||
for(i=0;i<24;i++) { | |||||
spi_buffer->data[2*i]=pwm[i]; | |||||
spi_buffer->data[2*i+1]=pwm[i]>>8; | |||||
} | |||||
spi_buffer->cmd=SPI_DONE; | |||||
break; | |||||
*/ | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
return 0; | |||||
} | |||||
@@ -0,0 +1,14 @@ | |||||
#!/bin/bash | |||||
SERIAL=/dev/tty.USA19QWfd31P1.1 | |||||
echo -ne "7" > $SERIAL | |||||
sleep 1 | |||||
echo -ne "10000000\r" > $SERIAL | |||||
sleep 1 | |||||
printf "%08x\r" `stat -f %z image` > $SERIAL | |||||
sleep 1 | |||||
cat image > $SERIAL | |||||
sleep 1 | |||||
echo -ne 5 > $SERIAL | |||||
sleep 1 | |||||
echo 10000000 > $SERIAL |
@@ -0,0 +1,16 @@ | |||||
#!/bin/ash | |||||
SERIAL=/dev/ttyS1 | |||||
stty -F /dev/ttyS1 speed 115200 -icanon -isig -iexten -echo -icrnl -imaxbel -ignbrk -brkint -opost -onlcr cs8 -parenb clocal | |||||
echo -ne "7" > $SERIAL | |||||
sleep 1 | |||||
echo -ne "10000000\r" > $SERIAL | |||||
sleep 1 | |||||
printf "%08x\r" `ls -l image | cut -b 38-42` > $SERIAL | |||||
sleep 1 | |||||
cat image > $SERIAL | |||||
sleep 1 | |||||
echo -ne 5 > $SERIAL | |||||
sleep 1 | |||||
echo 10000000 > $SERIAL |
@@ -0,0 +1,61 @@ | |||||
--------------------------------------------------------------------- | |||||
-- TITLE: Arithmetic Logic Unit | |||||
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) | |||||
-- DATE CREATED: 2/8/01 | |||||
-- FILENAME: alu.vhd | |||||
-- PROJECT: Plasma CPU core | |||||
-- COPYRIGHT: Software placed into the public domain by the author. | |||||
-- Software 'as is' without warranty. Author liable for nothing. | |||||
-- DESCRIPTION: | |||||
-- Implements the ALU. | |||||
--------------------------------------------------------------------- | |||||
library ieee; | |||||
use ieee.std_logic_1164.all; | |||||
use work.mlite_pack.all; | |||||
entity alu is | |||||
generic(alu_type : string := "DEFAULT"); | |||||
port(a_in : in std_logic_vector(31 downto 0); | |||||
b_in : in std_logic_vector(31 downto 0); | |||||
alu_function : in alu_function_type; | |||||
c_alu : out std_logic_vector(31 downto 0)); | |||||
end; --alu | |||||
architecture logic of alu is | |||||
signal do_add : std_logic; | |||||
signal sum : std_logic_vector(32 downto 0); | |||||
signal less_than : std_logic; | |||||
begin | |||||
do_add <= '1' when alu_function = ALU_ADD else '0'; | |||||
sum <= bv_adder(a_in, b_in, do_add); | |||||
less_than <= sum(32) when a_in(31) = b_in(31) or alu_function = ALU_LESS_THAN | |||||
else a_in(31); | |||||
GENERIC_ALU: if alu_type = "DEFAULT" generate | |||||
c_alu <= sum(31 downto 0) when alu_function=ALU_ADD or | |||||
alu_function=ALU_SUBTRACT else | |||||
ZERO(31 downto 1) & less_than when alu_function=ALU_LESS_THAN or | |||||
alu_function=ALU_LESS_THAN_SIGNED else | |||||
a_in or b_in when alu_function=ALU_OR else | |||||
a_in and b_in when alu_function=ALU_AND else | |||||
a_in xor b_in when alu_function=ALU_XOR else | |||||
a_in nor b_in when alu_function=ALU_NOR else | |||||
ZERO; | |||||
end generate; | |||||
AREA_OPTIMIZED_ALU: if alu_type/="DEFAULT" generate | |||||
c_alu <= sum(31 downto 0) when alu_function=ALU_ADD or | |||||
alu_function=ALU_SUBTRACT else (others => 'Z'); | |||||
c_alu <= ZERO(31 downto 1) & less_than when alu_function=ALU_LESS_THAN or | |||||
alu_function=ALU_LESS_THAN_SIGNED else | |||||
(others => 'Z'); | |||||
c_alu <= a_in or b_in when alu_function=ALU_OR else (others => 'Z'); | |||||
c_alu <= a_in and b_in when alu_function=ALU_AND else (others => 'Z'); | |||||
c_alu <= a_in xor b_in when alu_function=ALU_XOR else (others => 'Z'); | |||||
c_alu <= a_in nor b_in when alu_function=ALU_NOR else (others => 'Z'); | |||||
c_alu <= ZERO when alu_function=ALU_NOTHING else (others => 'Z'); | |||||
end generate; | |||||
end; --architecture logic | |||||
@@ -0,0 +1,136 @@ | |||||
--------------------------------------------------------------------- | |||||
-- TITLE: Bus Multiplexer / Signal Router | |||||
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) | |||||
-- DATE CREATED: 2/8/01 | |||||
-- FILENAME: bus_mux.vhd | |||||
-- PROJECT: Plasma CPU core | |||||
-- COPYRIGHT: Software placed into the public domain by the author. | |||||
-- Software 'as is' without warranty. Author liable for nothing. | |||||
-- DESCRIPTION: | |||||
-- This entity is the main signal router. | |||||
-- It multiplexes signals from multiple sources to the correct location. | |||||
-- The outputs are as follows: | |||||
-- a_bus : goes to the ALU | |||||
-- b_bus : goes to the ALU | |||||
-- reg_dest_out : goes to the register bank | |||||
-- take_branch : goes to pc_next | |||||
--------------------------------------------------------------------- | |||||
library ieee; | |||||
use ieee.std_logic_1164.all; | |||||
use work.mlite_pack.all; | |||||
entity bus_mux is | |||||
port(imm_in : in std_logic_vector(15 downto 0); | |||||
reg_source : in std_logic_vector(31 downto 0); | |||||
a_mux : in a_source_type; | |||||
a_out : out std_logic_vector(31 downto 0); | |||||
reg_target : in std_logic_vector(31 downto 0); | |||||
b_mux : in b_source_type; | |||||
b_out : out std_logic_vector(31 downto 0); | |||||
c_bus : in std_logic_vector(31 downto 0); | |||||
c_memory : in std_logic_vector(31 downto 0); | |||||
c_pc : in std_logic_vector(31 downto 2); | |||||
c_pc_plus4 : in std_logic_vector(31 downto 2); | |||||
c_mux : in c_source_type; | |||||
reg_dest_out : out std_logic_vector(31 downto 0); | |||||
branch_func : in branch_function_type; | |||||
take_branch : out std_logic); | |||||
end; --entity bus_mux | |||||
architecture logic of bus_mux is | |||||
begin | |||||
--Determine value of a_bus | |||||
amux: process(reg_source, imm_in, a_mux, c_pc) | |||||
begin | |||||
case a_mux is | |||||
when A_FROM_REG_SOURCE => | |||||
a_out <= reg_source; | |||||
when A_FROM_IMM10_6 => | |||||
a_out <= ZERO(31 downto 5) & imm_in(10 downto 6); | |||||
when A_FROM_PC => | |||||
a_out <= c_pc & "00"; | |||||
when others => | |||||
a_out <= c_pc & "00"; | |||||
end case; | |||||
end process; | |||||
--Determine value of b_bus | |||||
bmux: process(reg_target, imm_in, b_mux) | |||||
begin | |||||
case b_mux is | |||||
when B_FROM_REG_TARGET => | |||||
b_out <= reg_target; | |||||
when B_FROM_IMM => | |||||
b_out <= ZERO(31 downto 16) & imm_in; | |||||
when B_FROM_SIGNED_IMM => | |||||
if imm_in(15) = '0' then | |||||
b_out(31 downto 16) <= ZERO(31 downto 16); | |||||
else | |||||
b_out(31 downto 16) <= "1111111111111111"; | |||||
end if; | |||||
b_out(15 downto 0) <= imm_in; | |||||
when B_FROM_IMMX4 => | |||||
if imm_in(15) = '0' then | |||||
b_out(31 downto 18) <= "00000000000000"; | |||||
else | |||||
b_out(31 downto 18) <= "11111111111111"; | |||||
end if; | |||||
b_out(17 downto 0) <= imm_in & "00"; | |||||
when others => | |||||
b_out <= reg_target; | |||||
end case; | |||||
end process; | |||||
--Determine value of c_bus | |||||
cmux: process(c_bus, c_memory, c_pc, c_pc_plus4, imm_in, c_mux) | |||||
begin | |||||
case c_mux is | |||||
when C_FROM_ALU => -- | C_FROM_SHIFT | C_FROM_MULT => | |||||
reg_dest_out <= c_bus; | |||||
when C_FROM_MEMORY => | |||||
reg_dest_out <= c_memory; | |||||
when C_FROM_PC => | |||||
reg_dest_out <= c_pc(31 downto 2) & "00"; | |||||
when C_FROM_PC_PLUS4 => | |||||
reg_dest_out <= c_pc_plus4 & "00"; | |||||
when C_FROM_IMM_SHIFT16 => | |||||
reg_dest_out <= imm_in & ZERO(15 downto 0); | |||||
when others => | |||||
reg_dest_out <= c_bus; | |||||
end case; | |||||
end process; | |||||
--Determine value of take_branch | |||||
pc_mux: process(branch_func, reg_source, reg_target) | |||||
variable is_equal : std_logic; | |||||
begin | |||||
if reg_source = reg_target then | |||||
is_equal := '1'; | |||||
else | |||||
is_equal := '0'; | |||||
end if; | |||||
case branch_func is | |||||
when BRANCH_LTZ => | |||||
take_branch <= reg_source(31); | |||||
when BRANCH_LEZ => | |||||
take_branch <= reg_source(31) or is_equal; | |||||
when BRANCH_EQ => | |||||
take_branch <= is_equal; | |||||
when BRANCH_NE => | |||||
take_branch <= not is_equal; | |||||
when BRANCH_GEZ => | |||||
take_branch <= not reg_source(31); | |||||
when BRANCH_GTZ => | |||||
take_branch <= not reg_source(31) and not is_equal; | |||||
when BRANCH_YES => | |||||
take_branch <= '1'; | |||||
when others => | |||||
take_branch <= '0'; | |||||
end case; | |||||
end process; | |||||
end; --architecture logic |
@@ -0,0 +1,481 @@ | |||||
--------------------------------------------------------------------- | |||||
-- TITLE: Controller / Opcode Decoder | |||||
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) | |||||
-- DATE CREATED: 2/8/01 | |||||
-- FILENAME: control.vhd | |||||
-- PROJECT: Plasma CPU core | |||||
-- COPYRIGHT: Software placed into the public domain by the author. | |||||
-- Software 'as is' without warranty. Author liable for nothing. | |||||
-- NOTE: MIPS(tm) is a registered trademark of MIPS Technologies. | |||||
-- MIPS Technologies does not endorse and is not associated with | |||||
-- this project. | |||||
-- DESCRIPTION: | |||||
-- Controls the CPU by decoding the opcode and generating control | |||||
-- signals to the rest of the CPU. | |||||
-- This entity decodes the MIPS(tm) opcode into a | |||||
-- Very-Long-Word-Instruction. | |||||
-- The 32-bit opcode is converted to a | |||||
-- 6+6+6+16+4+2+4+3+2+2+3+2+4 = 60 bit VLWI opcode. | |||||
-- Based on information found in: | |||||
-- "MIPS RISC Architecture" by Gerry Kane and Joe Heinrich | |||||
-- and "The Designer's Guide to VHDL" by Peter J. Ashenden | |||||
--------------------------------------------------------------------- | |||||
library ieee; | |||||
use ieee.std_logic_1164.all; | |||||
use work.mlite_pack.all; | |||||
entity control is | |||||
port(opcode : in std_logic_vector(31 downto 0); | |||||
intr_signal : in std_logic; | |||||
rs_index : out std_logic_vector(5 downto 0); | |||||
rt_index : out std_logic_vector(5 downto 0); | |||||
rd_index : out std_logic_vector(5 downto 0); | |||||
imm_out : out std_logic_vector(15 downto 0); | |||||
alu_func : out alu_function_type; | |||||
shift_func : out shift_function_type; | |||||
mult_func : out mult_function_type; | |||||
branch_func : out branch_function_type; | |||||
a_source_out : out a_source_type; | |||||
b_source_out : out b_source_type; | |||||
c_source_out : out c_source_type; | |||||
pc_source_out: out pc_source_type; | |||||
mem_source_out:out mem_source_type; | |||||
exception_out: out std_logic); | |||||
end; --entity control | |||||
architecture logic of control is | |||||
begin | |||||
control_proc: process(opcode, intr_signal) | |||||
variable op, func : std_logic_vector(5 downto 0); | |||||
variable rs, rt, rd : std_logic_vector(5 downto 0); | |||||
variable rtx : std_logic_vector(4 downto 0); | |||||
variable imm : std_logic_vector(15 downto 0); | |||||
variable alu_function : alu_function_type; | |||||
variable shift_function : shift_function_type; | |||||
variable mult_function : mult_function_type; | |||||
variable a_source : a_source_type; | |||||
variable b_source : b_source_type; | |||||
variable c_source : c_source_type; | |||||
variable pc_source : pc_source_type; | |||||
variable branch_function: branch_function_type; | |||||
variable mem_source : mem_source_type; | |||||
variable is_syscall : std_logic; | |||||
begin | |||||
alu_function := ALU_NOTHING; | |||||
shift_function := SHIFT_NOTHING; | |||||
mult_function := MULT_NOTHING; | |||||
a_source := A_FROM_REG_SOURCE; | |||||
b_source := B_FROM_REG_TARGET; | |||||
c_source := C_FROM_NULL; | |||||
pc_source := FROM_INC4; | |||||
branch_function := BRANCH_EQ; | |||||
mem_source := MEM_FETCH; | |||||
op := opcode(31 downto 26); | |||||
rs := '0' & opcode(25 downto 21); | |||||
rt := '0' & opcode(20 downto 16); | |||||
rtx := opcode(20 downto 16); | |||||
rd := '0' & opcode(15 downto 11); | |||||
func := opcode(5 downto 0); | |||||
imm := opcode(15 downto 0); | |||||
is_syscall := '0'; | |||||
case op is | |||||
when "000000" => --SPECIAL | |||||
case func is | |||||
when "000000" => --SLL r[rd]=r[rt]<<re; | |||||
a_source := A_FROM_IMM10_6; | |||||
c_source := C_FROM_SHIFT; | |||||
shift_function := SHIFT_LEFT_UNSIGNED; | |||||
when "000010" => --SRL r[rd]=u[rt]>>re; | |||||
a_source := A_FROM_IMM10_6; | |||||
c_source := C_FROM_shift; | |||||
shift_function := SHIFT_RIGHT_UNSIGNED; | |||||
when "000011" => --SRA r[rd]=r[rt]>>re; | |||||
a_source := A_FROM_IMM10_6; | |||||
c_source := C_FROM_SHIFT; | |||||
shift_function := SHIFT_RIGHT_SIGNED; | |||||
when "000100" => --SLLV r[rd]=r[rt]<<r[rs]; | |||||
c_source := C_FROM_SHIFT; | |||||
shift_function := SHIFT_LEFT_UNSIGNED; | |||||
when "000110" => --SRLV r[rd]=u[rt]>>r[rs]; | |||||
c_source := C_FROM_SHIFT; | |||||
shift_function := SHIFT_RIGHT_UNSIGNED; | |||||
when "000111" => --SRAV r[rd]=r[rt]>>r[rs]; | |||||
c_source := C_FROM_SHIFT; | |||||
shift_function := SHIFT_RIGHT_SIGNED; | |||||
when "001000" => --JR s->pc_next=r[rs]; | |||||
pc_source := FROM_BRANCH; | |||||
alu_function := ALU_ADD; | |||||
branch_function := BRANCH_YES; | |||||
when "001001" => --JALR r[rd]=s->pc_next; s->pc_next=r[rs]; | |||||
c_source := C_FROM_PC_PLUS4; | |||||
pc_source := FROM_BRANCH; | |||||
alu_function := ALU_ADD; | |||||
branch_function := BRANCH_YES; | |||||
--when "001010" => --MOVZ if(!r[rt]) r[rd]=r[rs]; /*IV*/ | |||||
--when "001011" => --MOVN if(r[rt]) r[rd]=r[rs]; /*IV*/ | |||||
when "001100" => --SYSCALL | |||||
is_syscall := '1'; | |||||
when "001101" => --BREAK s->wakeup=1; | |||||
is_syscall := '1'; | |||||
--when "001111" => --SYNC s->wakeup=1; | |||||
when "010000" => --MFHI r[rd]=s->hi; | |||||
c_source := C_FROM_MULT; | |||||
mult_function := MULT_READ_HI; | |||||
when "010001" => --FTHI s->hi=r[rs]; | |||||
mult_function := MULT_WRITE_HI; | |||||
when "010010" => --MFLO r[rd]=s->lo; | |||||
c_source := C_FROM_MULT; | |||||
mult_function := MULT_READ_LO; | |||||
when "010011" => --MTLO s->lo=r[rs]; | |||||
mult_function := MULT_WRITE_LO; | |||||
when "011000" => --MULT s->lo=r[rs]*r[rt]; s->hi=0; | |||||
mult_function := MULT_SIGNED_MULT; | |||||
when "011001" => --MULTU s->lo=r[rs]*r[rt]; s->hi=0; | |||||
mult_function := MULT_MULT; | |||||
when "011010" => --DIV s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt]; | |||||
mult_function := MULT_SIGNED_DIVIDE; | |||||
when "011011" => --DIVU s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt]; | |||||
mult_function := MULT_DIVIDE; | |||||
when "100000" => --ADD r[rd]=r[rs]+r[rt]; | |||||
c_source := C_FROM_ALU; | |||||
alu_function := ALU_ADD; | |||||
when "100001" => --ADDU r[rd]=r[rs]+r[rt]; | |||||
c_source := C_FROM_ALU; | |||||
alu_function := ALU_ADD; | |||||
when "100010" => --SUB r[rd]=r[rs]-r[rt]; | |||||
c_source := C_FROM_ALU; | |||||
alu_function := ALU_SUBTRACT; | |||||
when "100011" => --SUBU r[rd]=r[rs]-r[rt]; | |||||
c_source := C_FROM_ALU; | |||||
alu_function := ALU_SUBTRACT; | |||||
when "100100" => --AND r[rd]=r[rs]&r[rt]; | |||||
c_source := C_FROM_ALU; | |||||
alu_function := ALU_AND; | |||||
when "100101" => --OR r[rd]=r[rs]|r[rt]; | |||||
c_source := C_FROM_ALU; | |||||
alu_function := ALU_OR; | |||||
when "100110" => --XOR r[rd]=r[rs]^r[rt]; | |||||
c_source := C_FROM_ALU; | |||||
alu_function := ALU_XOR; | |||||
when "100111" => --NOR r[rd]=~(r[rs]|r[rt]); | |||||
c_source := C_FROM_ALU; | |||||
alu_function := ALU_NOR; | |||||
when "101010" => --SLT r[rd]=r[rs]<r[rt]; | |||||
c_source := C_FROM_ALU; | |||||
alu_function := ALU_LESS_THAN_SIGNED; | |||||
when "101011" => --SLTU r[rd]=u[rs]<u[rt]; | |||||
c_source := C_FROM_ALU; | |||||
alu_function := ALU_LESS_THAN; | |||||
when "101101" => --DADDU r[rd]=r[rs]+u[rt]; | |||||
c_source := C_FROM_ALU; | |||||
alu_function := ALU_ADD; | |||||
--when "110001" => --TGEU | |||||
--when "110010" => --TLT | |||||
--when "110011" => --TLTU | |||||
--when "110100" => --TEQ | |||||
--when "110110" => --TNE | |||||
when others => | |||||
end case; | |||||
when "000001" => --REGIMM | |||||
rt := "000000"; | |||||
rd := "011111"; | |||||
a_source := A_FROM_PC; | |||||
b_source := B_FROM_IMMX4; | |||||
alu_function := ALU_ADD; | |||||
pc_source := FROM_BRANCH; | |||||
branch_function := BRANCH_GTZ; | |||||
--if(test) pc=pc+imm*4 | |||||
case rtx is | |||||
when "10000" => --BLTZAL r[31]=s->pc_next; branch=r[rs]<0; | |||||
c_source := C_FROM_PC_PLUS4; | |||||
branch_function := BRANCH_LTZ; | |||||
when "00000" => --BLTZ branch=r[rs]<0; | |||||
branch_function := BRANCH_LTZ; | |||||
when "10001" => --BGEZAL r[31]=s->pc_next; branch=r[rs]>=0; | |||||
c_source := C_FROM_PC_PLUS4; | |||||
branch_function := BRANCH_GEZ; | |||||
when "00001" => --BGEZ branch=r[rs]>=0; | |||||
branch_function := BRANCH_GEZ; | |||||
--when "10010" => --BLTZALL r[31]=s->pc_next; lbranch=r[rs]<0; | |||||
--when "00010" => --BLTZL lbranch=r[rs]<0; | |||||
--when "10011" => --BGEZALL r[31]=s->pc_next; lbranch=r[rs]>=0; | |||||
--when "00011" => --BGEZL lbranch=r[rs]>=0; | |||||
when others => | |||||
end case; | |||||
when "000011" => --JAL r[31]=s->pc_next; s->pc_next=(s->pc&0xf0000000)|target; | |||||
c_source := C_FROM_PC_PLUS4; | |||||
rd := "011111"; | |||||
pc_source := FROM_OPCODE25_0; | |||||
when "000010" => --J s->pc_next=(s->pc&0xf0000000)|target; | |||||
pc_source := FROM_OPCODE25_0; | |||||
when "000100" => --BEQ branch=r[rs]==r[rt]; | |||||
a_source := A_FROM_PC; | |||||
b_source := B_FROM_IMMX4; | |||||
alu_function := ALU_ADD; | |||||
pc_source := FROM_BRANCH; | |||||
branch_function := BRANCH_EQ; | |||||
when "000101" => --BNE branch=r[rs]!=r[rt]; | |||||
a_source := A_FROM_PC; | |||||
b_source := B_FROM_IMMX4; | |||||
alu_function := ALU_ADD; | |||||
pc_source := FROM_BRANCH; | |||||
branch_function := BRANCH_NE; | |||||
when "000110" => --BLEZ branch=r[rs]<=0; | |||||
a_source := A_FROM_PC; | |||||
b_source := b_FROM_IMMX4; | |||||
alu_function := ALU_ADD; | |||||
pc_source := FROM_BRANCH; | |||||
branch_function := BRANCH_LEZ; | |||||
when "000111" => --BGTZ branch=r[rs]>0; | |||||
a_source := A_FROM_PC; | |||||
b_source := B_FROM_IMMX4; | |||||
alu_function := ALU_ADD; | |||||
pc_source := FROM_BRANCH; | |||||
branch_function := BRANCH_GTZ; | |||||
when "001000" => --ADDI r[rt]=r[rs]+(short)imm; | |||||
b_source := B_FROM_SIGNED_IMM; | |||||
c_source := C_FROM_ALU; | |||||
rd := rt; | |||||
alu_function := ALU_ADD; | |||||
when "001001" => --ADDIU u[rt]=u[rs]+(short)imm; | |||||
b_source := B_FROM_SIGNED_IMM; | |||||
c_source := C_FROM_ALU; | |||||
rd := rt; | |||||
alu_function := ALU_ADD; | |||||
when "001010" => --SLTI r[rt]=r[rs]<(short)imm; | |||||
b_source := B_FROM_SIGNED_IMM; | |||||
c_source := C_FROM_ALU; | |||||
rd := rt; | |||||
alu_function := ALU_LESS_THAN_SIGNED; | |||||
when "001011" => --SLTIU u[rt]=u[rs]<(unsigned long)(short)imm; | |||||
b_source := B_FROM_IMM; | |||||
c_source := C_FROM_ALU; | |||||
rd := rt; | |||||
alu_function := ALU_LESS_THAN; | |||||
when "001100" => --ANDI r[rt]=r[rs]&imm; | |||||
b_source := B_FROM_IMM; | |||||
c_source := C_FROM_ALU; | |||||
rd := rt; | |||||
alu_function := ALU_AND; | |||||
when "001101" => --ORI r[rt]=r[rs]|imm; | |||||
b_source := B_FROM_IMM; | |||||
c_source := C_FROM_ALU; | |||||
rd := rt; | |||||
alu_function := ALU_OR; | |||||
when "001110" => --XORI r[rt]=r[rs]^imm; | |||||
b_source := B_FROM_IMM; | |||||
c_source := C_FROM_ALU; | |||||
rd := rt; | |||||
alu_function := ALU_XOR; | |||||
when "001111" => --LUI r[rt]=(imm<<16); | |||||
c_source := C_FROM_IMM_SHIFT16; | |||||
rd := rt; | |||||
when "010000" => --COP0 | |||||
alu_function := ALU_OR; | |||||
c_source := C_FROM_ALU; | |||||
if opcode(23) = '0' then --move from CP0 | |||||
rs := '1' & opcode(15 downto 11); | |||||
rt := "000000"; | |||||
rd := '0' & opcode(20 downto 16); | |||||
else --move to CP0 | |||||
rs := "000000"; | |||||
rd(5) := '1'; | |||||
pc_source := FROM_BRANCH; --delay possible interrupt | |||||
branch_function := BRANCH_NO; | |||||
end if; | |||||
--when "010001" => --COP1 | |||||
--when "010010" => --COP2 | |||||
--when "010011" => --COP3 | |||||
--when "010100" => --BEQL lbranch=r[rs]==r[rt]; | |||||
--when "010101" => --BNEL lbranch=r[rs]!=r[rt]; | |||||
--when "010110" => --BLEZL lbranch=r[rs]<=0; | |||||
--when "010111" => --BGTZL lbranch=r[rs]>0; | |||||
when "100000" => --LB r[rt]=*(signed char*)ptr; | |||||
a_source := A_FROM_REG_SOURCE; | |||||
b_source := B_FROM_SIGNED_IMM; | |||||
alu_function := ALU_ADD; | |||||
rd := rt; | |||||
c_source := C_FROM_MEMORY; | |||||
mem_source := MEM_READ8S; --address=(short)imm+r[rs]; | |||||
when "100001" => --LH r[rt]=*(signed short*)ptr; | |||||
a_source := A_FROM_REG_SOURCE; | |||||
b_source := B_FROM_SIGNED_IMM; | |||||
alu_function := ALU_ADD; | |||||
rd := rt; | |||||
c_source := C_FROM_MEMORY; | |||||
mem_source := MEM_READ16S; --address=(short)imm+r[rs]; | |||||
when "100010" => --LWL //Not Implemented | |||||
a_source := A_FROM_REG_SOURCE; | |||||
b_source := B_FROM_SIGNED_IMM; | |||||
alu_function := ALU_ADD; | |||||
rd := rt; | |||||
c_source := C_FROM_MEMORY; | |||||
mem_source := MEM_READ32; | |||||
when "100011" => --LW r[rt]=*(long*)ptr; | |||||
a_source := A_FROM_REG_SOURCE; | |||||
b_source := B_FROM_SIGNED_IMM; | |||||
alu_function := ALU_ADD; | |||||
rd := rt; | |||||
c_source := C_FROM_MEMORY; | |||||
mem_source := MEM_READ32; | |||||
when "100100" => --LBU r[rt]=*(unsigned char*)ptr; | |||||
a_source := A_FROM_REG_SOURCE; | |||||
b_source := B_FROM_SIGNED_IMM; | |||||
alu_function := ALU_ADD; | |||||
rd := rt; | |||||
c_source := C_FROM_MEMORY; | |||||
mem_source := MEM_READ8; --address=(short)imm+r[rs]; | |||||
when "100101" => --LHU r[rt]=*(unsigned short*)ptr; | |||||
a_source := A_FROM_REG_SOURCE; | |||||
b_source := B_FROM_SIGNED_IMM; | |||||
alu_function := ALU_ADD; | |||||
rd := rt; | |||||
c_source := C_FROM_MEMORY; | |||||
mem_source := MEM_READ16; --address=(short)imm+r[rs]; | |||||
--when "100110" => --LWR //Not Implemented | |||||
when "101000" => --SB *(char*)ptr=(char)r[rt]; | |||||
a_source := A_FROM_REG_SOURCE; | |||||
b_source := B_FROM_SIGNED_IMM; | |||||
alu_function := ALU_ADD; | |||||
mem_source := MEM_WRITE8; --address=(short)imm+r[rs]; | |||||
when "101001" => --SH *(short*)ptr=(short)r[rt]; | |||||
a_source := A_FROM_REG_SOURCE; | |||||
b_source := B_FROM_SIGNED_IMM; | |||||
alu_function := ALU_ADD; | |||||
mem_source := MEM_WRITE16; | |||||
when "101010" => --SWL //Not Implemented | |||||
a_source := A_FROM_REG_SOURCE; | |||||
b_source := B_FROM_SIGNED_IMM; | |||||
alu_function := ALU_ADD; | |||||
mem_source := MEM_WRITE32; --address=(short)imm+r[rs]; | |||||
when "101011" => --SW *(long*)ptr=r[rt]; | |||||
a_source := A_FROM_REG_SOURCE; | |||||
b_source := B_FROM_SIGNED_IMM; | |||||
alu_function := ALU_ADD; | |||||
mem_source := MEM_WRITE32; --address=(short)imm+r[rs]; | |||||
--when "101110" => --SWR //Not Implemented | |||||
--when "101111" => --CACHE | |||||
--when "110000" => --LL r[rt]=*(long*)ptr; | |||||
--when "110001" => --LWC1 | |||||
--when "110010" => --LWC2 | |||||
--when "110011" => --LWC3 | |||||
--when "110101" => --LDC1 | |||||
--when "110110" => --LDC2 | |||||
--when "110111" => --LDC3 | |||||
--when "111000" => --SC *(long*)ptr=r[rt]; r[rt]=1; | |||||
--when "111001" => --SWC1 | |||||
--when "111010" => --SWC2 | |||||
--when "111011" => --SWC3 | |||||
--when "111101" => --SDC1 | |||||
--when "111110" => --SDC2 | |||||
--when "111111" => --SDC3 | |||||
when others => | |||||
end case; | |||||
if c_source = C_FROM_NULL then | |||||
rd := "000000"; | |||||
end if; | |||||
if intr_signal = '1' or is_syscall = '1' then | |||||
rs := "111111"; --interrupt vector | |||||
rt := "000000"; | |||||
rd := "101110"; --save PC in EPC | |||||
alu_function := ALU_OR; | |||||
shift_function := SHIFT_NOTHING; | |||||
mult_function := MULT_NOTHING; | |||||
branch_function := BRANCH_YES; | |||||
a_source := A_FROM_REG_SOURCE; | |||||
b_source := B_FROM_REG_TARGET; | |||||
c_source := C_FROM_PC; | |||||
pc_source := FROM_LBRANCH; | |||||
mem_source := MEM_FETCH; | |||||
exception_out <= '1'; | |||||
else | |||||
exception_out <= '0'; | |||||
end if; | |||||
rs_index <= rs; | |||||
rt_index <= rt; | |||||
rd_index <= rd; | |||||
imm_out <= imm; | |||||
alu_func <= alu_function; | |||||
shift_func <= shift_function; | |||||
mult_func <= mult_function; | |||||
branch_func <= branch_function; | |||||
a_source_out <= a_source; | |||||
b_source_out <= b_source; | |||||
c_source_out <= c_source; | |||||
pc_source_out <= pc_source; | |||||
mem_source_out <= mem_source; | |||||
end process; | |||||
end; --logic |
@@ -0,0 +1,196 @@ | |||||
--------------------------------------------------------------------- | |||||
-- TITLE: Memory Controller | |||||
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) | |||||
-- DATE CREATED: 1/31/01 | |||||
-- FILENAME: mem_ctrl.vhd | |||||
-- PROJECT: Plasma CPU core | |||||
-- COPYRIGHT: Software placed into the public domain by the author. | |||||
-- Software 'as is' without warranty. Author liable for nothing. | |||||
-- DESCRIPTION: | |||||
-- Memory controller for the Plasma CPU. | |||||
-- Supports Big or Little Endian mode. | |||||
--------------------------------------------------------------------- | |||||
library ieee; | |||||
use ieee.std_logic_1164.all; | |||||
use work.mlite_pack.all; | |||||
entity mem_ctrl is | |||||
port(clk : in std_logic; | |||||
reset_in : in std_logic; | |||||
pause_in : in std_logic; | |||||
nullify_op : in std_logic; | |||||
address_pc : in std_logic_vector(31 downto 2); | |||||
opcode_out : out std_logic_vector(31 downto 0); | |||||
address_in : in std_logic_vector(31 downto 0); | |||||
mem_source : in mem_source_type; | |||||
data_write : in std_logic_vector(31 downto 0); | |||||
data_read : out std_logic_vector(31 downto 0); | |||||
pause_out : out std_logic; | |||||
address_next : out std_logic_vector(31 downto 2); | |||||
byte_we_next : out std_logic_vector(3 downto 0); | |||||
address : out std_logic_vector(31 downto 2); | |||||
byte_we : out std_logic_vector(3 downto 0); | |||||
data_w : out std_logic_vector(31 downto 0); | |||||
data_r : in std_logic_vector(31 downto 0)); | |||||
end; --entity mem_ctrl | |||||
architecture logic of mem_ctrl is | |||||
--"00" = big_endian; "11" = little_endian | |||||
constant ENDIAN_MODE : std_logic_vector(1 downto 0) := "00"; | |||||
signal opcode_reg : std_logic_vector(31 downto 0); | |||||
signal next_opcode_reg : std_logic_vector(31 downto 0); | |||||
signal address_reg : std_logic_vector(31 downto 2); | |||||
signal byte_we_reg : std_logic_vector(3 downto 0); | |||||
signal mem_state_reg : std_logic; | |||||
constant STATE_ADDR : std_logic := '0'; | |||||
constant STATE_ACCESS : std_logic := '1'; | |||||
begin | |||||
mem_proc: process(clk, reset_in, pause_in, nullify_op, | |||||
address_pc, address_in, mem_source, data_write, | |||||
data_r, opcode_reg, next_opcode_reg, mem_state_reg, | |||||
address_reg, byte_we_reg) | |||||
variable address_var : std_logic_vector(31 downto 2); | |||||
variable data_read_var : std_logic_vector(31 downto 0); | |||||
variable data_write_var : std_logic_vector(31 downto 0); | |||||
variable opcode_next : std_logic_vector(31 downto 0); | |||||
variable byte_we_var : std_logic_vector(3 downto 0); | |||||
variable mem_state_next : std_logic; | |||||
variable pause_var : std_logic; | |||||
variable bits : std_logic_vector(1 downto 0); | |||||
begin | |||||
byte_we_var := "0000"; | |||||
pause_var := '0'; | |||||
data_read_var := ZERO; | |||||
data_write_var := ZERO; | |||||
mem_state_next := mem_state_reg; | |||||
opcode_next := opcode_reg; | |||||
case mem_source is | |||||
when MEM_READ32 => | |||||
data_read_var := data_r; | |||||
when MEM_READ16 | MEM_READ16S => | |||||
if address_in(1) = ENDIAN_MODE(1) then | |||||
data_read_var(15 downto 0) := data_r(31 downto 16); | |||||
else | |||||
data_read_var(15 downto 0) := data_r(15 downto 0); | |||||
end if; | |||||
if mem_source = MEM_READ16 or data_read_var(15) = '0' then | |||||
data_read_var(31 downto 16) := ZERO(31 downto 16); | |||||
else | |||||
data_read_var(31 downto 16) := ONES(31 downto 16); | |||||
end if; | |||||
when MEM_READ8 | MEM_READ8S => | |||||
bits := address_in(1 downto 0) xor ENDIAN_MODE; | |||||
case bits is | |||||
when "00" => data_read_var(7 downto 0) := data_r(31 downto 24); | |||||
when "01" => data_read_var(7 downto 0) := data_r(23 downto 16); | |||||
when "10" => data_read_var(7 downto 0) := data_r(15 downto 8); | |||||
when others => data_read_var(7 downto 0) := data_r(7 downto 0); | |||||
end case; | |||||
if mem_source = MEM_READ8 or data_read_var(7) = '0' then | |||||
data_read_var(31 downto 8) := ZERO(31 downto 8); | |||||
else | |||||
data_read_var(31 downto 8) := ONES(31 downto 8); | |||||
end if; | |||||
when MEM_WRITE32 => | |||||
data_write_var := data_write; | |||||
byte_we_var := "1111"; | |||||
when MEM_WRITE16 => | |||||
data_write_var := data_write(15 downto 0) & data_write(15 downto 0); | |||||
if address_in(1) = ENDIAN_MODE(1) then | |||||
byte_we_var := "1100"; | |||||
else | |||||
byte_we_var := "0011"; | |||||
end if; | |||||
when MEM_WRITE8 => | |||||
data_write_var := data_write(7 downto 0) & data_write(7 downto 0) & | |||||
data_write(7 downto 0) & data_write(7 downto 0); | |||||
bits := address_in(1 downto 0) xor ENDIAN_MODE; | |||||
case bits is | |||||
when "00" => | |||||
byte_we_var := "1000"; | |||||
when "01" => | |||||
byte_we_var := "0100"; | |||||
when "10" => | |||||
byte_we_var := "0010"; | |||||
when others => | |||||
byte_we_var := "0001"; | |||||
end case; | |||||
when others => | |||||
end case; | |||||
if mem_source = MEM_FETCH then --opcode fetch | |||||
address_var := address_pc; | |||||
opcode_next := data_r; | |||||
mem_state_next := STATE_ADDR; | |||||
else | |||||
if mem_state_reg = STATE_ADDR then | |||||
if pause_in = '0' then | |||||
address_var := address_in(31 downto 2); | |||||
mem_state_next := STATE_ACCESS; | |||||
pause_var := '1'; | |||||
else | |||||
address_var := address_pc; | |||||
byte_we_var := "0000"; | |||||
end if; | |||||
else --STATE_ACCESS | |||||
if pause_in = '0' then | |||||
address_var := address_pc; | |||||
opcode_next := next_opcode_reg; | |||||
mem_state_next := STATE_ADDR; | |||||
byte_we_var := "0000"; | |||||
else | |||||
address_var := address_in(31 downto 2); | |||||
byte_we_var := "0000"; | |||||
end if; | |||||
end if; | |||||
end if; | |||||
if nullify_op = '1' and pause_in = '0' then | |||||
opcode_next := ZERO; --NOP after beql | |||||
end if; | |||||
if reset_in = '1' then | |||||
mem_state_reg <= STATE_ADDR; | |||||
opcode_reg <= ZERO; | |||||
next_opcode_reg <= ZERO; | |||||
address_reg <= ZERO(31 downto 2); | |||||
byte_we_reg <= "0000"; | |||||
elsif rising_edge(clk) then | |||||
if pause_in = '0' then | |||||
address_reg <= address_var; | |||||
byte_we_reg <= byte_we_var; | |||||
mem_state_reg <= mem_state_next; | |||||
opcode_reg <= opcode_next; | |||||
if mem_state_reg = STATE_ADDR then | |||||
next_opcode_reg <= data_r; | |||||
end if; | |||||
end if; | |||||
end if; | |||||
opcode_out <= opcode_reg; | |||||
data_read <= data_read_var; | |||||
pause_out <= pause_var; | |||||
address_next <= address_var; | |||||
byte_we_next <= byte_we_var; | |||||
address <= address_reg; | |||||
byte_we <= byte_we_reg; | |||||
data_w <= data_write_var; | |||||
end process; --data_proc | |||||
end; --architecture logic |
@@ -0,0 +1,342 @@ | |||||
--------------------------------------------------------------------- | |||||
-- TITLE: Plasma CPU core | |||||
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) | |||||
-- DATE CREATED: 2/15/01 | |||||
-- FILENAME: mlite_cpu.vhd | |||||
-- PROJECT: Plasma CPU core | |||||
-- COPYRIGHT: Software placed into the public domain by the author. | |||||
-- Software 'as is' without warranty. Author liable for nothing. | |||||
-- NOTE: MIPS(tm) and MIPS I(tm) are registered trademarks of MIPS | |||||
-- Technologies. MIPS Technologies does not endorse and is not | |||||
-- associated with this project. | |||||
-- DESCRIPTION: | |||||
-- Top level VHDL document that ties the nine other entities together. | |||||
-- | |||||
-- Executes all MIPS I(tm) opcodes but exceptions and non-aligned | |||||
-- memory accesses. Based on information found in: | |||||
-- "MIPS RISC Architecture" by Gerry Kane and Joe Heinrich | |||||
-- and "The Designer's Guide to VHDL" by Peter J. Ashenden | |||||
-- | |||||
-- The CPU is implemented as a two or three stage pipeline. | |||||
-- An add instruction would take the following steps (see cpu.gif): | |||||
-- Stage #0: | |||||
-- 1. The "pc_next" entity passes the program counter (PC) to the | |||||
-- "mem_ctrl" entity which fetches the opcode from memory. | |||||
-- Stage #1: | |||||
-- 2. The memory returns the opcode. | |||||
-- Stage #2: | |||||
-- 3. "Mem_ctrl" passes the opcode to the "control" entity. | |||||
-- 4. "Control" converts the 32-bit opcode to a 60-bit VLWI opcode | |||||
-- and sends control signals to the other entities. | |||||
-- 5. Based on the rs_index and rt_index control signals, "reg_bank" | |||||
-- sends the 32-bit reg_source and reg_target to "bus_mux". | |||||
-- 6. Based on the a_source and b_source control signals, "bus_mux" | |||||
-- multiplexes reg_source onto a_bus and reg_target onto b_bus. | |||||
-- Stage #3 (part of stage #2 if using two stage pipeline): | |||||
-- 7. Based on the alu_func control signals, "alu" adds the values | |||||
-- from a_bus and b_bus and places the result on c_bus. | |||||
-- 8. Based on the c_source control signals, "bus_bux" multiplexes | |||||
-- c_bus onto reg_dest. | |||||
-- 9. Based on the rd_index control signal, "reg_bank" saves | |||||
-- reg_dest into the correct register. | |||||
-- Stage #3b: | |||||
-- 10. Read or write memory if needed. | |||||
-- | |||||
-- All signals are active high. | |||||
-- Here are the signals for writing a character to address 0xffff | |||||
-- when using a two stage pipeline: | |||||
-- | |||||
-- Program: | |||||
-- addr value opcode | |||||
-- ============================= | |||||
-- 3c: 00000000 nop | |||||
-- 40: 34040041 li $a0,0x41 | |||||
-- 44: 3405ffff li $a1,0xffff | |||||
-- 48: a0a40000 sb $a0,0($a1) | |||||
-- 4c: 00000000 nop | |||||
-- 50: 00000000 nop | |||||
-- | |||||
-- intr_in mem_pause | |||||
-- reset_in byte_we Stages | |||||
-- ns address data_w data_r 40 44 48 4c 50 | |||||
-- 3600 0 0 00000040 00000000 34040041 0 0 1 | |||||
-- 3700 0 0 00000044 00000000 3405FFFF 0 0 2 1 | |||||
-- 3800 0 0 00000048 00000000 A0A40000 0 0 2 1 | |||||
-- 3900 0 0 0000004C 41414141 00000000 0 0 2 1 | |||||
-- 4000 0 0 0000FFFC 41414141 XXXXXX41 1 0 3 2 | |||||
-- 4100 0 0 00000050 00000000 00000000 0 0 1 | |||||
--------------------------------------------------------------------- | |||||
library ieee; | |||||
use work.mlite_pack.all; | |||||
use ieee.std_logic_1164.all; | |||||
use ieee.std_logic_unsigned.all; | |||||
entity mlite_cpu is | |||||
generic(memory_type : string := "XILINX_16X"; --ALTERA_LPM, or DUAL_PORT_ | |||||
mult_type : string := "DEFAULT"; --AREA_OPTIMIZED | |||||
shifter_type : string := "DEFAULT"; --AREA_OPTIMIZED | |||||
alu_type : string := "DEFAULT"; --AREA_OPTIMIZED | |||||
pipeline_stages : natural := 3); --2 or 3 | |||||
port(clk : in std_logic; | |||||
reset_in : in std_logic; | |||||
intr_in : in std_logic; | |||||
address_next : out std_logic_vector(31 downto 2); --for synch ram | |||||
byte_we_next : out std_logic_vector(3 downto 0); | |||||
address : out std_logic_vector(31 downto 2); | |||||
byte_we : out std_logic_vector(3 downto 0); | |||||
data_w : out std_logic_vector(31 downto 0); | |||||
data_r : in std_logic_vector(31 downto 0); | |||||
mem_pause : in std_logic); | |||||
end; --entity mlite_cpu | |||||
architecture logic of mlite_cpu is | |||||
--When using a two stage pipeline "sigD <= sig". | |||||
--When using a three stage pipeline "sigD <= sig when rising_edge(clk)", | |||||
-- so sigD is delayed by one clock cycle. | |||||
signal opcode : std_logic_vector(31 downto 0); | |||||
signal rs_index : std_logic_vector(5 downto 0); | |||||
signal rt_index : std_logic_vector(5 downto 0); | |||||
signal rd_index : std_logic_vector(5 downto 0); | |||||
signal rd_indexD : std_logic_vector(5 downto 0); | |||||
signal reg_source : std_logic_vector(31 downto 0); | |||||
signal reg_target : std_logic_vector(31 downto 0); | |||||
signal reg_dest : std_logic_vector(31 downto 0); | |||||
signal reg_destD : std_logic_vector(31 downto 0); | |||||
signal a_bus : std_logic_vector(31 downto 0); | |||||
signal a_busD : std_logic_vector(31 downto 0); | |||||
signal b_bus : std_logic_vector(31 downto 0); | |||||
signal b_busD : std_logic_vector(31 downto 0); | |||||
signal c_bus : std_logic_vector(31 downto 0); | |||||
signal c_alu : std_logic_vector(31 downto 0); | |||||
signal c_shift : std_logic_vector(31 downto 0); | |||||
signal c_mult : std_logic_vector(31 downto 0); | |||||
signal c_memory : std_logic_vector(31 downto 0); | |||||
signal imm : std_logic_vector(15 downto 0); | |||||
signal pc_future : std_logic_vector(31 downto 2); | |||||
signal pc_current : std_logic_vector(31 downto 2); | |||||
signal pc_plus4 : std_logic_vector(31 downto 2); | |||||
signal alu_func : alu_function_type; | |||||
signal alu_funcD : alu_function_type; | |||||
signal shift_func : shift_function_type; | |||||
signal shift_funcD : shift_function_type; | |||||
signal mult_func : mult_function_type; | |||||
signal mult_funcD : mult_function_type; | |||||
signal branch_func : branch_function_type; | |||||
signal take_branch : std_logic; | |||||
signal a_source : a_source_type; | |||||
signal b_source : b_source_type; | |||||
signal c_source : c_source_type; | |||||
signal pc_source : pc_source_type; | |||||
signal mem_source : mem_source_type; | |||||
signal pause_mult : std_logic; | |||||
signal pause_ctrl : std_logic; | |||||
signal pause_pipeline : std_logic; | |||||
signal pause_any : std_logic; | |||||
signal pause_non_ctrl : std_logic; | |||||
signal pause_bank : std_logic; | |||||
signal nullify_op : std_logic; | |||||
signal intr_enable : std_logic; | |||||
signal intr_signal : std_logic; | |||||
signal exception_sig : std_logic; | |||||
signal reset_reg : std_logic_vector(3 downto 0); | |||||
signal reset : std_logic; | |||||
begin --architecture | |||||
pause_any <= (mem_pause or pause_ctrl) or (pause_mult or pause_pipeline); | |||||
pause_non_ctrl <= (mem_pause or pause_mult) or pause_pipeline; | |||||
pause_bank <= (mem_pause or pause_ctrl or pause_mult) and not pause_pipeline; | |||||
nullify_op <= '1' when (pc_source = FROM_LBRANCH and take_branch = '0') | |||||
or intr_signal = '1' or exception_sig = '1' | |||||
else '0'; | |||||
c_bus <= c_alu or c_shift or c_mult; | |||||
reset <= '1' when reset_in = '1' or reset_reg /= "1111" else '0'; | |||||
--synchronize reset and interrupt pins | |||||
intr_proc: process(clk, reset_in, reset_reg, intr_in, intr_enable, | |||||
pc_source, pc_current, pause_any) | |||||
begin | |||||
if reset_in = '1' then | |||||
reset_reg <= "0000"; | |||||
intr_signal <= '0'; | |||||
elsif rising_edge(clk) then | |||||
if reset_reg /= "1111" then | |||||
reset_reg <= reset_reg + 1; | |||||
end if; | |||||
--don't try to interrupt a multi-cycle instruction | |||||
if pause_any = '0' then | |||||
if intr_in = '1' and intr_enable = '1' and | |||||
pc_source = FROM_INC4 then | |||||
--the epc will contain pc+4 | |||||
intr_signal <= '1'; | |||||
else | |||||
intr_signal <= '0'; | |||||
end if; | |||||
end if; | |||||
end if; | |||||
end process; | |||||
u1_pc_next: pc_next PORT MAP ( | |||||
clk => clk, | |||||
reset_in => reset, | |||||
take_branch => take_branch, | |||||
pause_in => pause_any, | |||||
pc_new => c_bus(31 downto 2), | |||||
opcode25_0 => opcode(25 downto 0), | |||||
pc_source => pc_source, | |||||
pc_future => pc_future, | |||||
pc_current => pc_current, | |||||
pc_plus4 => pc_plus4); | |||||
u2_mem_ctrl: mem_ctrl | |||||
PORT MAP ( | |||||
clk => clk, | |||||
reset_in => reset, | |||||
pause_in => pause_non_ctrl, | |||||
nullify_op => nullify_op, | |||||
address_pc => pc_future, | |||||
opcode_out => opcode, | |||||
address_in => c_bus, | |||||
mem_source => mem_source, | |||||
data_write => reg_target, | |||||
data_read => c_memory, | |||||
pause_out => pause_ctrl, | |||||
address_next => address_next, | |||||
byte_we_next => byte_we_next, | |||||
address => address, | |||||
byte_we => byte_we, | |||||
data_w => data_w, | |||||
data_r => data_r); | |||||
u3_control: control PORT MAP ( | |||||
opcode => opcode, | |||||
intr_signal => intr_signal, | |||||
rs_index => rs_index, | |||||
rt_index => rt_index, | |||||
rd_index => rd_index, | |||||
imm_out => imm, | |||||
alu_func => alu_func, | |||||
shift_func => shift_func, | |||||
mult_func => mult_func, | |||||
branch_func => branch_func, | |||||
a_source_out => a_source, | |||||
b_source_out => b_source, | |||||
c_source_out => c_source, | |||||
pc_source_out=> pc_source, | |||||
mem_source_out=> mem_source, | |||||
exception_out=> exception_sig); | |||||
u4_reg_bank: reg_bank | |||||
generic map(memory_type => memory_type) | |||||
port map ( | |||||
clk => clk, | |||||
reset_in => reset, | |||||
pause => pause_bank, | |||||
rs_index => rs_index, | |||||
rt_index => rt_index, | |||||
rd_index => rd_indexD, | |||||
reg_source_out => reg_source, | |||||
reg_target_out => reg_target, | |||||
reg_dest_new => reg_destD, | |||||
intr_enable => intr_enable); | |||||
u5_bus_mux: bus_mux port map ( | |||||
imm_in => imm, | |||||
reg_source => reg_source, | |||||
a_mux => a_source, | |||||
a_out => a_bus, | |||||
reg_target => reg_target, | |||||
b_mux => b_source, | |||||
b_out => b_bus, | |||||
c_bus => c_bus, | |||||
c_memory => c_memory, | |||||
c_pc => pc_current, | |||||
c_pc_plus4 => pc_plus4, | |||||
c_mux => c_source, | |||||
reg_dest_out => reg_dest, | |||||
branch_func => branch_func, | |||||
take_branch => take_branch); | |||||
u6_alu: alu | |||||
generic map (alu_type => alu_type) | |||||
port map ( | |||||
a_in => a_busD, | |||||
b_in => b_busD, | |||||
alu_function => alu_funcD, | |||||
c_alu => c_alu); | |||||
u7_shifter: shifter | |||||
generic map (shifter_type => shifter_type) | |||||
port map ( | |||||
value => b_busD, | |||||
shift_amount => a_busD(4 downto 0), | |||||
shift_func => shift_funcD, | |||||
c_shift => c_shift); | |||||
u8_mult: mult | |||||
generic map (mult_type => mult_type) | |||||
port map ( | |||||
clk => clk, | |||||
reset_in => reset, | |||||
a => a_busD, | |||||
b => b_busD, | |||||
mult_func => mult_funcD, | |||||
c_mult => c_mult, | |||||
pause_out => pause_mult); | |||||
pipeline2: if pipeline_stages <= 2 generate | |||||
a_busD <= a_bus; | |||||
b_busD <= b_bus; | |||||
alu_funcD <= alu_func; | |||||
shift_funcD <= shift_func; | |||||
mult_funcD <= mult_func; | |||||
rd_indexD <= rd_index; | |||||
reg_destD <= reg_dest; | |||||
pause_pipeline <= '0'; | |||||
end generate; --pipeline2 | |||||
pipeline3: if pipeline_stages > 2 generate | |||||
--When operating in three stage pipeline mode, the following signals | |||||
--are delayed by one clock cycle: a_bus, b_bus, alu/shift/mult_func, | |||||
--c_source, and rd_index. | |||||
u9_pipeline: pipeline port map ( | |||||
clk => clk, | |||||
reset => reset, | |||||
a_bus => a_bus, | |||||
a_busD => a_busD, | |||||
b_bus => b_bus, | |||||
b_busD => b_busD, | |||||
alu_func => alu_func, | |||||
alu_funcD => alu_funcD, | |||||
shift_func => shift_func, | |||||
shift_funcD => shift_funcD, | |||||
mult_func => mult_func, | |||||
mult_funcD => mult_funcD, | |||||
reg_dest => reg_dest, | |||||
reg_destD => reg_destD, | |||||
rd_index => rd_index, | |||||
rd_indexD => rd_indexD, | |||||
rs_index => rs_index, | |||||
rt_index => rt_index, | |||||
pc_source => pc_source, | |||||
mem_source => mem_source, | |||||
a_source => a_source, | |||||
b_source => b_source, | |||||
c_source => c_source, | |||||
c_bus => c_bus, | |||||
pause_any => pause_any, | |||||
pause_pipeline => pause_pipeline); | |||||
end generate; --pipeline3 | |||||
end; --architecture logic |
@@ -0,0 +1,522 @@ | |||||
--------------------------------------------------------------------- | |||||
-- TITLE: Plasma Misc. Package | |||||
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) | |||||
-- DATE CREATED: 2/15/01 | |||||
-- FILENAME: mlite_pack.vhd | |||||
-- PROJECT: Plasma CPU core | |||||
-- COPYRIGHT: Software placed into the public domain by the author. | |||||
-- Software 'as is' without warranty. Author liable for nothing. | |||||
-- DESCRIPTION: | |||||
-- Data types, constants, and add functions needed for the Plasma CPU. | |||||
--------------------------------------------------------------------- | |||||
library ieee; | |||||
use ieee.std_logic_1164.all; | |||||
package mlite_pack is | |||||
constant ZERO : std_logic_vector(31 downto 0) := | |||||
"00000000000000000000000000000000"; | |||||
constant ONES : std_logic_vector(31 downto 0) := | |||||
"11111111111111111111111111111111"; | |||||
--make HIGH_Z equal to ZERO if compiler complains | |||||
constant HIGH_Z : std_logic_vector(31 downto 0) := | |||||
"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; | |||||
subtype alu_function_type is std_logic_vector(3 downto 0); | |||||
constant ALU_NOTHING : alu_function_type := "0000"; | |||||
constant ALU_ADD : alu_function_type := "0001"; | |||||
constant ALU_SUBTRACT : alu_function_type := "0010"; | |||||
constant ALU_LESS_THAN : alu_function_type := "0011"; | |||||
constant ALU_LESS_THAN_SIGNED : alu_function_type := "0100"; | |||||
constant ALU_OR : alu_function_type := "0101"; | |||||
constant ALU_AND : alu_function_type := "0110"; | |||||
constant ALU_XOR : alu_function_type := "0111"; | |||||
constant ALU_NOR : alu_function_type := "1000"; | |||||
subtype shift_function_type is std_logic_vector(1 downto 0); | |||||
constant SHIFT_NOTHING : shift_function_type := "00"; | |||||
constant SHIFT_LEFT_UNSIGNED : shift_function_type := "01"; | |||||
constant SHIFT_RIGHT_SIGNED : shift_function_type := "11"; | |||||
constant SHIFT_RIGHT_UNSIGNED : shift_function_type := "10"; | |||||
subtype mult_function_type is std_logic_vector(3 downto 0); | |||||
constant MULT_NOTHING : mult_function_type := "0000"; | |||||
constant MULT_READ_LO : mult_function_type := "0001"; | |||||
constant MULT_READ_HI : mult_function_type := "0010"; | |||||
constant MULT_WRITE_LO : mult_function_type := "0011"; | |||||
constant MULT_WRITE_HI : mult_function_type := "0100"; | |||||
constant MULT_MULT : mult_function_type := "0101"; | |||||
constant MULT_SIGNED_MULT : mult_function_type := "0110"; | |||||
constant MULT_DIVIDE : mult_function_type := "0111"; | |||||
constant MULT_SIGNED_DIVIDE : mult_function_type := "1000"; | |||||
subtype a_source_type is std_logic_vector(1 downto 0); | |||||
constant A_FROM_REG_SOURCE : a_source_type := "00"; | |||||
constant A_FROM_IMM10_6 : a_source_type := "01"; | |||||
constant A_FROM_PC : a_source_type := "10"; | |||||
subtype b_source_type is std_logic_vector(1 downto 0); | |||||
constant B_FROM_REG_TARGET : b_source_type := "00"; | |||||
constant B_FROM_IMM : b_source_type := "01"; | |||||
constant B_FROM_SIGNED_IMM : b_source_type := "10"; | |||||
constant B_FROM_IMMX4 : b_source_type := "11"; | |||||
subtype c_source_type is std_logic_vector(2 downto 0); | |||||
constant C_FROM_NULL : c_source_type := "000"; | |||||
constant C_FROM_ALU : c_source_type := "001"; | |||||
constant C_FROM_SHIFT : c_source_type := "001"; --same as alu | |||||
constant C_FROM_MULT : c_source_type := "001"; --same as alu | |||||
constant C_FROM_MEMORY : c_source_type := "010"; | |||||
constant C_FROM_PC : c_source_type := "011"; | |||||
constant C_FROM_PC_PLUS4 : c_source_type := "100"; | |||||
constant C_FROM_IMM_SHIFT16: c_source_type := "101"; | |||||
constant C_FROM_REG_SOURCEN: c_source_type := "110"; | |||||
subtype pc_source_type is std_logic_vector(1 downto 0); | |||||
constant FROM_INC4 : pc_source_type := "00"; | |||||
constant FROM_OPCODE25_0 : pc_source_type := "01"; | |||||
constant FROM_BRANCH : pc_source_type := "10"; | |||||
constant FROM_LBRANCH : pc_source_type := "11"; | |||||
subtype branch_function_type is std_logic_vector(2 downto 0); | |||||
constant BRANCH_LTZ : branch_function_type := "000"; | |||||
constant BRANCH_LEZ : branch_function_type := "001"; | |||||
constant BRANCH_EQ : branch_function_type := "010"; | |||||
constant BRANCH_NE : branch_function_type := "011"; | |||||
constant BRANCH_GEZ : branch_function_type := "100"; | |||||
constant BRANCH_GTZ : branch_function_type := "101"; | |||||
constant BRANCH_YES : branch_function_type := "110"; | |||||
constant BRANCH_NO : branch_function_type := "111"; | |||||
-- mode(32=1,16=2,8=3), signed, write | |||||
subtype mem_source_type is std_logic_vector(3 downto 0); | |||||
constant MEM_FETCH : mem_source_type := "0000"; | |||||
constant MEM_READ32 : mem_source_type := "0100"; | |||||
constant MEM_WRITE32 : mem_source_type := "0101"; | |||||
constant MEM_READ16 : mem_source_type := "1000"; | |||||
constant MEM_READ16S : mem_source_type := "1010"; | |||||
constant MEM_WRITE16 : mem_source_type := "1001"; | |||||
constant MEM_READ8 : mem_source_type := "1100"; | |||||
constant MEM_READ8S : mem_source_type := "1110"; | |||||
constant MEM_WRITE8 : mem_source_type := "1101"; | |||||
function bv_adder(a : in std_logic_vector; | |||||
b : in std_logic_vector; | |||||
do_add: in std_logic) return std_logic_vector; | |||||
function bv_negate(a : in std_logic_vector) return std_logic_vector; | |||||
function bv_increment(a : in std_logic_vector(31 downto 2) | |||||
) return std_logic_vector; | |||||
function bv_inc(a : in std_logic_vector | |||||
) return std_logic_vector; | |||||
-- For Altera | |||||
COMPONENT lpm_ram_dp | |||||
generic ( | |||||
LPM_WIDTH : natural; -- MUST be greater than 0 | |||||
LPM_WIDTHAD : natural; -- MUST be greater than 0 | |||||
LPM_NUMWORDS : natural := 0; | |||||
LPM_INDATA : string := "REGISTERED"; | |||||
LPM_OUTDATA : string := "REGISTERED"; | |||||
LPM_RDADDRESS_CONTROL : string := "REGISTERED"; | |||||
LPM_WRADDRESS_CONTROL : string := "REGISTERED"; | |||||
LPM_FILE : string := "UNUSED"; | |||||
LPM_TYPE : string := "LPM_RAM_DP"; | |||||
USE_EAB : string := "OFF"; | |||||
INTENDED_DEVICE_FAMILY : string := "UNUSED"; | |||||
RDEN_USED : string := "TRUE"; | |||||
LPM_HINT : string := "UNUSED"); | |||||
port ( | |||||
RDCLOCK : in std_logic := '0'; | |||||
RDCLKEN : in std_logic := '1'; | |||||
RDADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0); | |||||
RDEN : in std_logic := '1'; | |||||
DATA : in std_logic_vector(LPM_WIDTH-1 downto 0); | |||||
WRADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0); | |||||
WREN : in std_logic; | |||||
WRCLOCK : in std_logic := '0'; | |||||
WRCLKEN : in std_logic := '1'; | |||||
Q : out std_logic_vector(LPM_WIDTH-1 downto 0)); | |||||
END COMPONENT; | |||||
-- For Altera | |||||
component LPM_RAM_DQ | |||||
generic ( | |||||
LPM_WIDTH : natural; -- MUST be greater than 0 | |||||
LPM_WIDTHAD : natural; -- MUST be greater than 0 | |||||
LPM_NUMWORDS : natural := 0; | |||||
LPM_INDATA : string := "REGISTERED"; | |||||
LPM_ADDRESS_CONTROL: string := "REGISTERED"; | |||||
LPM_OUTDATA : string := "REGISTERED"; | |||||
LPM_FILE : string := "UNUSED"; | |||||
LPM_TYPE : string := "LPM_RAM_DQ"; | |||||
USE_EAB : string := "OFF"; | |||||
INTENDED_DEVICE_FAMILY : string := "UNUSED"; | |||||
LPM_HINT : string := "UNUSED"); | |||||
port ( | |||||
DATA : in std_logic_vector(LPM_WIDTH-1 downto 0); | |||||
ADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0); | |||||
INCLOCK : in std_logic := '0'; | |||||
OUTCLOCK : in std_logic := '0'; | |||||
WE : in std_logic; | |||||
Q : out std_logic_vector(LPM_WIDTH-1 downto 0)); | |||||
end component; | |||||
-- For Xilinx | |||||
component RAM16X1D | |||||
-- synthesis translate_off | |||||
generic (INIT : bit_vector := X"16"); | |||||
-- synthesis translate_on | |||||
port (DPO : out STD_ULOGIC; | |||||
SPO : out STD_ULOGIC; | |||||
A0 : in STD_ULOGIC; | |||||
A1 : in STD_ULOGIC; | |||||
A2 : in STD_ULOGIC; | |||||
A3 : in STD_ULOGIC; | |||||
D : in STD_ULOGIC; | |||||
DPRA0 : in STD_ULOGIC; | |||||
DPRA1 : in STD_ULOGIC; | |||||
DPRA2 : in STD_ULOGIC; | |||||
DPRA3 : in STD_ULOGIC; | |||||
WCLK : in STD_ULOGIC; | |||||
WE : in STD_ULOGIC); | |||||
end component; | |||||
component pc_next | |||||
port(clk : in std_logic; | |||||
reset_in : in std_logic; | |||||
pc_new : in std_logic_vector(31 downto 2); | |||||
take_branch : in std_logic; | |||||
pause_in : in std_logic; | |||||
opcode25_0 : in std_logic_vector(25 downto 0); | |||||
pc_source : in pc_source_type; | |||||
pc_future : out std_logic_vector(31 downto 2); | |||||
pc_current : out std_logic_vector(31 downto 2); | |||||
pc_plus4 : out std_logic_vector(31 downto 2)); | |||||
end component; | |||||
component mem_ctrl | |||||
port(clk : in std_logic; | |||||
reset_in : in std_logic; | |||||
pause_in : in std_logic; | |||||
nullify_op : in std_logic; | |||||
address_pc : in std_logic_vector(31 downto 2); | |||||
opcode_out : out std_logic_vector(31 downto 0); | |||||
address_in : in std_logic_vector(31 downto 0); | |||||
mem_source : in mem_source_type; | |||||
data_write : in std_logic_vector(31 downto 0); | |||||
data_read : out std_logic_vector(31 downto 0); | |||||
pause_out : out std_logic; | |||||
address_next : out std_logic_vector(31 downto 2); | |||||
byte_we_next : out std_logic_vector(3 downto 0); | |||||
address : out std_logic_vector(31 downto 2); | |||||
byte_we : out std_logic_vector(3 downto 0); | |||||
data_w : out std_logic_vector(31 downto 0); | |||||
data_r : in std_logic_vector(31 downto 0)); | |||||
end component; | |||||
component control | |||||
port(opcode : in std_logic_vector(31 downto 0); | |||||
intr_signal : in std_logic; | |||||
rs_index : out std_logic_vector(5 downto 0); | |||||
rt_index : out std_logic_vector(5 downto 0); | |||||
rd_index : out std_logic_vector(5 downto 0); | |||||
imm_out : out std_logic_vector(15 downto 0); | |||||
alu_func : out alu_function_type; | |||||
shift_func : out shift_function_type; | |||||
mult_func : out mult_function_type; | |||||
branch_func : out branch_function_type; | |||||
a_source_out : out a_source_type; | |||||
b_source_out : out b_source_type; | |||||
c_source_out : out c_source_type; | |||||
pc_source_out: out pc_source_type; | |||||
mem_source_out:out mem_source_type; | |||||
exception_out: out std_logic); | |||||
end component; | |||||
component reg_bank | |||||
generic(memory_type : string := "XILINX_16X"); | |||||
port(clk : in std_logic; | |||||
reset_in : in std_logic; | |||||
pause : in std_logic; | |||||
rs_index : in std_logic_vector(5 downto 0); | |||||
rt_index : in std_logic_vector(5 downto 0); | |||||
rd_index : in std_logic_vector(5 downto 0); | |||||
reg_source_out : out std_logic_vector(31 downto 0); | |||||
reg_target_out : out std_logic_vector(31 downto 0); | |||||
reg_dest_new : in std_logic_vector(31 downto 0); | |||||
intr_enable : out std_logic); | |||||
end component; | |||||
component bus_mux | |||||
port(imm_in : in std_logic_vector(15 downto 0); | |||||
reg_source : in std_logic_vector(31 downto 0); | |||||
a_mux : in a_source_type; | |||||
a_out : out std_logic_vector(31 downto 0); | |||||
reg_target : in std_logic_vector(31 downto 0); | |||||
b_mux : in b_source_type; | |||||
b_out : out std_logic_vector(31 downto 0); | |||||
c_bus : in std_logic_vector(31 downto 0); | |||||
c_memory : in std_logic_vector(31 downto 0); | |||||
c_pc : in std_logic_vector(31 downto 2); | |||||
c_pc_plus4 : in std_logic_vector(31 downto 2); | |||||
c_mux : in c_source_type; | |||||
reg_dest_out : out std_logic_vector(31 downto 0); | |||||
branch_func : in branch_function_type; | |||||
take_branch : out std_logic); | |||||
end component; | |||||
component alu | |||||
generic(alu_type : string := "DEFAULT"); | |||||
port(a_in : in std_logic_vector(31 downto 0); | |||||
b_in : in std_logic_vector(31 downto 0); | |||||
alu_function : in alu_function_type; | |||||
c_alu : out std_logic_vector(31 downto 0)); | |||||
end component; | |||||
component shifter | |||||
generic(shifter_type : string := "DEFAULT" ); | |||||
port(value : in std_logic_vector(31 downto 0); | |||||
shift_amount : in std_logic_vector(4 downto 0); | |||||
shift_func : in shift_function_type; | |||||
c_shift : out std_logic_vector(31 downto 0)); | |||||
end component; | |||||
component mult | |||||
generic(mult_type : string := "DEFAULT"); | |||||
port(clk : in std_logic; | |||||
reset_in : in std_logic; | |||||
a, b : in std_logic_vector(31 downto 0); | |||||
mult_func : in mult_function_type; | |||||
c_mult : out std_logic_vector(31 downto 0); | |||||
pause_out : out std_logic); | |||||
end component; | |||||
component pipeline | |||||
port(clk : in std_logic; | |||||
reset : in std_logic; | |||||
a_bus : in std_logic_vector(31 downto 0); | |||||
a_busD : out std_logic_vector(31 downto 0); | |||||
b_bus : in std_logic_vector(31 downto 0); | |||||
b_busD : out std_logic_vector(31 downto 0); | |||||
alu_func : in alu_function_type; | |||||
alu_funcD : out alu_function_type; | |||||
shift_func : in shift_function_type; | |||||
shift_funcD : out shift_function_type; | |||||
mult_func : in mult_function_type; | |||||
mult_funcD : out mult_function_type; | |||||
reg_dest : in std_logic_vector(31 downto 0); | |||||
reg_destD : out std_logic_vector(31 downto 0); | |||||
rd_index : in std_logic_vector(5 downto 0); | |||||
rd_indexD : out std_logic_vector(5 downto 0); | |||||
rs_index : in std_logic_vector(5 downto 0); | |||||
rt_index : in std_logic_vector(5 downto 0); | |||||
pc_source : in pc_source_type; | |||||
mem_source : in mem_source_type; | |||||
a_source : in a_source_type; | |||||
b_source : in b_source_type; | |||||
c_source : in c_source_type; | |||||
c_bus : in std_logic_vector(31 downto 0); | |||||
pause_any : in std_logic; | |||||
pause_pipeline : out std_logic); | |||||
end component; | |||||
component mlite_cpu | |||||
generic(memory_type : string := "XILINX_16X"; --ALTERA_LPM, or DUAL_PORT_ | |||||
mult_type : string := "DEFAULT"; | |||||
shifter_type : string := "DEFAULT"; | |||||
alu_type : string := "DEFAULT"; | |||||
pipeline_stages : natural := 2); --2 or 3 | |||||
port(clk : in std_logic; | |||||
reset_in : in std_logic; | |||||
intr_in : in std_logic; | |||||
address_next : out std_logic_vector(31 downto 2); --for synch ram | |||||
byte_we_next : out std_logic_vector(3 downto 0); | |||||
address : out std_logic_vector(31 downto 2); | |||||
byte_we : out std_logic_vector(3 downto 0); | |||||
data_w : out std_logic_vector(31 downto 0); | |||||
data_r : in std_logic_vector(31 downto 0); | |||||
mem_pause : in std_logic); | |||||
end component; | |||||
component ram | |||||
generic(memory_type : string := "DEFAULT"); | |||||
port(clk : in std_logic; | |||||
enable : in std_logic; | |||||
write_byte_enable : in std_logic_vector(3 downto 0); | |||||
address : in std_logic_vector(31 downto 2); | |||||
data_write : in std_logic_vector(31 downto 0); | |||||
data_read : out std_logic_vector(31 downto 0)); | |||||
end component; --ram | |||||
component uart | |||||
generic(log_file : string := "UNUSED"); | |||||
port(clk : in std_logic; | |||||
reset : in std_logic; | |||||
enable_read : in std_logic; | |||||
enable_write : in std_logic; | |||||
data_in : in std_logic_vector(7 downto 0); | |||||
data_out : out std_logic_vector(7 downto 0); | |||||
uart_read : in std_logic; | |||||
uart_write : out std_logic; | |||||
busy_write : out std_logic; | |||||
data_avail : out std_logic); | |||||
end component; --uart | |||||
component eth_dma | |||||
port(clk : in std_logic; --25 MHz | |||||
reset : in std_logic; | |||||
enable_eth : in std_logic; | |||||
select_eth : in std_logic; | |||||
rec_isr : out std_logic; | |||||
send_isr : out std_logic; | |||||
address : out std_logic_vector(31 downto 2); --to DDR | |||||
byte_we : out std_logic_vector(3 downto 0); | |||||
data_write : out std_logic_vector(31 downto 0); | |||||
data_read : in std_logic_vector(31 downto 0); | |||||
pause_in : in std_logic; | |||||
mem_address : in std_logic_vector(31 downto 2); --from CPU | |||||
mem_byte_we : in std_logic_vector(3 downto 0); | |||||
data_w : in std_logic_vector(31 downto 0); | |||||
pause_out : out std_logic; | |||||
E_RX_CLK : in std_logic; --2.5 MHz receive | |||||
E_RX_DV : in std_logic; --data valid | |||||
E_RXD : in std_logic_vector(3 downto 0); --receive nibble | |||||
E_TX_CLK : in std_logic; --2.5 MHz transmit | |||||
E_TX_EN : out std_logic; --transmit enable | |||||
E_TXD : out std_logic_vector(3 downto 0)); --transmit nibble | |||||
end component; --eth_dma | |||||
component plasma | |||||
generic(memory_type : string := "XILINX_X16"; --"DUAL_PORT_" "ALTERA_LPM"; | |||||
log_file : string := "UNUSED"; | |||||
ethernet : std_logic := '0'); | |||||
port(clk : in std_logic; | |||||
reset : in std_logic; | |||||
uart_write : out std_logic; | |||||
uart_read : in std_logic; | |||||
address : out std_logic_vector(31 downto 2); | |||||
byte_we : out std_logic_vector(3 downto 0); | |||||
data_write : out std_logic_vector(31 downto 0); | |||||
data_read : in std_logic_vector(31 downto 0); | |||||
mem_pause_in : in std_logic; | |||||
gpio0_out : out std_logic_vector(31 downto 0); | |||||
gpioA_in : in std_logic_vector(31 downto 0)); | |||||
end component; --plasma | |||||
component ddr_ctrl | |||||
port(clk : in std_logic; | |||||
clk_2x : in std_logic; | |||||
reset_in : in std_logic; | |||||
address : in std_logic_vector(25 downto 2); | |||||
byte_we : in std_logic_vector(3 downto 0); | |||||
data_w : in std_logic_vector(31 downto 0); | |||||
data_r : out std_logic_vector(31 downto 0); | |||||
active : in std_logic; | |||||
pause : out std_logic; | |||||
SD_CK_P : out std_logic; --clock_positive | |||||
SD_CK_N : out std_logic; --clock_negative | |||||
SD_CKE : out std_logic; --clock_enable | |||||
SD_BA : out std_logic_vector(1 downto 0); --bank_address | |||||
SD_A : out std_logic_vector(12 downto 0); --address(row or col) | |||||
SD_CS : out std_logic; --chip_select | |||||
SD_RAS : out std_logic; --row_address_strobe | |||||
SD_CAS : out std_logic; --column_address_strobe | |||||
SD_WE : out std_logic; --write_enable | |||||
SD_DQ : inout std_logic_vector(15 downto 0); --data | |||||
SD_UDM : out std_logic; --upper_byte_enable | |||||
SD_UDQS : inout std_logic; --upper_data_strobe | |||||
SD_LDM : out std_logic; --low_byte_enable | |||||
SD_LDQS : inout std_logic); --low_data_strobe | |||||
end component; --ddr | |||||
end; --package mlite_pack | |||||
package body mlite_pack is | |||||
function bv_adder(a : in std_logic_vector; | |||||
b : in std_logic_vector; | |||||
do_add: in std_logic) return std_logic_vector is | |||||
variable carry_in : std_logic; | |||||
variable bb : std_logic_vector(a'length-1 downto 0); | |||||
variable result : std_logic_vector(a'length downto 0); | |||||
begin | |||||
if do_add = '1' then | |||||
bb := b; | |||||
carry_in := '0'; | |||||
else | |||||
bb := not b; | |||||
carry_in := '1'; | |||||
end if; | |||||
for index in 0 to a'length-1 loop | |||||
result(index) := a(index) xor bb(index) xor carry_in; | |||||
carry_in := (carry_in and (a(index) or bb(index))) or | |||||
(a(index) and bb(index)); | |||||
end loop; | |||||
result(a'length) := carry_in xnor do_add; | |||||
return result; | |||||
end; --function | |||||
function bv_negate(a : in std_logic_vector) return std_logic_vector is | |||||
variable carry_in : std_logic; | |||||
variable not_a : std_logic_vector(a'length-1 downto 0); | |||||
variable result : std_logic_vector(a'length-1 downto 0); | |||||
begin | |||||
not_a := not a; | |||||
carry_in := '1'; | |||||
for index in a'reverse_range loop | |||||
result(index) := not_a(index) xor carry_in; | |||||
carry_in := carry_in and not_a(index); | |||||
end loop; | |||||
return result; | |||||
end; --function | |||||
function bv_increment(a : in std_logic_vector(31 downto 2) | |||||
) return std_logic_vector is | |||||
variable carry_in : std_logic; | |||||
variable result : std_logic_vector(31 downto 2); | |||||
begin | |||||
carry_in := '1'; | |||||
for index in 2 to 31 loop | |||||
result(index) := a(index) xor carry_in; | |||||
carry_in := a(index) and carry_in; | |||||
end loop; | |||||
return result; | |||||
end; --function | |||||
function bv_inc(a : in std_logic_vector | |||||
) return std_logic_vector is | |||||
variable carry_in : std_logic; | |||||
variable result : std_logic_vector(a'length-1 downto 0); | |||||
begin | |||||
carry_in := '1'; | |||||
for index in 0 to a'length-1 loop | |||||
result(index) := a(index) xor carry_in; | |||||
carry_in := a(index) and carry_in; | |||||
end loop; | |||||
return result; | |||||
end; --function | |||||
end; --package body | |||||
@@ -0,0 +1,208 @@ | |||||
--------------------------------------------------------------------- | |||||
-- TITLE: Multiplication and Division Unit | |||||
-- AUTHORS: Steve Rhoads (rhoadss@yahoo.com) | |||||
-- DATE CREATED: 1/31/01 | |||||
-- FILENAME: mult.vhd | |||||
-- PROJECT: Plasma CPU core | |||||
-- COPYRIGHT: Software placed into the public domain by the author. | |||||
-- Software 'as is' without warranty. Author liable for nothing. | |||||
-- DESCRIPTION: | |||||
-- Implements the multiplication and division unit in 32 clocks. | |||||
-- | |||||
-- To reduce space, compile your code using the flag "-mno-mul" which | |||||
-- will use software base routines in math.c if USE_SW_MULT is defined. | |||||
-- Then remove references to the entity mult in mlite_cpu.vhd. | |||||
-- | |||||
-- MULTIPLICATION | |||||
-- long64 answer = 0 | |||||
-- for(i = 0; i < 32; ++i) | |||||
-- { | |||||
-- answer = (answer >> 1) + (((b&1)?a:0) << 31); | |||||
-- b = b >> 1; | |||||
-- } | |||||
-- | |||||
-- DIVISION | |||||
-- long upper=a, lower=0; | |||||
-- a = b << 31; | |||||
-- for(i = 0; i < 32; ++i) | |||||
-- { | |||||
-- lower = lower << 1; | |||||
-- if(upper >= a && a && b < 2) | |||||
-- { | |||||
-- upper = upper - a; | |||||
-- lower |= 1; | |||||
-- } | |||||
-- a = ((b&2) << 30) | (a >> 1); | |||||
-- b = b >> 1; | |||||
-- } | |||||
--------------------------------------------------------------------- | |||||
library ieee; | |||||
use ieee.std_logic_1164.all; | |||||
use ieee.std_logic_unsigned.all; | |||||
use IEEE.std_logic_arith.all; | |||||
use work.mlite_pack.all; | |||||
entity mult is | |||||
generic(mult_type : string := "DEFAULT"); | |||||
port(clk : in std_logic; | |||||
reset_in : in std_logic; | |||||
a, b : in std_logic_vector(31 downto 0); | |||||
mult_func : in mult_function_type; | |||||
c_mult : out std_logic_vector(31 downto 0); | |||||
pause_out : out std_logic); | |||||
end; --entity mult | |||||
architecture logic of mult is | |||||
constant MODE_MULT : std_logic := '1'; | |||||
constant MODE_DIV : std_logic := '0'; | |||||
signal mode_reg : std_logic; | |||||
signal negate_reg : std_logic; | |||||
signal sign_reg : std_logic; | |||||
signal sign2_reg : std_logic; | |||||
signal count_reg : std_logic_vector(5 downto 0); | |||||
signal aa_reg : std_logic_vector(31 downto 0); | |||||
signal bb_reg : std_logic_vector(31 downto 0); | |||||
signal upper_reg : std_logic_vector(31 downto 0); | |||||
signal lower_reg : std_logic_vector(31 downto 0); | |||||
signal a_neg : std_logic_vector(31 downto 0); | |||||
signal b_neg : std_logic_vector(31 downto 0); | |||||
signal sum : std_logic_vector(32 downto 0); | |||||
begin | |||||
-- Result | |||||
c_mult <= lower_reg when mult_func = MULT_READ_LO and negate_reg = '0' else | |||||
bv_negate(lower_reg) when mult_func = MULT_READ_LO | |||||
and negate_reg = '1' else | |||||
upper_reg when mult_func = MULT_READ_HI else | |||||
ZERO; | |||||
pause_out <= '1' when (count_reg /= "000000") and | |||||
(mult_func = MULT_READ_LO or mult_func = MULT_READ_HI) else '0'; | |||||
-- ABS and remainder signals | |||||
a_neg <= bv_negate(a); | |||||
b_neg <= bv_negate(b); | |||||
sum <= bv_adder(upper_reg, aa_reg, mode_reg); | |||||
--multiplication/division unit | |||||
mult_proc: process(clk, reset_in, a, b, mult_func, | |||||
a_neg, b_neg, sum, sign_reg, mode_reg, negate_reg, | |||||
count_reg, aa_reg, bb_reg, upper_reg, lower_reg) | |||||
variable count : std_logic_vector(2 downto 0); | |||||
begin | |||||
count := "001"; | |||||
if reset_in = '1' then | |||||
mode_reg <= '0'; | |||||
negate_reg <= '0'; | |||||
sign_reg <= '0'; | |||||
sign2_reg <= '0'; | |||||
count_reg <= "000000"; | |||||
aa_reg <= ZERO; | |||||
bb_reg <= ZERO; | |||||
upper_reg <= ZERO; | |||||
lower_reg <= ZERO; | |||||
elsif rising_edge(clk) then | |||||
case mult_func is | |||||
when MULT_WRITE_LO => | |||||
lower_reg <= a; | |||||
negate_reg <= '0'; | |||||
when MULT_WRITE_HI => | |||||
upper_reg <= a; | |||||
negate_reg <= '0'; | |||||
when MULT_MULT => | |||||
mode_reg <= MODE_MULT; | |||||
aa_reg <= a; | |||||
bb_reg <= b; | |||||
upper_reg <= ZERO; | |||||
count_reg <= "100000"; | |||||
negate_reg <= '0'; | |||||
sign_reg <= '0'; | |||||
sign2_reg <= '0'; | |||||
when MULT_SIGNED_MULT => | |||||
mode_reg <= MODE_MULT; | |||||
if b(31) = '0' then | |||||
aa_reg <= a; | |||||
bb_reg <= b; | |||||
sign_reg <= a(31); | |||||
else | |||||
aa_reg <= a_neg; | |||||
bb_reg <= b_neg; | |||||
sign_reg <= a_neg(31); | |||||
end if; | |||||
sign2_reg <= '0'; | |||||
upper_reg <= ZERO; | |||||
count_reg <= "100000"; | |||||
negate_reg <= '0'; | |||||
when MULT_DIVIDE => | |||||
mode_reg <= MODE_DIV; | |||||
aa_reg <= b(0) & ZERO(30 downto 0); | |||||
bb_reg <= b; | |||||
upper_reg <= a; | |||||
count_reg <= "100000"; | |||||
negate_reg <= '0'; | |||||
when MULT_SIGNED_DIVIDE => | |||||
mode_reg <= MODE_DIV; | |||||
if b(31) = '0' then | |||||
aa_reg(31) <= b(0); | |||||
bb_reg <= b; | |||||
else | |||||
aa_reg(31) <= b_neg(0); | |||||
bb_reg <= b_neg; | |||||
end if; | |||||
if a(31) = '0' then | |||||
upper_reg <= a; | |||||
else | |||||
upper_reg <= a_neg; | |||||
end if; | |||||
aa_reg(30 downto 0) <= ZERO(30 downto 0); | |||||
count_reg <= "100000"; | |||||
negate_reg <= a(31) xor b(31); | |||||
when others => | |||||
if count_reg /= "000000" then | |||||
if mode_reg = MODE_MULT then | |||||
-- Multiplication | |||||
if bb_reg(0) = '1' then | |||||
upper_reg <= (sign_reg xor sum(32)) & sum(31 downto 1); | |||||
lower_reg <= sum(0) & lower_reg(31 downto 1); | |||||
sign2_reg <= sign2_reg or sign_reg; | |||||
sign_reg <= '0'; | |||||
bb_reg <= '0' & bb_reg(31 downto 1); | |||||
-- The following six lines are optional for speedup | |||||
elsif bb_reg(3 downto 0) = "0000" and sign2_reg = '0' and | |||||
count_reg(5 downto 2) /= "0000" then | |||||
upper_reg <= "0000" & upper_reg(31 downto 4); | |||||
lower_reg <= upper_reg(3 downto 0) & lower_reg(31 downto 4); | |||||
count := "100"; | |||||
bb_reg <= "0000" & bb_reg(31 downto 4); | |||||
else | |||||
upper_reg <= sign2_reg & upper_reg(31 downto 1); | |||||
lower_reg <= upper_reg(0) & lower_reg(31 downto 1); | |||||
bb_reg <= '0' & bb_reg(31 downto 1); | |||||
end if; | |||||
else | |||||
-- Division | |||||
if sum(32) = '0' and aa_reg /= ZERO and | |||||
bb_reg(31 downto 1) = ZERO(31 downto 1) then | |||||
upper_reg <= sum(31 downto 0); | |||||
lower_reg(0) <= '1'; | |||||
else | |||||
lower_reg(0) <= '0'; | |||||
end if; | |||||
aa_reg <= bb_reg(1) & aa_reg(31 downto 1); | |||||
lower_reg(31 downto 1) <= lower_reg(30 downto 0); | |||||
bb_reg <= '0' & bb_reg(31 downto 1); | |||||
end if; | |||||
count_reg <= count_reg - count; | |||||
end if; --count | |||||
end case; | |||||
end if; | |||||
end process; | |||||
end; --architecture logic |
@@ -0,0 +1,71 @@ | |||||
--------------------------------------------------------------------- | |||||
-- TITLE: Program Counter Next | |||||
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) | |||||
-- DATE CREATED: 2/8/01 | |||||
-- FILENAME: pc_next.vhd | |||||
-- PROJECT: Plasma CPU core | |||||
-- COPYRIGHT: Software placed into the public domain by the author. | |||||
-- Software 'as is' without warranty. Author liable for nothing. | |||||
-- DESCRIPTION: | |||||
-- Implements the Program Counter logic. | |||||
--------------------------------------------------------------------- | |||||
library ieee; | |||||
use ieee.std_logic_1164.all; | |||||
use work.mlite_pack.all; | |||||
entity pc_next is | |||||
port(clk : in std_logic; | |||||
reset_in : in std_logic; | |||||
pc_new : in std_logic_vector(31 downto 2); | |||||
take_branch : in std_logic; | |||||
pause_in : in std_logic; | |||||
opcode25_0 : in std_logic_vector(25 downto 0); | |||||
pc_source : in pc_source_type; | |||||
pc_future : out std_logic_vector(31 downto 2); | |||||
pc_current : out std_logic_vector(31 downto 2); | |||||
pc_plus4 : out std_logic_vector(31 downto 2)); | |||||
end; --pc_next | |||||
architecture logic of pc_next is | |||||
signal pc_reg : std_logic_vector(31 downto 2); | |||||
begin | |||||
pc_select: process(clk, reset_in, pc_new, take_branch, pause_in, | |||||
opcode25_0, pc_source, pc_reg) | |||||
variable pc_inc : std_logic_vector(31 downto 2); | |||||
variable pc_next : std_logic_vector(31 downto 2); | |||||
begin | |||||
pc_inc := bv_increment(pc_reg); --pc_reg+1 | |||||
case pc_source is | |||||
when FROM_INC4 => | |||||
pc_next := pc_inc; | |||||
when FROM_OPCODE25_0 => | |||||
pc_next := pc_reg(31 downto 28) & opcode25_0; | |||||
when FROM_BRANCH | FROM_LBRANCH => | |||||
if take_branch = '1' then | |||||
pc_next := pc_new; | |||||
else | |||||
pc_next := pc_inc; | |||||
end if; | |||||
when others => | |||||
pc_next := pc_inc; | |||||
end case; | |||||
if pause_in = '1' then | |||||
pc_next := pc_reg; | |||||
end if; | |||||
if reset_in = '1' then | |||||
pc_reg <= ZERO(31 downto 2); | |||||
pc_next := pc_reg; | |||||
elsif rising_edge(clk) then | |||||
pc_reg <= pc_next; | |||||
end if; | |||||
pc_future <= pc_next; | |||||
pc_current <= pc_reg; | |||||
pc_plus4 <= pc_inc; | |||||
end process; | |||||
end; --logic |
@@ -0,0 +1,139 @@ | |||||
--------------------------------------------------------------------- | |||||
-- TITLE: Pipeline | |||||
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) | |||||
-- DATE CREATED: 6/24/02 | |||||
-- FILENAME: pipeline.vhd | |||||
-- PROJECT: Plasma CPU core | |||||
-- COPYRIGHT: Software placed into the public domain by the author. | |||||
-- Software 'as is' without warranty. Author liable for nothing. | |||||
-- DESCRIPTION: | |||||
-- Controls the three stage pipeline by delaying the signals: | |||||
-- a_bus, b_bus, alu/shift/mult_func, c_source, and rs_index. | |||||
--------------------------------------------------------------------- | |||||
library ieee; | |||||
use ieee.std_logic_1164.all; | |||||
use work.mlite_pack.all; | |||||
--Note: sigD <= sig after rising_edge(clk) | |||||
entity pipeline is | |||||
port(clk : in std_logic; | |||||
reset : in std_logic; | |||||
a_bus : in std_logic_vector(31 downto 0); | |||||
a_busD : out std_logic_vector(31 downto 0); | |||||
b_bus : in std_logic_vector(31 downto 0); | |||||
b_busD : out std_logic_vector(31 downto 0); | |||||
alu_func : in alu_function_type; | |||||
alu_funcD : out alu_function_type; | |||||
shift_func : in shift_function_type; | |||||
shift_funcD : out shift_function_type; | |||||
mult_func : in mult_function_type; | |||||
mult_funcD : out mult_function_type; | |||||
reg_dest : in std_logic_vector(31 downto 0); | |||||
reg_destD : out std_logic_vector(31 downto 0); | |||||
rd_index : in std_logic_vector(5 downto 0); | |||||
rd_indexD : out std_logic_vector(5 downto 0); | |||||
rs_index : in std_logic_vector(5 downto 0); | |||||
rt_index : in std_logic_vector(5 downto 0); | |||||
pc_source : in pc_source_type; | |||||
mem_source : in mem_source_type; | |||||
a_source : in a_source_type; | |||||
b_source : in b_source_type; | |||||
c_source : in c_source_type; | |||||
c_bus : in std_logic_vector(31 downto 0); | |||||
pause_any : in std_logic; | |||||
pause_pipeline : out std_logic); | |||||
end; --entity pipeline | |||||
architecture logic of pipeline is | |||||
signal rd_index_reg : std_logic_vector(5 downto 0); | |||||
signal reg_dest_reg : std_logic_vector(31 downto 0); | |||||
signal reg_dest_delay : std_logic_vector(31 downto 0); | |||||
signal c_source_reg : c_source_type; | |||||
signal pause_enable_reg : std_logic; | |||||
begin | |||||
--When operating in three stage pipeline mode, the following signals | |||||
--are delayed by one clock cycle: a_bus, b_bus, alu/shift/mult_func, | |||||
--c_source, and rd_index. | |||||
pipeline3: process(clk, reset, a_bus, b_bus, alu_func, shift_func, mult_func, | |||||
rd_index, rd_index_reg, pause_any, pause_enable_reg, | |||||
rs_index, rt_index, | |||||
pc_source, mem_source, a_source, b_source, c_source, c_source_reg, | |||||
reg_dest, reg_dest_reg, reg_dest_delay, c_bus) | |||||
variable pause_mult_clock : std_logic; | |||||
variable freeze_pipeline : std_logic; | |||||
begin | |||||
if (pc_source /= FROM_INC4 and pc_source /= FROM_OPCODE25_0) or | |||||
mem_source /= MEM_FETCH or | |||||
(mult_func = MULT_READ_LO or mult_func = MULT_READ_HI) then | |||||
pause_mult_clock := '1'; | |||||
else | |||||
pause_mult_clock := '0'; | |||||
end if; | |||||
freeze_pipeline := not (pause_mult_clock and pause_enable_reg) and pause_any; | |||||
pause_pipeline <= pause_mult_clock and pause_enable_reg; | |||||
rd_indexD <= rd_index_reg; | |||||
-- The value written back into the register bank, signal reg_dest is tricky. | |||||
-- If reg_dest comes from the ALU via the signal c_bus, it is already delayed | |||||
-- into stage #3, because a_busD and b_busD are delayed. If reg_dest comes from | |||||
-- c_memory, pc_current, or pc_plus4 then reg_dest hasn't yet been delayed into | |||||
-- stage #3. | |||||
-- Instead of delaying c_memory, pc_current, and pc_plus4, these signals | |||||
-- are multiplexed into reg_dest which is then delayed. The decision to use | |||||
-- the already delayed c_bus or the delayed value of reg_dest (reg_dest_reg) is | |||||
-- based on a delayed value of c_source (c_source_reg). | |||||
if c_source_reg = C_FROM_ALU then | |||||
reg_dest_delay <= c_bus; --delayed by 1 clock cycle via a_busD & b_busD | |||||
else | |||||
reg_dest_delay <= reg_dest_reg; --need to delay 1 clock cycle from reg_dest | |||||
end if; | |||||
reg_destD <= reg_dest_delay; | |||||
if reset = '1' then | |||||
a_busD <= ZERO; | |||||
b_busD <= ZERO; | |||||
alu_funcD <= ALU_NOTHING; | |||||
shift_funcD <= SHIFT_NOTHING; | |||||
mult_funcD <= MULT_NOTHING; | |||||
reg_dest_reg <= ZERO; | |||||
c_source_reg <= "000"; | |||||
rd_index_reg <= "000000"; | |||||
pause_enable_reg <= '0'; | |||||
elsif rising_edge(clk) then | |||||
if freeze_pipeline = '0' then | |||||
if (rs_index = "000000" or rs_index /= rd_index_reg) or | |||||
(a_source /= A_FROM_REG_SOURCE or pause_enable_reg = '0') then | |||||
a_busD <= a_bus; | |||||
else | |||||
a_busD <= reg_dest_delay; --rs from previous operation (bypass stage) | |||||
end if; | |||||
if (rt_index = "000000" or rt_index /= rd_index_reg) or | |||||
(b_source /= B_FROM_REG_TARGET or pause_enable_reg = '0') then | |||||
b_busD <= b_bus; | |||||
else | |||||
b_busD <= reg_dest_delay; --rt from previous operation | |||||
end if; | |||||
alu_funcD <= alu_func; | |||||
shift_funcD <= shift_func; | |||||
mult_funcD <= mult_func; | |||||
reg_dest_reg <= reg_dest; | |||||
c_source_reg <= c_source; | |||||
rd_index_reg <= rd_index; | |||||
end if; | |||||
if pause_enable_reg = '0' and pause_any = '0' then | |||||
pause_enable_reg <= '1'; --enable pause_pipeline | |||||
elsif pause_mult_clock = '1' then | |||||
pause_enable_reg <= '0'; --disable pause_pipeline | |||||
end if; | |||||
end if; | |||||
end process; --pipeline3 | |||||
end; --logic |
@@ -0,0 +1,301 @@ | |||||
--------------------------------------------------------------------- | |||||
-- TITLE: Plasma (CPU core with memory) | |||||
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) | |||||
-- DATE CREATED: 6/4/02 | |||||
-- FILENAME: plasma.vhd | |||||
-- PROJECT: Plasma CPU core | |||||
-- COPYRIGHT: Software placed into the public domain by the author. | |||||
-- Software 'as is' without warranty. Author liable for nothing. | |||||
-- DESCRIPTION: | |||||
-- This entity combines the CPU core with memory and a UART. | |||||
-- | |||||
-- Memory Map: | |||||
-- 0x00000000 - 0x0000ffff Internal RAM (8KB) | |||||
-- 0x10000000 - 0x100fffff External RAM (1MB) | |||||
-- Access all Misc registers with 32-bit accesses | |||||
-- 0x20000000 Uart Write (will pause CPU if busy) | |||||
-- 0x20000000 Uart Read | |||||
-- 0x20000010 IRQ Mask | |||||
-- 0x20000020 IRQ Status | |||||
-- 0x20000030 GPIO0 Out Set bits | |||||
-- 0x20000040 GPIO0 Out Clear bits | |||||
-- 0x20000050 GPIOA In | |||||
-- 0x20000060 Counter | |||||
-- 0x20000070 Ethernet transmit count | |||||
-- IRQ bits: | |||||
-- 7 GPIO31 | |||||
-- 6 ^GPIO31 | |||||
-- 5 EthernetSendDone | |||||
-- 4 EthernetReceive | |||||
-- 3 Counter(18) | |||||
-- 2 ^Counter(18) | |||||
-- 1 ^UartWriteBusy | |||||
-- 0 UartDataAvailable | |||||
--------------------------------------------------------------------- | |||||
library ieee; | |||||
use ieee.std_logic_1164.all; | |||||
use work.mlite_pack.all; | |||||
entity plasma is | |||||
generic(memory_type : string := "XILINX_16X"; --"DUAL_PORT_" "ALTERA_LPM"; | |||||
log_file : string := "UNUSED"); | |||||
port(clk : in std_logic; | |||||
clk66 : in std_logic; | |||||
reset : in std_logic; | |||||
uart_write : out std_logic; | |||||
uart_read : in std_logic; | |||||
address : out std_logic_vector(31 downto 2); | |||||
byte_we : out std_logic_vector(3 downto 0); | |||||
data_write : out std_logic_vector(31 downto 0); | |||||
data_read : in std_logic_vector(31 downto 0); | |||||
mem_pause_in : in std_logic; | |||||
gpio0_out : out std_logic_vector(31 downto 0); | |||||
gpioA_in : in std_logic_vector(31 downto 0); | |||||
pwm_out : out std_logic_vector(23 downto 0); | |||||
spi_miso : out std_logic; | |||||
spi_mosi : in std_logic; | |||||
spi_clk : in std_logic; | |||||
spi_cs : in std_logic); | |||||
end; --entity plasma | |||||
architecture logic of plasma is | |||||
component pwm2 is | |||||
Port ( clk : in STD_LOGIC; | |||||
clk66 : in std_logic; | |||||
reset : in STD_LOGIC; | |||||
address : in STD_LOGIC_VECTOR (31 downto 2); | |||||
enable : in std_logic; | |||||
byte_we : in std_logic_vector(3 downto 0); | |||||
data_read : out std_logic_vector(31 downto 0); | |||||
data_write : in STD_LOGIC_VECTOR (31 downto 0); | |||||
pwm_out : out STD_LOGIC_VECTOR (23 downto 0)); | |||||
end component; | |||||
component spi is | |||||
Port ( clk : in STD_LOGIC; | |||||
clk66 : in std_logic; | |||||
reset : in STD_LOGIC; | |||||
address : in STD_LOGIC_VECTOR (31 downto 2); | |||||
enable : in std_logic; | |||||
byte_we : in std_logic_vector(3 downto 0); | |||||
data_read : out std_logic_vector(31 downto 0); | |||||
data_write : in STD_LOGIC_VECTOR (31 downto 0); | |||||
spi_miso : out STD_LOGIC; | |||||
spi_mosi : in STD_LOGIC; | |||||
spi_clk : in STD_LOGIC; | |||||
spi_cs : in STD_LOGIC); | |||||
end component; | |||||
signal address_next : std_logic_vector(31 downto 2); | |||||
signal byte_we_next : std_logic_vector(3 downto 0); | |||||
signal mem_address : std_logic_vector(31 downto 2); | |||||
signal mem_byte_we : std_logic_vector(3 downto 0); | |||||
signal data_r : std_logic_vector(31 downto 0); | |||||
signal data_w : std_logic_vector(31 downto 0); | |||||
signal data_read_ram : std_logic_vector(31 downto 0); | |||||
signal data_read_ram2 : std_logic_vector(31 downto 0); | |||||
signal data_read_pwm : std_logic_vector(31 downto 0); | |||||
signal data_read_spi : std_logic_vector(31 downto 0); | |||||
signal data_read_uart : std_logic_vector(7 downto 0); | |||||
signal write_enable : std_logic; | |||||
signal mem_pause : std_logic; | |||||
signal eth_pause : std_logic; | |||||
signal enable_internal_ram : std_logic; | |||||
signal enable_internal_ram2 : std_logic; | |||||
signal enable_misc : std_logic; | |||||
signal enable_uart : std_logic; | |||||
signal enable_uart_read : std_logic; | |||||
signal enable_uart_write : std_logic; | |||||
signal enable_spi : std_logic; | |||||
signal enable_pwm : std_logic; | |||||
signal gpio0_reg : std_logic_vector(31 downto 0); | |||||
signal uart_write_busy : std_logic; | |||||
signal uart_data_avail : std_logic; | |||||
signal irq_mask_reg : std_logic_vector(7 downto 0); | |||||
signal irq_status : std_logic_vector(7 downto 0); | |||||
signal irq : std_logic; | |||||
signal irq_eth_rec : std_logic; | |||||
signal irq_eth_send : std_logic; | |||||
signal counter_reg : std_logic_vector(31 downto 0); | |||||
begin --architecture | |||||
write_enable <= '1' when mem_byte_we /= "0000" else '0'; | |||||
mem_pause <= ((mem_pause_in or eth_pause) and not enable_misc) or | |||||
(uart_write_busy and enable_uart and write_enable); | |||||
irq_status <= gpioA_in(31) & not gpioA_in(31) & | |||||
'0' & '0' & | |||||
counter_reg(18) & not counter_reg(18) & | |||||
not uart_write_busy & uart_data_avail; | |||||
irq <= '1' when (irq_status and irq_mask_reg) /= ZERO(7 downto 0) else '0'; | |||||
gpio0_out(31 downto 29) <= gpio0_reg(31 downto 29); | |||||
gpio0_out(23 downto 0) <= gpio0_reg(23 downto 0); | |||||
enable_internal_ram <= '1' when address_next(30 downto 28) = "000" else '0'; | |||||
enable_internal_ram2 <= '1' when address_next(30 downto 28) = "001" else '0'; | |||||
enable_misc <= '1' when mem_address(30 downto 28) = "010" else '0'; | |||||
enable_uart <= '1' when enable_misc = '1' and mem_address(7 downto 4) = "0000" else '0'; | |||||
enable_uart_read <= enable_uart and not write_enable; | |||||
enable_uart_write <= enable_uart and write_enable; | |||||
enable_pwm <= '1' when address_next(30 downto 28) = "100" else '0'; | |||||
enable_spi <= '1' when address_next(30 downto 28) = "101" else '0'; | |||||
u1_cpu: mlite_cpu | |||||
generic map (memory_type => memory_type) | |||||
PORT MAP ( | |||||
clk => clk, | |||||
reset_in => reset, | |||||
intr_in => irq, | |||||
address_next => address_next, | |||||
byte_we_next => byte_we_next, | |||||
address => mem_address, | |||||
byte_we => mem_byte_we, | |||||
data_w => data_w, | |||||
data_r => data_r, | |||||
mem_pause => mem_pause); | |||||
misc_proc: process(clk, reset, address_next, mem_address, enable_misc, | |||||
data_read_ram, data_read, data_read_uart, mem_pause, | |||||
irq_mask_reg, irq_status, gpio0_reg, write_enable, | |||||
gpioA_in, counter_reg, data_w) | |||||
begin | |||||
case mem_address(30 downto 28) is | |||||
when "000" => --internal RAM | |||||
data_r <= data_read_ram; | |||||
when "001" => --external RAM | |||||
data_r <= data_read_ram2; | |||||
when "010" => --misc | |||||
case mem_address(7 downto 4) is | |||||
when "0000" => --uart | |||||
data_r <= ZERO(31 downto 8) & data_read_uart; | |||||
when "0001" => --irq_mask | |||||
data_r <= ZERO(31 downto 8) & irq_mask_reg; | |||||
when "0010" => --irq_status | |||||
data_r <= ZERO(31 downto 8) & irq_status; | |||||
when "0011" => --gpio0 | |||||
data_r <= gpio0_reg; | |||||
when "0101" => --gpioA | |||||
data_r <= gpioA_in; | |||||
when "0110" => --counter | |||||
data_r <= counter_reg; | |||||
when others => | |||||
data_r <= gpioA_in; | |||||
end case; | |||||
when "011" => --flash | |||||
data_r <= data_read; | |||||
when "100" => | |||||
data_r <= data_read_pwm; | |||||
when "101" => | |||||
data_r <= data_read_spi; | |||||
when others => | |||||
data_r <= ZERO; | |||||
end case; | |||||
if reset = '1' then | |||||
irq_mask_reg <= ZERO(7 downto 0); | |||||
gpio0_reg <= ZERO; | |||||
counter_reg <= ZERO; | |||||
elsif rising_edge(clk) then | |||||
if mem_pause = '0' then | |||||
if enable_misc = '1' and write_enable = '1' then | |||||
if mem_address(6 downto 4) = "001" then | |||||
irq_mask_reg <= data_w(7 downto 0); | |||||
elsif mem_address(6 downto 4) = "011" then | |||||
gpio0_reg <= gpio0_reg or data_w; | |||||
elsif mem_address(6 downto 4) = "100" then | |||||
gpio0_reg <= gpio0_reg and not data_w; | |||||
end if; | |||||
end if; | |||||
end if; | |||||
counter_reg <= bv_inc(counter_reg); | |||||
end if; | |||||
end process; | |||||
u2_ram: ram | |||||
generic map (memory_type => memory_type) | |||||
port map ( | |||||
clk => clk, | |||||
enable => enable_internal_ram, | |||||
write_byte_enable => byte_we_next, | |||||
address => address_next, | |||||
data_write => data_w, | |||||
data_read => data_read_ram); | |||||
u3_uart: uart | |||||
generic map (log_file => log_file) | |||||
port map( | |||||
clk => clk, | |||||
reset => reset, | |||||
enable_read => enable_uart_read, | |||||
enable_write => enable_uart_write, | |||||
data_in => data_w(7 downto 0), | |||||
data_out => data_read_uart, | |||||
uart_read => uart_read, | |||||
uart_write => uart_write, | |||||
busy_write => uart_write_busy, | |||||
data_avail => uart_data_avail); | |||||
address <= mem_address; | |||||
byte_we <= mem_byte_we; | |||||
data_write <= data_w; | |||||
eth_pause <= '0'; | |||||
gpio0_out(28 downto 24) <= ZERO(28 downto 24); | |||||
irq_eth_rec <= '0'; | |||||
irq_eth_send <= '0'; | |||||
u4_ram2: ram | |||||
generic map (memory_type => memory_type) | |||||
port map ( | |||||
clk => clk, | |||||
enable => enable_internal_ram2, | |||||
write_byte_enable => byte_we_next, | |||||
address => address_next, | |||||
data_write => data_w, | |||||
data_read => data_read_ram2); | |||||
u5_pwm: pwm2 port map ( | |||||
clk => clk, | |||||
clk66 => clk66, | |||||
reset => reset, | |||||
enable => enable_pwm, | |||||
address => address_next, | |||||
byte_we => byte_we_next, | |||||
data_write => data_w, | |||||
data_read => data_read_pwm, | |||||
pwm_out => pwm_out | |||||
); | |||||
u6_spi: spi port map ( | |||||
clk => clk, | |||||
clk66 => clk66, | |||||
reset => reset, | |||||
enable => enable_spi, | |||||
address => address_next, | |||||
byte_we => byte_we_next, | |||||
data_write => data_w, | |||||
data_read => data_read_spi, | |||||
spi_miso => spi_miso, | |||||
spi_mosi => spi_mosi, | |||||
spi_clk => spi_clk, | |||||
spi_cs => spi_cs | |||||
); | |||||
end; --architecture logic |
@@ -0,0 +1,62 @@ | |||||
CONFIG PART = XC3S250E-TQ144-4; | |||||
NET "clk_in" TNM_NET = "clk_in"; | |||||
TIMESPEC "TS_clk_in" = PERIOD "clk_in" 15 ns HIGH 50 %; | |||||
NET "clk_reg1" TNM_NET = "clk_reg1"; | |||||
TIMESPEC "TS_clk_reg1" = PERIOD "clk_reg1" 30 ns HIGH 50 %; | |||||
NET "clk_in" LOC = "P122" | IOSTANDARD = LVCMOS33; | |||||
NET "gpio0_out<0>" LOC = "P44" | IOSTANDARD = LVCMOS33; | |||||
NET "gpio0_out<1>" LOC = "P43" | IOSTANDARD = LVCMOS33; | |||||
NET "gpio0_out<2>" LOC = "P113" | IOSTANDARD = LVCMOS33; | |||||
NET "gpioA_in<0>" LOC = "P84" | IOSTANDARD = LVCMOS33 | PULLUP; | |||||
NET "gpioA_in<1>" LOC = "P69" | IOSTANDARD = LVCMOS33 | PULLUP; | |||||
NET "reset" LOC = "P78" | IOSTANDARD = LVCMOS33 | PULLUP; | |||||
NET "uart_console_read" LOC = "P29" | IOSTANDARD = LVCMOS33; | |||||
NET "uart_console_write" LOC = "P32" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<0>" LOC = "P116" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<1>" LOC = "P112" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<2>" LOC = "P106" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<3>" LOC = "P132" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<4>" LOC = "P134" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<5>" LOC = "P139" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<6>" LOC = "P142" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<7>" LOC = "P140" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<8>" LOC = "P135" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<9>" LOC = "P8" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<10>" LOC = "P4" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<11>" LOC = "P2" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<12>" LOC = "P3" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<13>" LOC = "P5" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<14>" LOC = "P7" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<15>" LOC = "P35" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<16>" LOC = "P33" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<17>" LOC = "P31" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<18>" LOC = "P26" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<19>" LOC = "P23" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<20>" LOC = "P21" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<21>" LOC = "P130" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<22>" LOC = "P125" | IOSTANDARD = LVCMOS33; | |||||
NET "pwm_out<23>" LOC = "P124" | IOSTANDARD = LVCMOS33; | |||||
NET "spi_miso" LOC="P39" | IOSTANDARD = LVCMOS33; | |||||
NET "spi_mosi" LOC="P41" | IOSTANDARD = LVCMOS33; | |||||
NET "spi_clk" LOC="P15" | IOSTANDARD = LVCMOS33; | |||||
NET "spi_cs" LOC="P36" | IOSTANDARD = LVCMOS33; | |||||
NET "spi_clk" CLOCK_DEDICATED_ROUTE = FALSE; |
@@ -0,0 +1,129 @@ | |||||
--------------------------------------------------------------------- | |||||
-- TITLE: Plamsa Interface (clock divider and interface to FPGA board) | |||||
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) | |||||
-- DATE CREATED: 6/6/02 | |||||
-- FILENAME: plasma_if.vhd | |||||
-- PROJECT: Plasma CPU core | |||||
-- COPYRIGHT: Software placed into the public domain by the author. | |||||
-- Software 'as is' without warranty. Author liable for nothing. | |||||
-- DESCRIPTION: | |||||
-- This entity divides the clock by two and interfaces to the | |||||
-- Altera EP20K200EFC484-2X FPGA board. | |||||
-- Xilinx Spartan-3 XC3S200FT256-4 FPGA. | |||||
--------------------------------------------------------------------- | |||||
library ieee; | |||||
use ieee.std_logic_1164.all; | |||||
--use work.mlite_pack.all; | |||||
entity plasma_if is | |||||
port(clk_in : in std_logic; | |||||
reset : in std_logic; | |||||
uart_console_read : in std_logic; | |||||
uart_console_write : out std_logic; | |||||
spi_miso : out std_logic; | |||||
spi_mosi :in std_logic; | |||||
spi_clk : in std_logic; | |||||
spi_cs : in std_logic; | |||||
gpio0_out : out std_logic_vector(2 downto 0); | |||||
gpioA_in : in std_logic_vector(1 downto 0); | |||||
pwm_out : out std_logic_vector(23 downto 0)); | |||||
end; --entity plasma_if | |||||
architecture logic of plasma_if is | |||||
component plasma | |||||
generic(memory_type : string := "XILINX_16X"; --"DUAL_PORT_" "ALTERA_LPM"; | |||||
log_file : string := "UNUSED"); | |||||
port(clk : in std_logic; | |||||
clk66 : in std_logic; | |||||
reset : in std_logic; | |||||
uart_write : out std_logic; | |||||
uart_read : in std_logic; | |||||
address : out std_logic_vector(31 downto 2); | |||||
byte_we : out std_logic_vector(3 downto 0); | |||||
data_write : out std_logic_vector(31 downto 0); | |||||
data_read : in std_logic_vector(31 downto 0); | |||||
mem_pause_in : in std_logic; | |||||
gpio0_out : out std_logic_vector(31 downto 0); | |||||
gpioA_in : in std_logic_vector(31 downto 0); | |||||
pwm_out : out std_logic_vector(23 downto 0); | |||||
spi_miso : out std_logic; | |||||
spi_mosi : in std_logic; | |||||
spi_clk : in std_logic; | |||||
spi_cs : in std_logic); | |||||
end component; --plasma | |||||
signal clk_reg : std_logic; | |||||
signal we_n_next : std_logic; | |||||
signal we_n_reg : std_logic; | |||||
signal mem_address : std_logic_vector(31 downto 2); | |||||
signal data_write : std_logic_vector(31 downto 0); | |||||
signal data_reg : std_logic_vector(31 downto 0); | |||||
signal byte_we : std_logic_vector(3 downto 0); | |||||
signal mem_pause_in : std_logic; | |||||
signal gpio0_out_reg : std_logic_vector(31 downto 0); | |||||
signal gpioA_in_reg : std_logic_vector(31 downto 0); | |||||
signal uart_plasma_console_write : std_logic; | |||||
signal uart_plasma_console_read : std_logic; | |||||
signal consel : std_logic; | |||||
begin --architecture | |||||
--Divide 50 MHz clock by two | |||||
clk_div: process(reset, clk_in, clk_reg, we_n_next) | |||||
begin | |||||
if reset = '0' then | |||||
clk_reg <= '0'; | |||||
elsif rising_edge(clk_in) then | |||||
clk_reg <= not clk_reg; | |||||
end if; | |||||
end process; --clk_div | |||||
mem_pause_in <= '0'; | |||||
gpio0_out(2 downto 0)<=gpio0_out_reg(2 downto 0); | |||||
gpioA_in_reg(1 downto 0)<=gpioA_in(1 downto 0); | |||||
gpioA_in_reg(31 downto 2)<=(others=>'0'); | |||||
u1_plasma: plasma | |||||
generic map (memory_type => "XILINX_16X", | |||||
log_file => "UNUSED") | |||||
PORT MAP ( | |||||
clk => clk_reg, | |||||
clk66 => clk_in, | |||||
reset => not reset, | |||||
uart_write => uart_plasma_console_write, | |||||
uart_read => uart_plasma_console_read, | |||||
address => mem_address, | |||||
byte_we => byte_we, | |||||
data_write => data_write, | |||||
data_read => data_reg, | |||||
mem_pause_in => mem_pause_in, | |||||
gpio0_out => gpio0_out_reg, | |||||
gpioA_in => gpioA_in_reg, | |||||
pwm_out => pwm_out, | |||||
spi_mosi => spi_mosi, | |||||
spi_miso => spi_miso, | |||||
spi_clk => spi_clk, | |||||
spi_cs => spi_cs | |||||
); | |||||
uart_console_write <=uart_plasma_console_write; | |||||
uart_plasma_console_read <=uart_console_read; | |||||
end; --architecture logic | |||||
@@ -0,0 +1,129 @@ | |||||
---------------------------------------------------------------------------------- | |||||
-- Company: | |||||
-- Engineer: | |||||
-- | |||||
-- Create Date: 16:04:28 12/29/2008 | |||||
-- Design Name: | |||||
-- Module Name: pwm2 - 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; | |||||
use IEEE.STD_LOGIC_ARITH.ALL; | |||||
use IEEE.STD_LOGIC_UNSIGNED.ALL; | |||||
---- Uncomment the following library declaration if instantiating | |||||
---- any Xilinx primitives in this code. | |||||
library UNISIM; | |||||
use UNISIM.VComponents.all; | |||||
entity pwm2 is | |||||
Port ( clk : in STD_LOGIC; | |||||
clk66 : in std_logic; | |||||
reset : in STD_LOGIC; | |||||
address : in STD_LOGIC_VECTOR (31 downto 2); | |||||
enable : in std_logic; | |||||
byte_we : in std_logic_vector(3 downto 0); | |||||
data_read : out std_logic_vector(31 downto 0); | |||||
data_write : in STD_LOGIC_VECTOR (31 downto 0); | |||||
pwm_out : out STD_LOGIC_VECTOR (23 downto 0)); | |||||
end pwm2; | |||||
architecture Behavioral of pwm2 is | |||||
signal counter_66 : std_logic_vector(19 downto 0) := (others=>'0'); -- runs from 0 to 2^20-1=1048575 @ 66 MHz -> 62 Hz/15.9 ms | |||||
signal pwm_ram_addr : std_logic_vector(10 downto 0); | |||||
signal pwm_ram_out : std_logic_vector(15 downto 0); | |||||
signal pwm_counter : std_logic_vector(14 downto 0) := (others=>'0'); | |||||
signal pwm_index : std_logic_vector(4 downto 0) := (others=>'0'); | |||||
begin | |||||
counter_66_proc: process(clk66,reset) is | |||||
begin | |||||
if(reset='1') then | |||||
counter_66<=(others=>'0'); | |||||
pwm_out<=(others=>'0'); | |||||
else | |||||
if rising_edge(clk66) then | |||||
pwm_counter<=counter_66(17 downto 3); | |||||
pwm_index<=pwm_ram_addr(4 downto 0); | |||||
counter_66<=counter_66+1; | |||||
if(pwm_ram_out="000000000000000") then | |||||
pwm_out(conv_integer(pwm_index))<='0'; | |||||
else | |||||
if(pwm_counter<4096) then | |||||
pwm_out(conv_integer(pwm_index))<='1'; | |||||
elsif(pwm_counter>20480) then | |||||
pwm_out(conv_integer(pwm_index))<='0'; | |||||
elsif(pwm_counter<pwm_ram_out) then | |||||
pwm_out(conv_integer(pwm_index))<='1'; | |||||
else | |||||
pwm_out(conv_integer(pwm_index))<='0'; | |||||
end if; | |||||
end if; | |||||
end if; | |||||
end if; | |||||
end process; | |||||
pwm_ram_addr<="000000"&counter_66(2 downto 0)&counter_66(19 downto 18); | |||||
register_block_lo: RAMB16_S9_S9 | |||||
port map ( | |||||
CLKA => clk, | |||||
ENA => enable, | |||||
WEA => byte_we(0), | |||||
ADDRA => address(12 downto 2), | |||||
DIA => data_write(7 downto 0), | |||||
DOA => data_read(7 downto 0), | |||||
DIPA => (others=>'0'), | |||||
DOPA => open, | |||||
SSRA => '0', | |||||
CLKB => clk66, | |||||
ADDRB => pwm_ram_addr, | |||||
DIB => "00000000", | |||||
DOB => pwm_ram_out(7 downto 0), | |||||
DIPB => (others=>'0'), | |||||
DOPB => open, | |||||
ENB => '1', | |||||
SSRB => '0', | |||||
WEB => '0'); | |||||
register_block_hi: RAMB16_S9_S9 | |||||
port map ( | |||||
CLKA => clk, | |||||
ENA => enable, | |||||
WEA => byte_we(1), | |||||
ADDRA => address(12 downto 2), | |||||
DIA => data_write(15 downto 8), | |||||
DOA => data_read(15 downto 8), | |||||
DIPA => (others=>'0'), | |||||
DOPA => open, | |||||
SSRA => '0', | |||||
CLKB => clk66, | |||||
ENB => '1', | |||||
WEB => '0', | |||||
ADDRB => pwm_ram_addr, | |||||
DIB => "00000000", | |||||
DOB => pwm_ram_out(15 downto 8), | |||||
DOPB => open, | |||||
SSRB => '0'); | |||||
end Behavioral; | |||||