@@ -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; | |||