Disabled external gits

This commit is contained in:
2022-04-07 18:54:11 +02:00
parent 15e7120d6d
commit 0fb3e365d4
376 changed files with 50840 additions and 0 deletions

View File

@@ -0,0 +1,514 @@
#!/bin/bash -x
# ===================================================================================
# usage: create_linux_system.sh [sdcard_device]
#
# positional arguments:
# sdcard_device path to sdcard device file [ex: "/dev/sdb", "/dev/mmcblk0"]
# ===================================================================================
# make sure to be in the same directory as this script
script_dir_abs=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
cd "${script_dir_abs}"
# constants ####################################################################
quartus_dir="$(readlink -m "hw/quartus")"
quartus_project_name="$(basename "$(find "${quartus_dir}" -name "*.qpf")" .qpf)"
quartus_sof_file="$(readlink -m "${quartus_dir}/output_files/${quartus_project_name}.sof")"
fpga_device_part_number="5CSEMA4U23C6" # 5CSEMA5F31C6
preloader_dir="$(readlink -m "sw/hps/preloader")"
preloader_settings_dir="$(readlink -m "${quartus_dir}/hps_isw_handoff/soc_system_hps_0")"
preloader_settings_file="$(readlink -m "${preloader_dir}/settings.bsp")"
preloader_source_tgz_file="$(readlink -m "${SOCEDS_DEST_ROOT}/host_tools/altera/preloader/uboot-socfpga.tar.gz")"
preloader_bin_file="${preloader_dir}/preloader-mkpimage.bin"
uboot_src_dir="$(readlink -m "sw/hps/u-boot")"
uboot_src_git_repo="git://git.denx.de/u-boot.git"
uboot_src_git_checkout_commit="b104b3dc1dd90cdbf67ccf3c51b06e4f1592fe91"
uboot_src_make_config_file="socfpga_de0_nano_soc_defconfig" # socfpga_cyclone5_config
uboot_src_config_file="${uboot_src_dir}/include/configs/socfpga_de0_nano_soc.h" # socfpga_cyclone5_socdk.h
uboot_script_file="$(readlink -m "${uboot_src_dir}/u-boot.script")"
uboot_img_file="$(readlink -m "${uboot_src_dir}/u-boot.img")"
linux_dir="$(readlink -m "sw/hps/linux")"
linux_src_git_repo="https://github.com/altera-opensource/linux-socfpga.git"
linux_src_dir="$(readlink -m "${linux_dir}/source")"
linux_src_git_checkout_commit="9735a22799b9214d17d3c231fe377fc852f042e9"
linux_src_make_config_file="socfpga_defconfig"
linux_kernel_mem_arg="1024M"
linux_zImage_file="$(readlink -m "${linux_src_dir}/arch/arm/boot/zImage")"
linux_dtb_file="$(readlink -m "${linux_src_dir}/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dtb")" # socfpga_cyclone5_socdk.dtb
rootfs_dir="${linux_dir}/rootfs"
rootfs_chroot_dir="$(readlink -m ${rootfs_dir}/ubuntu-core-rootfs)"
rootfs_src_tgz_link="http://cdimage.ubuntu.com/ubuntu-base/releases/14.04.5/release/ubuntu-base-14.04.5-base-armhf.tar.gz"
rootfs_src_tgz_file="$(readlink -m "${rootfs_dir}/${rootfs_src_tgz_link##*/}")"
rootfs_system_config_script_file="${rootfs_dir}/config_system.sh"
rootfs_post_install_config_script_file="${rootfs_dir}/config_post_install.sh"
sdcard_fat32_dir="$(readlink -m "sdcard/fat32")"
sdcard_fat32_rbf_file="$(readlink -m "${sdcard_fat32_dir}/socfpga.rbf")"
sdcard_fat32_uboot_img_file="$(readlink -m "${sdcard_fat32_dir}/$(basename "${uboot_img_file}")")"
sdcard_fat32_uboot_scr_file="$(readlink -m "${sdcard_fat32_dir}/u-boot.scr")"
sdcard_fat32_zImage_file="$(readlink -m "${sdcard_fat32_dir}/zImage")"
sdcard_fat32_dtb_file="$(readlink -m "${sdcard_fat32_dir}/socfpga.dtb")"
sdcard_dev="$(readlink -m "${1}")"
sdcard_ext3_rootfs_tgz_file="$(readlink -m "sdcard/ext3_rootfs.tar.gz")"
sdcard_a2_dir="$(readlink -m "sdcard/a2")"
sdcard_a2_preloader_bin_file="$(readlink -m "${sdcard_a2_dir}/$(basename "${preloader_bin_file}")")"
sdcard_partition_size_fat32="32M"
sdcard_partition_size_linux="512M"
sdcard_partition_number_fat32="1"
sdcard_partition_number_ext3="2"
sdcard_partition_number_a2="3"
if [ "$(echo "${sdcard_dev}" | grep -P "/dev/sd\w.*$")" ]; then
sdcard_dev_fat32_id="${sdcard_partition_number_fat32}"
sdcard_dev_ext3_id="${sdcard_partition_number_ext3}"
sdcard_dev_a2_id="${sdcard_partition_number_a2}"
elif [ "$(echo "${sdcard_dev}" | grep -P "/dev/mmcblk\w.*$")" ]; then
sdcard_dev_fat32_id="p${sdcard_partition_number_fat32}"
sdcard_dev_ext3_id="p${sdcard_partition_number_ext3}"
sdcard_dev_a2_id="p${sdcard_partition_number_a2}"
fi
sdcard_dev_fat32="${sdcard_dev}${sdcard_dev_fat32_id}"
sdcard_dev_ext3="${sdcard_dev}${sdcard_dev_ext3_id}"
sdcard_dev_a2="${sdcard_dev}${sdcard_dev_a2_id}"
sdcard_dev_fat32_mount_point="$(readlink -m "sdcard/mount_point_fat32")"
sdcard_dev_ext3_mount_point="$(readlink -m "sdcard/mount_point_ext3")"
# compile_quartus_project() ####################################################
compile_quartus_project() {
# change working directory to quartus directory
pushd "${quartus_dir}"
# delete old artifacts
rm -rf "c5_pin_model_dump.txt" \
"db/" \
"hps_isw_handoff/" \
"hps_sdram_p0_all_pins.txt" \
"incremental_db/" \
"output_files/" \
"soc_system.sopcinfo" \
"soc_system/" \
"${quartus_project_name}.qws" \
"${sdcard_fat32_rbf_file}"
qsys-generate "soc_system.qsys" --synthesis=VHDL --output-directory="soc_system/" --part="${fpga_device_part_number}"
# Analysis and synthesis
quartus_map "${quartus_project_name}"
# Execute HPS DDR3 pin assignment TCL script
# it is normal for the following script to report an error, but it was
# sucessfully executed
#ddr3_pin_assignment_script="$(find . -name "hps_sdram_p0_pin_assignments.tcl")"
#quartus_sta -t "${ddr3_pin_assignment_script}" "${quartus_project_name}"
# Fitter
quartus_fit "${quartus_project_name}"
# Assembler
quartus_asm "${quartus_project_name}"
#ddr3_pin_assignment_script="$(find . -name "hps_sdram_p0_pin_assignments.tcl")"
#quartus_sta -t "${ddr3_pin_assignment_script}" "${quartus_project_name}"
quartus_sta "${quartus_project_name}"
# convert .sof to .rbf in associated sdcard directory
quartus_cpf -c "${quartus_sof_file}" "${sdcard_fat32_rbf_file}"
# change working directory back to script directory
popd
}
# compile_preloader() ##########################################################
compile_preloader() {
# delete old artifacts
rm -rf "${preloader_dir}" \
"${sdcard_a2_preloader_bin_file}"
# create directory for preloader
mkdir -p "${preloader_dir}"
# change working directory to preloader directory
pushd "${preloader_dir}"
# create bsp settings file
bsp-create-settings \
--bsp-dir "${preloader_dir}" \
--preloader-settings-dir "${preloader_settings_dir}" \
--settings "${preloader_settings_file}" \
--type spl \
--set spl.CROSS_COMPILE "arm-altera-eabi-" \
--set spl.PRELOADER_TGZ "${preloader_source_tgz_file}" \
--set spl.boot.BOOTROM_HANDSHAKE_CFGIO "1" \
--set spl.boot.BOOT_FROM_NAND "0" \
--set spl.boot.BOOT_FROM_QSPI "0" \
--set spl.boot.BOOT_FROM_RAM "0" \
--set spl.boot.BOOT_FROM_SDMMC "1" \
--set spl.boot.CHECKSUM_NEXT_IMAGE "1" \
--set spl.boot.EXE_ON_FPGA "0" \
--set spl.boot.FAT_BOOT_PARTITION "1" \
--set spl.boot.FAT_LOAD_PAYLOAD_NAME "$(basename "${uboot_img_file}")" \
--set spl.boot.FAT_SUPPORT "1" \
--set spl.boot.FPGA_DATA_BASE "0xffff0000" \
--set spl.boot.FPGA_DATA_MAX_SIZE "0x10000" \
--set spl.boot.FPGA_MAX_SIZE "0x10000" \
--set spl.boot.NAND_NEXT_BOOT_IMAGE "0xc0000" \
--set spl.boot.QSPI_NEXT_BOOT_IMAGE "0x60000" \
--set spl.boot.RAMBOOT_PLLRESET "1" \
--set spl.boot.SDMMC_NEXT_BOOT_IMAGE "0x40000" \
--set spl.boot.SDRAM_SCRUBBING "0" \
--set spl.boot.SDRAM_SCRUB_BOOT_REGION_END "0x2000000" \
--set spl.boot.SDRAM_SCRUB_BOOT_REGION_START "0x1000000" \
--set spl.boot.SDRAM_SCRUB_REMAIN_REGION "1" \
--set spl.boot.STATE_REG_ENABLE "1" \
--set spl.boot.WARMRST_SKIP_CFGIO "1" \
--set spl.boot.WATCHDOG_ENABLE "1" \
--set spl.debug.DEBUG_MEMORY_ADDR "0xfffffd00" \
--set spl.debug.DEBUG_MEMORY_SIZE "0x200" \
--set spl.debug.DEBUG_MEMORY_WRITE "0" \
--set spl.debug.HARDWARE_DIAGNOSTIC "0" \
--set spl.debug.SEMIHOSTING "0" \
--set spl.debug.SKIP_SDRAM "0" \
--set spl.performance.SERIAL_SUPPORT "1" \
--set spl.reset_assert.DMA "0" \
--set spl.reset_assert.GPIO0 "0" \
--set spl.reset_assert.GPIO1 "0" \
--set spl.reset_assert.GPIO2 "0" \
--set spl.reset_assert.L4WD1 "0" \
--set spl.reset_assert.OSC1TIMER1 "0" \
--set spl.reset_assert.SDR "0" \
--set spl.reset_assert.SPTIMER0 "0" \
--set spl.reset_assert.SPTIMER1 "0" \
--set spl.warm_reset_handshake.ETR "1" \
--set spl.warm_reset_handshake.FPGA "1" \
--set spl.warm_reset_handshake.SDRAM "0"
# generate bsp
bsp-generate-files \
--bsp-dir "${preloader_dir}" \
--settings "${preloader_settings_file}"
# compile preloader
make -j4
# copy artifacts to associated sdcard directory
cp "${preloader_bin_file}" "${sdcard_a2_preloader_bin_file}"
# change working directory back to script directory
popd
}
# compile_uboot ################################################################
compile_uboot() {
# delete old artifacts
rm -rf "${sdcard_fat32_uboot_scr_file}" \
"${sdcard_fat32_uboot_img_file}"
# if uboot source tree doesn't exist, then download it
if [ ! -d "${uboot_src_dir}" ]; then
git clone "${uboot_src_git_repo}" "${uboot_src_dir}"
fi
# change working directory to uboot source tree directory
pushd "${uboot_src_dir}"
# use cross compiler instead of standard x86 version of gcc
export CROSS_COMPILE=arm-linux-gnueabihf-
# clean up source tree
make distclean
# checkout the following commit (tested and working):
git checkout "${uboot_src_git_checkout_commit}"
# configure uboot for socfpga_cyclone5 architecture
make "${uboot_src_make_config_file}"
## patch the uboot configuration file that describes environment variables
# replace value of CONFIG_BOOTCOMMAND macro (we will always use a script for configuring everything)
# result:
# #define CONFIG_BOOTCOMMAND "run callscript"
perl -pi -e 's/^(#define\s+CONFIG_BOOTCOMMAND)(.*)/$1\t"run callscript"/g' "${uboot_src_config_file}"
# replace value of CONFIG_EXTRA_ENV_SETTINGS macro
# result:
# #define CONFIG_EXTRA_ENV_SETTINGS \
# "scriptfile=u-boot.scr" "\0" \
# "fpgadata=0x2000000" "\0" \
# "callscript=fatload mmc 0:1 $fpgadata $scriptfile;" \
# "source $fpgadata" "\0"
perl -pi -e 'BEGIN{undef $/;} s/^(#define\s+CONFIG_EXTRA_ENV_SETTINGS)(.*)#include/$1\t"scriptfile=u-boot.scr\\0" "fpgadata=0x2000000\\0" "callscript=fatload mmc 0:1 \$fpgadata \$scriptfile; source \$fpgadata\\0"\n\n#include/smg' "${uboot_src_config_file}"
# compile uboot
make -j4
# create uboot script
cat <<EOF > "${uboot_script_file}"
################################################################################
echo --- Resetting Env variables ---
# reset environment variables to default
env default -a
echo --- Setting Env variables ---
# Set the kernel image
setenv bootimage $(basename ${sdcard_fat32_zImage_file});
# address to which the device tree will be loaded
setenv fdtaddr 0x00000100
# Set the devicetree image
setenv fdtimage $(basename ${sdcard_fat32_dtb_file});
# set kernel boot arguments, then boot the kernel
setenv mmcboot 'setenv bootargs mem=${linux_kernel_mem_arg} console=ttyS0,115200 root=\${mmcroot} rw rootwait; \
bootz \${loadaddr} - \${fdtaddr}';
# load linux kernel image and device tree to memory
setenv mmcload 'mmc rescan; \
\${mmcloadcmd} mmc 0:\${mmcloadpart} \${loadaddr} \${bootimage}; \
\${mmcloadcmd} mmc 0:\${mmcloadpart} \${fdtaddr} \${fdtimage}'
# command to be executed to read from sdcard
setenv mmcloadcmd fatload
# sdcard fat32 partition number
setenv mmcloadpart ${sdcard_partition_number_fat32}
# sdcard ext3 identifier
setenv mmcroot /dev/mmcblk0p${sdcard_partition_number_ext3}
# standard input/output
setenv stderr serial
setenv stdin serial
setenv stdout serial
# save environment to sdcard (not needed, but useful to avoid CRC errors on a new sdcard)
saveenv
################################################################################
echo --- Programming FPGA ---
# load rbf from FAT partition into memory
fatload mmc 0:1 \${fpgadata} $(basename ${sdcard_fat32_rbf_file});
# program FPGA
fpga load 0 \${fpgadata} \${filesize};
# enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges
bridge enable;
################################################################################
echo --- Booting Linux ---
# load linux kernel image and device tree to memory
run mmcload;
# set kernel boot arguments, then boot the kernel
run mmcboot;
EOF
# compile uboot script to binary form
mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "${quartus_project_name}" -d "${uboot_script_file}" "${sdcard_fat32_uboot_scr_file}"
# copy artifacts to associated sdcard directory
cp "${uboot_img_file}" "${sdcard_fat32_uboot_img_file}"
# change working directory back to script directory
popd
}
# compile_linux() ##############################################################
compile_linux() {
# if linux source tree doesn't exist, then download it
if [ ! -d "${linux_src_dir}" ]; then
git clone "${linux_src_git_repo}" "${linux_src_dir}"
fi
# change working directory to linux source tree directory
pushd "${linux_src_dir}"
# compile for the ARM architecture
export ARCH=arm
# use cross compiler instead of standard x86 version of gcc
export CROSS_COMPILE=arm-linux-gnueabihf-
# clean up source tree
make distclean
# checkout the following commit (tested and working):
git checkout "${linux_src_git_checkout_commit}"
# configure kernel for socfpga architecture
make "${linux_src_make_config_file}"
# compile zImage
make -j4 zImage
# compile device tree
make -j4 "$(basename "${linux_dtb_file}")"
# copy artifacts to associated sdcard directory
cp "${linux_zImage_file}" "${sdcard_fat32_zImage_file}"
cp "${linux_dtb_file}" "${sdcard_fat32_dtb_file}"
# change working directory back to script directory
popd
}
# create_rootfs() ##############################################################
create_rootfs() {
# if rootfs tarball doesn't exist, then download it
if [ ! -f "${rootfs_src_tgz_file}" ]; then
wget "${rootfs_src_tgz_link}" -O "${rootfs_src_tgz_file}"
fi
# delete old artifacts
sudo rm -rf "${rootfs_chroot_dir}" \
"${sdcard_ext3_rootfs_tgz_file}"
# create dir to extract rootfs
mkdir -p "${rootfs_chroot_dir}"
# extract ubuntu core rootfs
pushd "${rootfs_chroot_dir}"
sudo tar -xzpf "${rootfs_src_tgz_file}"
popd
# copy chroot SYSTEM configuration script to chroot directory
sudo cp "${rootfs_system_config_script_file}" "${rootfs_chroot_dir}"
# edit chroot environment's /etc/rc.local to execute the rootfs
# configuration script
sudo tee "${rootfs_chroot_dir}/etc/rc.local" > "/dev/null" <<EOF
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
/$(basename ${rootfs_system_config_script_file})
exit 0
EOF
# copy chroot POST-INSTALL configuration script to chroot directory
sudo cp "${rootfs_post_install_config_script_file}" "${rootfs_chroot_dir}"
# create archive of updated rootfs
pushd "${rootfs_chroot_dir}"
sudo tar -czpf "${sdcard_ext3_rootfs_tgz_file}" .
popd
}
# partition_sdcard() ###########################################################
partition_sdcard() {
# manually partitioning the sdcard
# sudo fdisk /dev/sdx
# use the following commands
# n p 3 <default> 4095 t a2 (2048 is default first sector)
# n p 1 <default> +32M t 1 b (4096 is default first sector)
# n p 2 <default> +512M t 2 83 (69632 is default first sector)
# w
# result
# Device Boot Start End Sectors Size Id Type
# /dev/sdb1 4096 69631 65536 32M b W95 FAT32
# /dev/sdb2 69632 1118207 1048576 512M 83 Linux
# /dev/sdb3 2048 4095 2048 1M a2 unknown
# note that you can choose any size for the FAT32 and Linux partitions,
# but the a2 partition must be 1M.
# automatically partitioning the sdcard
# wipe partition table
sudo dd if="/dev/zero" of="${sdcard_dev}" bs=512 count=1
# create partitions
# no need to specify the partition number for the first invocation of
# the "t" command in fdisk, because there is only 1 partition at this
# point
echo -e "n\np\n3\n\n4095\nt\na2\nn\np\n1\n\n+${sdcard_partition_size_fat32}\nt\n1\nb\nn\np\n2\n\n+${sdcard_partition_size_linux}\nt\n2\n83\nw\nq\n" | sudo fdisk "${sdcard_dev}"
# create filesystems
sudo mkfs.vfat "${sdcard_dev_fat32}"
sudo mkfs.ext3 -F "${sdcard_dev_ext3}"
}
# write_sdcard() ###############################################################
write_sdcard() {
# create mount point for sdcard
mkdir -p "${sdcard_dev_fat32_mount_point}"
mkdir -p "${sdcard_dev_ext3_mount_point}"
# mount sdcard partitions
sudo mount "${sdcard_dev_fat32}" "${sdcard_dev_fat32_mount_point}"
sudo mount "${sdcard_dev_ext3}" "${sdcard_dev_ext3_mount_point}"
# preloader
sudo dd if="${sdcard_a2_preloader_bin_file}" of="${sdcard_dev_a2}" bs=64K seek=0
# fpga .rbf, uboot .img, uboot .scr, linux zImage, linux .dtb
sudo cp "${sdcard_fat32_dir}"/* "${sdcard_dev_fat32_mount_point}"
# linux rootfs
pushd "${sdcard_dev_ext3_mount_point}"
sudo tar -xzf "${sdcard_ext3_rootfs_tgz_file}"
popd
# flush write buffers to target
sudo sync
# unmount sdcard partitions
sudo umount "${sdcard_dev_fat32_mount_point}"
sudo umount "${sdcard_dev_ext3_mount_point}"
# delete mount points for sdcard
rm -rf "${sdcard_dev_fat32_mount_point}"
rm -rf "${sdcard_dev_ext3_mount_point}"
}
# Script execution #############################################################
# Report script line number on any error (non-zero exit code).
trap 'echo "Error on line ${LINENO}" 1>&2' ERR
set -e
# Create sdcard output directories
mkdir -p "${sdcard_a2_dir}"
mkdir -p "${sdcard_fat32_dir}"
compile_quartus_project
compile_preloader
compile_uboot
compile_linux
create_rootfs
# Write sdcard if it exists
if [ -z "${sdcard_dev}" ]; then
echo "sdcard argument not provided => no sdcard written."
elif [ -b "${sdcard_dev}" ]; then
partition_sdcard
write_sdcard
fi
# Make sure MSEL = 000000

View File

@@ -0,0 +1,330 @@
-- #############################################################################
-- DE0_Nano_SoC_PrSoC_extn_board_top_level.vhd
--
-- BOARD : PrSoC extension board for DE0-Nano-SoC
-- Author : Florian Depraz based on Sahand Kashani-Akhavan work
-- Revision : 1.1
-- Creation date : 06/02/2016
--
-- Syntax Rule : GROUP_NAME_N[bit]
--
-- GROUP : specify a particular interface (ex: SDR_)
-- NAME : signal name (ex: CONFIG, D, ...)
-- bit : signal index
-- _N : to specify an active-low signal
-- #############################################################################
library ieee;
use ieee.std_logic_1164.all;
entity DE0_Nano_SoC_PrSoC_extn_board_top_level is
port(
-------------------------------
-- Comment ALL unused ports. --
-------------------------------
-- CLOCK
FPGA_CLK1_50 : in std_logic;
-- FPGA_CLK2_50 : in std_logic;
-- FPGA_CLK3_50 : in std_logic;
-- KEY on DE0 Nano SoC
KEY_N : in std_logic_vector(1 downto 0);
-- LEDs on DE0 Nano SoC
-- LED : out std_logic_vector(7 downto 0);
-- SWITCHES on DE0 Nano SoC
-- SW : in std_logic_vector(3 downto 0);
-- Servomotors pwm
SERVO_0 : out std_logic;
SERVO_1 : out std_logic;
-- ADC Joysticks
J0_SPI_CS_n : out std_logic;
J0_SPI_MOSI : out std_logic;
J0_SPI_MISO : in std_logic;
J0_SPI_CLK : out std_logic;
-- Lepton
CAM_TH_SPI_CS_N : out std_logic;
CAM_TH_MISO : in std_logic;
CAM_TH_MOSI : out std_logic;
CAM_TH_CLK : out std_logic;
-- PCA9637
-- PIO_SCL : inout std_logic;
-- PIO_SDA : inout std_logic;
-- PIO_INT_N : in std_logic;
-- RESET_N : out std_logic;
-- OV7670
-- CAM_D : in std_logic_vector(9 downto 0);
-- CAM_PIX_CLK : in std_logic;
-- CAM_LV : in std_logic;
-- CAM_FV : in std_logic;
-- CAM_SYS_CLK : out std_logic;
-- VGA and LCD shared signals
-- VIDEO_CLK : out std_logic;
-- VIDEO_VSYNC : out std_logic;
-- VIDEO_HSYNC : out std_logic;
-- VIDEO_B : out std_logic_vector(7 downto 0);
-- VIDEO_G : out std_logic_vector(7 downto 0);
-- VIDEO_R : out std_logic_vector(7 downto 0);
-- LCD Specific signals
-- LCD_DE : out std_logic;
-- LCD_PIN_DAV_N : ? ?? std_logic;
-- LCD_DISPLAY_EN : out std_logic;
-- SPI_MISO : in std_logic;
-- SPI_ENA_N : out std_logic;
-- SPI_CLK : out std_logic;
-- SPI_MOSI : out std_logic;
-- SPI_DAT : inout std_logic;
-- I2C TOUCH SCREEN
-- TS_SCL : inout std_logic;
-- TS_SDA : inout std_logic;
-- BLUETOOTH (BLE)
-- BLT_TXD : in std_logic;
-- BLT_RXD : out std_logic;
-- I2C For VGA, PAL and OV7670 cameras
-- CAM_PAL_VGA_SDA : inout std_logic;
-- CAM_PAL_VGA_SCL : inout std_logic;
-- ONE WIRE
-- BOARD_ID : inout std_logic;
-- PAL Camera
-- PAL_VD_VD : in std_logic_vector(7 downto 0);
-- PAL_VD_VSO : in std_logic;
-- PAL_VD_HSO : in std_logic;
-- PAL_VD_CLKO : in std_logic;
-- PAL_PWDN : out std_logic;
-- WIFI
-- FROM_ESP_TXD : in std_logic;
-- TO_ESP_RXD : out std_logic;
-- LED RGB
-- LED_BGR : out std_logic;
-- HPS
HPS_CONV_USB_N : inout std_logic;
HPS_DDR3_ADDR : out std_logic_vector(14 downto 0);
HPS_DDR3_BA : out std_logic_vector(2 downto 0);
HPS_DDR3_CAS_N : out std_logic;
HPS_DDR3_CK_N : out std_logic;
HPS_DDR3_CK_P : out std_logic;
HPS_DDR3_CKE : out std_logic;
HPS_DDR3_CS_N : out std_logic;
HPS_DDR3_DM : out std_logic_vector(3 downto 0);
HPS_DDR3_DQ : inout std_logic_vector(31 downto 0);
HPS_DDR3_DQS_N : inout std_logic_vector(3 downto 0);
HPS_DDR3_DQS_P : inout std_logic_vector(3 downto 0);
HPS_DDR3_ODT : out std_logic;
HPS_DDR3_RAS_N : out std_logic;
HPS_DDR3_RESET_N : out std_logic;
HPS_DDR3_RZQ : in std_logic;
HPS_DDR3_WE_N : out std_logic;
HPS_ENET_GTX_CLK : out std_logic;
HPS_ENET_INT_N : inout std_logic;
HPS_ENET_MDC : out std_logic;
HPS_ENET_MDIO : inout std_logic;
HPS_ENET_RX_CLK : in std_logic;
HPS_ENET_RX_DATA : in std_logic_vector(3 downto 0);
HPS_ENET_RX_DV : in std_logic;
HPS_ENET_TX_DATA : out std_logic_vector(3 downto 0);
HPS_ENET_TX_EN : out std_logic;
HPS_GSENSOR_INT : inout std_logic;
HPS_I2C0_SCLK : inout std_logic;
HPS_I2C0_SDAT : inout std_logic;
HPS_I2C1_SCLK : inout std_logic;
HPS_I2C1_SDAT : inout std_logic;
HPS_KEY_N : inout std_logic;
-- HPS_LED : inout std_logic;
HPS_LTC_GPIO : inout std_logic;
HPS_SD_CLK : out std_logic;
HPS_SD_CMD : inout std_logic;
HPS_SD_DATA : inout std_logic_vector(3 downto 0);
HPS_SPIM_CLK : out std_logic;
HPS_SPIM_MISO : in std_logic;
HPS_SPIM_MOSI : out std_logic;
HPS_SPIM_SS : inout std_logic;
HPS_UART_RX : in std_logic;
HPS_UART_TX : out std_logic;
HPS_USB_CLKOUT : in std_logic;
HPS_USB_DATA : inout std_logic_vector(7 downto 0);
HPS_USB_DIR : in std_logic;
HPS_USB_NXT : in std_logic;
HPS_USB_STP : out std_logic
);
end entity DE0_Nano_SoC_PrSoC_extn_board_top_level;
architecture rtl of DE0_Nano_SoC_PrSoC_extn_board_top_level is
component soc_system is
port (
clk_clk : in std_logic := 'X'; -- clk
hps_0_ddr_mem_a : out std_logic_vector(14 downto 0); -- mem_a
hps_0_ddr_mem_ba : out std_logic_vector(2 downto 0); -- mem_ba
hps_0_ddr_mem_ck : out std_logic; -- mem_ck
hps_0_ddr_mem_ck_n : out std_logic; -- mem_ck_n
hps_0_ddr_mem_cke : out std_logic; -- mem_cke
hps_0_ddr_mem_cs_n : out std_logic; -- mem_cs_n
hps_0_ddr_mem_ras_n : out std_logic; -- mem_ras_n
hps_0_ddr_mem_cas_n : out std_logic; -- mem_cas_n
hps_0_ddr_mem_we_n : out std_logic; -- mem_we_n
hps_0_ddr_mem_reset_n : out std_logic; -- mem_reset_n
hps_0_ddr_mem_dq : inout std_logic_vector(31 downto 0) := (others => 'X'); -- mem_dq
hps_0_ddr_mem_dqs : inout std_logic_vector(3 downto 0) := (others => 'X'); -- mem_dqs
hps_0_ddr_mem_dqs_n : inout std_logic_vector(3 downto 0) := (others => 'X'); -- mem_dqs_n
hps_0_ddr_mem_odt : out std_logic; -- mem_odt
hps_0_ddr_mem_dm : out std_logic_vector(3 downto 0); -- mem_dm
hps_0_ddr_oct_rzqin : in std_logic := 'X'; -- oct_rzqin
hps_0_io_hps_io_emac1_inst_TX_CLK : out std_logic; -- hps_io_emac1_inst_TX_CLK
hps_0_io_hps_io_emac1_inst_TXD0 : out std_logic; -- hps_io_emac1_inst_TXD0
hps_0_io_hps_io_emac1_inst_TXD1 : out std_logic; -- hps_io_emac1_inst_TXD1
hps_0_io_hps_io_emac1_inst_TXD2 : out std_logic; -- hps_io_emac1_inst_TXD2
hps_0_io_hps_io_emac1_inst_TXD3 : out std_logic; -- hps_io_emac1_inst_TXD3
hps_0_io_hps_io_emac1_inst_RXD0 : in std_logic := 'X'; -- hps_io_emac1_inst_RXD0
hps_0_io_hps_io_emac1_inst_MDIO : inout std_logic := 'X'; -- hps_io_emac1_inst_MDIO
hps_0_io_hps_io_emac1_inst_MDC : out std_logic; -- hps_io_emac1_inst_MDC
hps_0_io_hps_io_emac1_inst_RX_CTL : in std_logic := 'X'; -- hps_io_emac1_inst_RX_CTL
hps_0_io_hps_io_emac1_inst_TX_CTL : out std_logic; -- hps_io_emac1_inst_TX_CTL
hps_0_io_hps_io_emac1_inst_RX_CLK : in std_logic := 'X'; -- hps_io_emac1_inst_RX_CLK
hps_0_io_hps_io_emac1_inst_RXD1 : in std_logic := 'X'; -- hps_io_emac1_inst_RXD1
hps_0_io_hps_io_emac1_inst_RXD2 : in std_logic := 'X'; -- hps_io_emac1_inst_RXD2
hps_0_io_hps_io_emac1_inst_RXD3 : in std_logic := 'X'; -- hps_io_emac1_inst_RXD3
hps_0_io_hps_io_sdio_inst_CMD : inout std_logic := 'X'; -- hps_io_sdio_inst_CMD
hps_0_io_hps_io_sdio_inst_D0 : inout std_logic := 'X'; -- hps_io_sdio_inst_D0
hps_0_io_hps_io_sdio_inst_D1 : inout std_logic := 'X'; -- hps_io_sdio_inst_D1
hps_0_io_hps_io_sdio_inst_CLK : out std_logic; -- hps_io_sdio_inst_CLK
hps_0_io_hps_io_sdio_inst_D2 : inout std_logic := 'X'; -- hps_io_sdio_inst_D2
hps_0_io_hps_io_sdio_inst_D3 : inout std_logic := 'X'; -- hps_io_sdio_inst_D3
hps_0_io_hps_io_usb1_inst_D0 : inout std_logic := 'X'; -- hps_io_usb1_inst_D0
hps_0_io_hps_io_usb1_inst_D1 : inout std_logic := 'X'; -- hps_io_usb1_inst_D1
hps_0_io_hps_io_usb1_inst_D2 : inout std_logic := 'X'; -- hps_io_usb1_inst_D2
hps_0_io_hps_io_usb1_inst_D3 : inout std_logic := 'X'; -- hps_io_usb1_inst_D3
hps_0_io_hps_io_usb1_inst_D4 : inout std_logic := 'X'; -- hps_io_usb1_inst_D4
hps_0_io_hps_io_usb1_inst_D5 : inout std_logic := 'X'; -- hps_io_usb1_inst_D5
hps_0_io_hps_io_usb1_inst_D6 : inout std_logic := 'X'; -- hps_io_usb1_inst_D6
hps_0_io_hps_io_usb1_inst_D7 : inout std_logic := 'X'; -- hps_io_usb1_inst_D7
hps_0_io_hps_io_usb1_inst_CLK : in std_logic := 'X'; -- hps_io_usb1_inst_CLK
hps_0_io_hps_io_usb1_inst_STP : out std_logic; -- hps_io_usb1_inst_STP
hps_0_io_hps_io_usb1_inst_DIR : in std_logic := 'X'; -- hps_io_usb1_inst_DIR
hps_0_io_hps_io_usb1_inst_NXT : in std_logic := 'X'; -- hps_io_usb1_inst_NXT
hps_0_io_hps_io_spim1_inst_CLK : out std_logic; -- hps_io_spim1_inst_CLK
hps_0_io_hps_io_spim1_inst_MOSI : out std_logic; -- hps_io_spim1_inst_MOSI
hps_0_io_hps_io_spim1_inst_MISO : in std_logic := 'X'; -- hps_io_spim1_inst_MISO
hps_0_io_hps_io_spim1_inst_SS0 : out std_logic; -- hps_io_spim1_inst_SS0
hps_0_io_hps_io_uart0_inst_RX : in std_logic := 'X'; -- hps_io_uart0_inst_RX
hps_0_io_hps_io_uart0_inst_TX : out std_logic; -- hps_io_uart0_inst_TX
hps_0_io_hps_io_i2c0_inst_SDA : inout std_logic := 'X'; -- hps_io_i2c0_inst_SDA
hps_0_io_hps_io_i2c0_inst_SCL : inout std_logic := 'X'; -- hps_io_i2c0_inst_SCL
hps_0_io_hps_io_i2c1_inst_SDA : inout std_logic := 'X'; -- hps_io_i2c1_inst_SDA
hps_0_io_hps_io_i2c1_inst_SCL : inout std_logic := 'X'; -- hps_io_i2c1_inst_SCL
hps_0_io_hps_io_gpio_inst_GPIO09 : inout std_logic := 'X'; -- hps_io_gpio_inst_GPIO09
hps_0_io_hps_io_gpio_inst_GPIO35 : inout std_logic := 'X'; -- hps_io_gpio_inst_GPIO35
hps_0_io_hps_io_gpio_inst_GPIO40 : inout std_logic := 'X'; -- hps_io_gpio_inst_GPIO40
hps_0_io_hps_io_gpio_inst_GPIO54 : inout std_logic := 'X'; -- hps_io_gpio_inst_GPIO54
hps_0_io_hps_io_gpio_inst_GPIO61 : inout std_logic := 'X'; -- hps_io_gpio_inst_GPIO61
lepton_0_spi_cs_n : out std_logic; -- cs_n
lepton_0_spi_miso : in std_logic := 'X'; -- miso
lepton_0_spi_mosi : out std_logic; -- mosi
lepton_0_spi_sclk : out std_logic; -- sclk
mcp3204_0_conduit_end_cs_n : out std_logic; -- cs_n
mcp3204_0_conduit_end_mosi : out std_logic; -- mosi
mcp3204_0_conduit_end_miso : in std_logic := 'X'; -- miso
mcp3204_0_conduit_end_sclk : out std_logic; -- sclk
pwm_0_conduit_end_pwm : out std_logic; -- pwm
pwm_1_conduit_end_pwm : out std_logic; -- pwm
reset_reset_n : in std_logic := 'X' -- reset_n
);
end component soc_system;
begin
u0 : component soc_system
port map (
clk_clk => FPGA_CLK1_50, -- clk.clk
hps_0_ddr_mem_a => HPS_DDR3_ADDR, -- hps_0_ddr.mem_a
hps_0_ddr_mem_ba => HPS_DDR3_BA, -- .mem_ba
hps_0_ddr_mem_ck => HPS_DDR3_CK_P, -- .mem_ck
hps_0_ddr_mem_ck_n => HPS_DDR3_CK_N, -- .mem_ck_n
hps_0_ddr_mem_cke => HPS_DDR3_CKE, -- .mem_cke
hps_0_ddr_mem_cs_n => HPS_DDR3_CS_N, -- .mem_cs_n
hps_0_ddr_mem_ras_n => HPS_DDR3_RAS_N, -- .mem_ras_n
hps_0_ddr_mem_cas_n => HPS_DDR3_CAS_N, -- .mem_cas_n
hps_0_ddr_mem_we_n => HPS_DDR3_WE_N, -- .mem_we_n
hps_0_ddr_mem_reset_n => HPS_DDR3_RESET_N, -- .mem_reset_n
hps_0_ddr_mem_dq => HPS_DDR3_DQ, -- .mem_dq
hps_0_ddr_mem_dqs => HPS_DDR3_DQS_P, -- .mem_dqs
hps_0_ddr_mem_dqs_n => HPS_DDR3_DQS_N, -- .mem_dqs_n
hps_0_ddr_mem_odt => HPS_DDR3_ODT, -- .mem_odt
hps_0_ddr_mem_dm => HPS_DDR3_DM, -- .mem_dm
hps_0_ddr_oct_rzqin => HPS_DDR3_RZQ, -- .oct_rzqin
hps_0_io_hps_io_emac1_inst_TX_CLK => HPS_ENET_GTX_CLK, -- hps_0_io.hps_io_emac1_inst_TX_CLK
hps_0_io_hps_io_emac1_inst_TXD0 => HPS_ENET_TX_DATA(0), -- .hps_io_emac1_inst_TXD0
hps_0_io_hps_io_emac1_inst_TXD1 => HPS_ENET_TX_DATA(1), -- .hps_io_emac1_inst_TXD1
hps_0_io_hps_io_emac1_inst_TXD2 => HPS_ENET_TX_DATA(2), -- .hps_io_emac1_inst_TXD2
hps_0_io_hps_io_emac1_inst_TXD3 => HPS_ENET_TX_DATA(3), -- .hps_io_emac1_inst_TXD3
hps_0_io_hps_io_emac1_inst_RXD0 => HPS_ENET_RX_DATA(0), -- .hps_io_emac1_inst_RXD0
hps_0_io_hps_io_emac1_inst_MDIO => HPS_ENET_MDIO, -- .hps_io_emac1_inst_MDIO
hps_0_io_hps_io_emac1_inst_MDC => HPS_ENET_MDC, -- .hps_io_emac1_inst_MDC
hps_0_io_hps_io_emac1_inst_RX_CTL => HPS_ENET_RX_DV, -- .hps_io_emac1_inst_RX_CTL
hps_0_io_hps_io_emac1_inst_TX_CTL => HPS_ENET_TX_EN, -- .hps_io_emac1_inst_TX_CTL
hps_0_io_hps_io_emac1_inst_RX_CLK => HPS_ENET_RX_CLK, -- .hps_io_emac1_inst_RX_CLK
hps_0_io_hps_io_emac1_inst_RXD1 => HPS_ENET_RX_DATA(1), -- .hps_io_emac1_inst_RXD1
hps_0_io_hps_io_emac1_inst_RXD2 => HPS_ENET_RX_DATA(2), -- .hps_io_emac1_inst_RXD2
hps_0_io_hps_io_emac1_inst_RXD3 => HPS_ENET_RX_DATA(3), -- .hps_io_emac1_inst_RXD3
hps_0_io_hps_io_sdio_inst_CMD => HPS_SD_CMD, -- .hps_io_sdio_inst_CMD
hps_0_io_hps_io_sdio_inst_D0 => HPS_SD_DATA(0), -- .hps_io_sdio_inst_D0
hps_0_io_hps_io_sdio_inst_D1 => HPS_SD_DATA(1), -- .hps_io_sdio_inst_D1
hps_0_io_hps_io_sdio_inst_CLK => HPS_SD_CLK, -- .hps_io_sdio_inst_CLK
hps_0_io_hps_io_sdio_inst_D2 => HPS_SD_DATA(2), -- .hps_io_sdio_inst_D2
hps_0_io_hps_io_sdio_inst_D3 => HPS_SD_DATA(3), -- .hps_io_sdio_inst_D3
hps_0_io_hps_io_usb1_inst_D0 => HPS_USB_DATA(0), -- .hps_io_usb1_inst_D0
hps_0_io_hps_io_usb1_inst_D1 => HPS_USB_DATA(1), -- .hps_io_usb1_inst_D1
hps_0_io_hps_io_usb1_inst_D2 => HPS_USB_DATA(2), -- .hps_io_usb1_inst_D2
hps_0_io_hps_io_usb1_inst_D3 => HPS_USB_DATA(3), -- .hps_io_usb1_inst_D3
hps_0_io_hps_io_usb1_inst_D4 => HPS_USB_DATA(4), -- .hps_io_usb1_inst_D4
hps_0_io_hps_io_usb1_inst_D5 => HPS_USB_DATA(5), -- .hps_io_usb1_inst_D5
hps_0_io_hps_io_usb1_inst_D6 => HPS_USB_DATA(6), -- .hps_io_usb1_inst_D6
hps_0_io_hps_io_usb1_inst_D7 => HPS_USB_DATA(7), -- .hps_io_usb1_inst_D7
hps_0_io_hps_io_usb1_inst_CLK => HPS_USB_CLKOUT, -- .hps_io_usb1_inst_CLK
hps_0_io_hps_io_usb1_inst_STP => HPS_USB_STP, -- .hps_io_usb1_inst_STP
hps_0_io_hps_io_usb1_inst_DIR => HPS_USB_DIR, -- .hps_io_usb1_inst_DIR
hps_0_io_hps_io_usb1_inst_NXT => HPS_USB_NXT, -- .hps_io_usb1_inst_NXT
hps_0_io_hps_io_spim1_inst_CLK => HPS_SPIM_CLK, -- .hps_io_spim1_inst_CLK
hps_0_io_hps_io_spim1_inst_MOSI => HPS_SPIM_MOSI, -- .hps_io_spim1_inst_MOSI
hps_0_io_hps_io_spim1_inst_MISO => HPS_SPIM_MISO, -- .hps_io_spim1_inst_MISO
hps_0_io_hps_io_spim1_inst_SS0 => HPS_SPIM_SS, -- .hps_io_spim1_inst_SS0
hps_0_io_hps_io_uart0_inst_RX => HPS_UART_RX, -- .hps_io_uart0_inst_RX
hps_0_io_hps_io_uart0_inst_TX => HPS_UART_TX, -- .hps_io_uart0_inst_TX
hps_0_io_hps_io_i2c0_inst_SDA => HPS_I2C0_SDAT, -- .hps_io_i2c0_inst_SDA
hps_0_io_hps_io_i2c0_inst_SCL => HPS_I2C0_SCLK, -- .hps_io_i2c0_inst_SCL
hps_0_io_hps_io_i2c1_inst_SDA => HPS_I2C1_SDAT, -- .hps_io_i2c1_inst_SDA
hps_0_io_hps_io_i2c1_inst_SCL => HPS_I2C1_SCLK, -- .hps_io_i2c1_inst_SCL
hps_0_io_hps_io_gpio_inst_GPIO09 => HPS_CONV_USB_N, -- .hps_io_gpio_inst_GPIO09
hps_0_io_hps_io_gpio_inst_GPIO35 => HPS_ENET_INT_N, -- .hps_io_gpio_inst_GPIO35
hps_0_io_hps_io_gpio_inst_GPIO40 => HPS_LTC_GPIO, -- .hps_io_gpio_inst_GPIO40
hps_0_io_hps_io_gpio_inst_GPIO54 => HPS_KEY_N, -- .hps_io_gpio_inst_GPIO54
hps_0_io_hps_io_gpio_inst_GPIO61 => HPS_GSENSOR_INT, -- .hps_io_gpio_inst_GPIO61
lepton_0_spi_cs_n => CAM_TH_SPI_CS_N, -- lepton_0_spi.cs_n
lepton_0_spi_miso => CAM_TH_MISO, -- .miso
lepton_0_spi_mosi => CAM_TH_MOSI, -- .mosi
lepton_0_spi_sclk => CAM_TH_CLK, -- .sclk
mcp3204_0_conduit_end_cs_n => J0_SPI_CS_n, -- mcp3204_0_conduit_end.cs_n
mcp3204_0_conduit_end_mosi => J0_SPI_MOSI, -- .mosi
mcp3204_0_conduit_end_miso => J0_SPI_MISO, -- .miso
mcp3204_0_conduit_end_sclk => J0_SPI_CLK, -- .sclk
pwm_0_conduit_end_pwm => SERVO_0, -- pwm_0_conduit_end.pwm
pwm_1_conduit_end_pwm => SERVO_1, -- pwm_1_conduit_end.pwm
reset_reset_n => KEY_N(0) -- reset.reset_n
);
end;

View File

@@ -0,0 +1,138 @@
-- #############################################################################
-- mcp3204.vhd
-- ===========
-- MCP3204 Avalon-MM slave interface.
--
-- Register map
-- +-------+-----------+--------+------------------------------------+
-- | RegNo | Name | Access | Description |
-- +-------+-----------+--------+------------------------------------+
-- | 0 | CHANNEL_0 | RO | 12-bit digital value of channel 0. |
-- +-------+-----------+--------+------------------------------------+
-- | 1 | CHANNEL_1 | RO | 12-bit digital value of channel 1. |
-- +-------+-----------+--------+------------------------------------+
-- | 2 | CHANNEL_2 | RO | 12-bit digital value of channel 2. |
-- +-------+-----------+--------+------------------------------------+
-- | 3 | CHANNEL_3 | RO | 12-bit digital value of channel 3. |
-- +-------+-----------+--------+------------------------------------+
--
-- Author : Philémon Favrod [philemon.favrod@epfl.ch]
-- Author : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
-- Revision : 2
-- Last modified : 2018-03-06
-- #############################################################################
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity mcp3204 is
port(
-- Avalon Clock interface
clk : in std_logic;
-- Avalon Reset interface
reset : in std_logic;
-- Avalon-MM Slave interface
address : in std_logic_vector(1 downto 0);
read : in std_logic;
readdata : out std_logic_vector(31 downto 0);
-- Avalon Conduit interface
CS_N : out std_logic;
MOSI : out std_logic;
MISO : in std_logic;
SCLK : out std_logic
);
end entity;
architecture arch of mcp3204 is
constant NUM_CHANNELS : positive := 4;
constant CHANNEL_WIDTH : positive := integer(ceil(log2(real(NUM_CHANNELS))));
type data_array is array (NUM_CHANNELS - 1 downto 0) of std_logic_vector(readdata'range);
signal data_reg : data_array;
signal spi_busy, spi_start, spi_datavalid : std_logic;
signal spi_channel : std_logic_vector(1 downto 0);
signal spi_data : std_logic_vector(11 downto 0);
type state_t is (READY, INIT_READ_CHANNEL, WAIT_FOR_DATA);
signal state : state_t;
signal channel : unsigned(CHANNEL_WIDTH - 1 downto 0);
begin
SPI : entity work.mcp3204_spi
port map(
clk => clk,
reset => reset,
busy => spi_busy,
start => spi_start,
channel => spi_channel,
data_valid => spi_datavalid,
data => spi_data,
SCLK => SCLK,
CS_N => CS_N,
MOSI => MOSI,
MISO => MISO
);
-- FSM that dictates which channel is being read. The state of the component
-- should be thought as the pair (state, channel)
p_fsm : process(reset, clk)
begin
if reset = '1' then
state <= READY;
channel <= (others => '0');
elsif rising_edge(clk) then
case state is
when READY =>
if spi_busy = '0' then
state <= INIT_READ_CHANNEL;
end if;
when INIT_READ_CHANNEL =>
state <= WAIT_FOR_DATA;
when WAIT_FOR_DATA =>
if spi_datavalid = '1' then
state <= READY;
channel <= channel + 1;
end if;
end case;
end if;
end process p_fsm;
-- Updates the internal registers when a new data is available
p_data : process(reset, clk)
begin
if reset = '1' then
for i in 0 to NUM_CHANNELS - 1 loop
data_reg(i) <= (others => '0');
end loop;
elsif rising_edge(clk) then
if state = WAIT_FOR_DATA and spi_datavalid = '1' then
data_reg(to_integer(channel)) <= (31 downto 12 => '0') & spi_data;
end if;
end if;
end process p_data;
spi_start <= '1' when state = INIT_READ_CHANNEL else '0';
spi_channel <= std_logic_vector(channel);
-- Interface with the Avalon Switch Fabric
p_avalon_read : process(reset, clk)
begin
if reset = '1' then
readdata <= (others => '0');
elsif rising_edge(clk) then
if read = '1' then
readdata <= data_reg(to_integer(unsigned(address)));
end if;
end if;
end process p_avalon_read;
end architecture;

View File

@@ -0,0 +1,137 @@
# TCL File Generated by Component Editor 16.0
# Sun Feb 05 18:14:06 CET 2017
# DO NOT MODIFY
#
# mcp3204 "mcp3204" v1.0
# Philemon Favrod & Sahand Kashani-Akhavan 2017.02.05.18:14:06
# 4-Channel 12-Bit A/D Converter with SPI Serial Interface
#
#
# request TCL package from ACDS 16.0
#
package require -exact qsys 16.0
#
# module mcp3204
#
set_module_property DESCRIPTION "4-Channel 12-Bit A/D Converter with SPI Serial Interface"
set_module_property NAME mcp3204
set_module_property VERSION 1.0
set_module_property INTERNAL false
set_module_property OPAQUE_ADDRESS_MAP true
set_module_property GROUP Joystick
set_module_property AUTHOR "Philemon Favrod & Sahand Kashani-Akhavan"
set_module_property DISPLAY_NAME mcp3204
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
set_module_property EDITABLE true
set_module_property REPORT_TO_TALKBACK false
set_module_property ALLOW_GREYBOX_GENERATION false
set_module_property REPORT_HIERARCHY false
#
# file sets
#
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
set_fileset_property QUARTUS_SYNTH TOP_LEVEL mcp3204
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
add_fileset_file mcp3204.vhd VHDL PATH mcp3204.vhd TOP_LEVEL_FILE
add_fileset_file mcp3204_spi.vhd VHDL PATH mcp3204_spi.vhd
#
# parameters
#
#
# display items
#
#
# connection point clock
#
add_interface clock clock end
set_interface_property clock clockRate 0
set_interface_property clock ENABLED true
set_interface_property clock EXPORT_OF ""
set_interface_property clock PORT_NAME_MAP ""
set_interface_property clock CMSIS_SVD_VARIABLES ""
set_interface_property clock SVD_ADDRESS_GROUP ""
add_interface_port clock clk clk Input 1
#
# connection point reset
#
add_interface reset reset end
set_interface_property reset associatedClock clock
set_interface_property reset synchronousEdges DEASSERT
set_interface_property reset ENABLED true
set_interface_property reset EXPORT_OF ""
set_interface_property reset PORT_NAME_MAP ""
set_interface_property reset CMSIS_SVD_VARIABLES ""
set_interface_property reset SVD_ADDRESS_GROUP ""
add_interface_port reset reset reset Input 1
#
# connection point avalon_slave_0
#
add_interface avalon_slave_0 avalon end
set_interface_property avalon_slave_0 addressUnits WORDS
set_interface_property avalon_slave_0 associatedClock clock
set_interface_property avalon_slave_0 associatedReset reset
set_interface_property avalon_slave_0 bitsPerSymbol 8
set_interface_property avalon_slave_0 burstOnBurstBoundariesOnly false
set_interface_property avalon_slave_0 burstcountUnits WORDS
set_interface_property avalon_slave_0 explicitAddressSpan 0
set_interface_property avalon_slave_0 holdTime 0
set_interface_property avalon_slave_0 linewrapBursts false
set_interface_property avalon_slave_0 maximumPendingReadTransactions 0
set_interface_property avalon_slave_0 maximumPendingWriteTransactions 0
set_interface_property avalon_slave_0 readLatency 0
set_interface_property avalon_slave_0 readWaitTime 1
set_interface_property avalon_slave_0 setupTime 0
set_interface_property avalon_slave_0 timingUnits Cycles
set_interface_property avalon_slave_0 writeWaitTime 0
set_interface_property avalon_slave_0 ENABLED true
set_interface_property avalon_slave_0 EXPORT_OF ""
set_interface_property avalon_slave_0 PORT_NAME_MAP ""
set_interface_property avalon_slave_0 CMSIS_SVD_VARIABLES ""
set_interface_property avalon_slave_0 SVD_ADDRESS_GROUP ""
add_interface_port avalon_slave_0 address address Input 2
add_interface_port avalon_slave_0 read read Input 1
add_interface_port avalon_slave_0 readdata readdata Output 32
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isFlash 0
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isMemoryDevice 0
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isNonVolatileStorage 0
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isPrintableDevice 0
#
# connection point conduit_end
#
add_interface conduit_end conduit end
set_interface_property conduit_end associatedClock clock
set_interface_property conduit_end associatedReset ""
set_interface_property conduit_end ENABLED true
set_interface_property conduit_end EXPORT_OF ""
set_interface_property conduit_end PORT_NAME_MAP ""
set_interface_property conduit_end CMSIS_SVD_VARIABLES ""
set_interface_property conduit_end SVD_ADDRESS_GROUP ""
add_interface_port conduit_end CS_N cs_n Output 1
add_interface_port conduit_end MOSI mosi Output 1
add_interface_port conduit_end MISO miso Input 1
add_interface_port conduit_end SCLK sclk Output 1

View File

@@ -0,0 +1,87 @@
-- #############################################################################
-- mcp3204_spi.vhd
-- ===============
-- MCP3204 SPI interface.
--
-- Author : Philémon Favrod [philemon.favrod@epfl.ch]
-- Author : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
-- Author : <insert your name> (<insert your e-mail address>)
-- Revision : 1
-- Last modified : <insert date>
-- #############################################################################
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity mcp3204_spi is
port(
-- 50 MHz
clk : in std_logic;
reset : in std_logic;
busy : out std_logic;
start : in std_logic;
channel : in std_logic_vector(1 downto 0);
data_valid : out std_logic;
data : out std_logic_vector(11 downto 0);
-- 1 MHz
SCLK : out std_logic;
CS_N : out std_logic;
MOSI : out std_logic;
MISO : in std_logic
);
end mcp3204_spi;
architecture rtl of mcp3204_spi is
signal reg_clk_divider_counter : unsigned(4 downto 0) := (others => '0'); -- need to be able to count until 24
signal reg_spi_en : std_logic := '0'; -- pulses every 0.5 MHz
signal reg_rising_edge_sclk : std_logic := '0';
signal reg_falling_edge_sclk : std_logic := '0';
signal reg_sclk : std_logic := '0';
begin
clk_divider_generation : process(clk, reset)
begin
if reset = '1' then
reg_clk_divider_counter <= (others => '0');
elsif rising_edge(clk) then
reg_clk_divider_counter <= reg_clk_divider_counter + 1;
reg_spi_en <= '0';
reg_rising_edge_sclk <= '0';
reg_falling_edge_sclk <= '0';
if reg_clk_divider_counter = 24 then
reg_clk_divider_counter <= (others => '0');
reg_spi_en <= '1';
if reg_sclk = '0' then
reg_rising_edge_sclk <= '1';
elsif reg_sclk = '1' then
reg_falling_edge_sclk <= '1';
end if;
end if;
end if;
end process;
SCLK_generation : process(clk, reset)
begin
if reset = '1' then
reg_sclk <= '0';
elsif rising_edge(clk) then
if reg_spi_en = '1' then
reg_sclk <= not reg_sclk;
end if;
end if;
end process;
STATE_LOGIC : process(clk, reset)
begin
-- TODO: complete this process
if reset = '1' then
elsif rising_edge(clk) then
end if;
end process;
end architecture rtl;

View File

@@ -0,0 +1,103 @@
-- #############################################################################
-- tb_mcp3204_spi.vhd
-- ==================
-- Testbench for MCP3204 SPI interface.
--
-- Author : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
-- Revision : 1
-- Last modified : 2018-03-06
-- #############################################################################
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity tb_mcp3204_spi is
end entity;
architecture rtl of tb_mcp3204_spi is
constant CLK_PERIOD : time := 20 ns;
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal sim_finished : boolean := false;
-- mcp3204_spi ------------------------------------------------------------
signal busy : std_logic := '0';
signal start : std_logic := '0';
signal channel : std_logic_vector(1 downto 0) := (others => '0');
signal data_valid : std_logic := '0';
signal data : std_logic_vector(11 downto 0) := (others => '0');
signal SCLK : std_logic := '0';
signal CS_N : std_logic := '1';
signal MOSI : std_logic := '0';
signal MISO : std_logic := '0';
begin
duv : entity work.mcp3204_spi
port map(
clk => clk,
reset => reset,
busy => busy,
start => start,
channel => channel,
data_valid => data_valid,
data => data,
SCLK => SCLK,
CS_N => CS_N,
MOSI => MOSI,
MISO => MISO
);
clk <= not clk after CLK_PERIOD / 2 when not sim_finished;
sim : process
procedure async_reset is
begin
wait until rising_edge(clk);
wait for CLK_PERIOD / 4;
reset <= '1';
wait for CLK_PERIOD / 2;
reset <= '0';
end procedure async_reset;
procedure spi_transfer(constant channel_number : natural range 0 to 3) is
begin
if busy = '1' then
wait until busy = '0';
else
wait until falling_edge(clk);
start <= '1';
channel <= std_logic_vector(to_unsigned(channel_number, channel'length));
wait until falling_edge(clk);
start <= '0';
channel <= (others => '0');
wait until rising_edge(data_valid);
wait until falling_edge(busy);
end if;
end procedure spi_transfer;
begin
async_reset;
MISO <= '1';
spi_transfer(0);
MISO <= '0';
spi_transfer(1);
MISO <= '1';
spi_transfer(2);
MISO <= '0';
spi_transfer(3);
sim_finished <= true;
wait;
end process sim;
end architecture rtl;

View File

@@ -0,0 +1,139 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.utils.all;
entity avalon_st_spi_master is
generic(
INPUT_CLK_FREQ : integer := 50000000;
SPI_SCLK_FREQ : integer := 10000000;
CPOL : integer := 1;
CPHA : integer := 1
);
port(
-- Input clock
clk : in std_logic;
-- Reset
reset : in std_logic;
spi_cs_n : in std_logic;
-- Sink Avalon ST Interface
mosi_sink_data : in std_logic_vector(7 downto 0);
mosi_sink_valid : in std_logic;
mosi_sink_ready : out std_logic;
-- Source Avalon ST Interface
miso_src_data : out std_logic_vector(7 downto 0);
miso_src_valid : out std_logic;
-- SPI Master signals
SCLK : out std_logic;
MISO : in std_logic;
MOSI : out std_logic;
CS_n : out std_logic
);
end avalon_st_spi_master;
architecture rtl of avalon_st_spi_master is
constant SCLK_PRESCALER_MAX : integer := INPUT_CLK_FREQ / SPI_SCLK_FREQ / 2;
signal sclk_prescaler : unsigned(bitlength(SCLK_PRESCALER_MAX) downto 0);
signal sclk_toggle : std_logic;
signal new_sink_buffer, cur_sink_buffer : std_logic_vector(mosi_sink_data'range);
signal new_sink_buffer_busy, cur_sink_buffer_busy : std_logic;
signal miso_src_buffer : std_logic_vector(7 downto 0);
signal spi_done, i_sclk : std_logic;
signal spi_bit_index : unsigned(2 downto 0);
begin
CS_n <= spi_cs_n;
p_sclk_prescaler : process(clk, reset) is
begin
if reset = '1' then
sclk_prescaler <= to_unsigned(1, sclk_prescaler'length);
elsif rising_edge(clk) then
if sclk_prescaler = SCLK_PRESCALER_MAX then
sclk_prescaler <= to_unsigned(1, sclk_prescaler'length);
else
sclk_prescaler <= sclk_prescaler + 1;
end if;
end if;
end process p_sclk_prescaler;
sclk_toggle <= '1' when sclk_prescaler = SCLK_PRESCALER_MAX else '0';
p_avalon_st_sink : process(clk, reset) is
begin
if reset = '1' then
new_sink_buffer_busy <= '0';
new_sink_buffer <= (others => '0');
elsif rising_edge(clk) then
if mosi_sink_valid = '1' then
if new_sink_buffer_busy = '0' and cur_sink_buffer_busy = '1' then
new_sink_buffer <= mosi_sink_data;
new_sink_buffer_busy <= '1';
end if;
elsif new_sink_buffer_busy = '1' and cur_sink_buffer_busy = '0' then
new_sink_buffer_busy <= '0';
end if;
end if;
end process p_avalon_st_sink;
mosi_sink_ready <= not new_sink_buffer_busy;
p_cur_buffer : process(clk, reset) is
begin
if reset = '1' then
cur_sink_buffer <= (others => '0');
cur_sink_buffer_busy <= '0';
elsif rising_edge(clk) then
if mosi_sink_valid = '1' and cur_sink_buffer_busy = '0' then
cur_sink_buffer <= mosi_sink_data;
cur_sink_buffer_busy <= '1';
elsif cur_sink_buffer_busy = '0' and new_sink_buffer_busy = '1' then
cur_sink_buffer <= new_sink_buffer;
cur_sink_buffer_busy <= '1';
elsif cur_sink_buffer_busy = '1' and spi_done = '1' then
cur_sink_buffer_busy <= '0';
end if;
end if;
end process p_cur_buffer;
p_spi : process(clk, reset) is
begin
if reset = '1' then
spi_done <= '0';
i_sclk <= to_unsigned(CPOL, 1)(0);
spi_bit_index <= "000";
MOSI <= '0';
miso_src_data <= (others => '0');
miso_src_valid <= '0';
miso_src_buffer <= (others => '0');
elsif rising_edge(clk) then
spi_done <= '0';
miso_src_valid <= '0';
if cur_sink_buffer_busy = '1' and sclk_toggle = '1' then
if i_sclk /= to_unsigned(CPHA, 1)(0) then
if spi_bit_index = "111" then
spi_done <= '1';
spi_bit_index <= "000";
miso_src_valid <= '1';
miso_src_data <= miso_src_buffer(7 downto 1) & MISO;
else
MOSI <= cur_sink_buffer(7 - to_integer(spi_bit_index));
miso_src_buffer(7 - to_integer(spi_bit_index)) <= MISO;
spi_bit_index <= spi_bit_index + 1;
end if;
end if;
i_sclk <= not i_sclk;
end if;
end if;
end process p_spi;
SCLK <= i_sclk;
end rtl;

View File

@@ -0,0 +1,87 @@
-------------------------------------------------------------------------------
-- Title : Byte stream to pixel converter for the Lepton Camera
-- Project : PrSoC
-------------------------------------------------------------------------------
-- File : byte2pix.vhd
-- Author : Philemon Orphee Favrod <pofavrod@lappc5.epfl.ch>
-- Company :
-- Created : 2016-03-21
-- Last update: 2017-03-19
-- Platform :
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description: Converts a byte stream to a 14-bit pixel stream.
-------------------------------------------------------------------------------
-- Copyright (c) 2016
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2016-03-21 1.0 pofavrod Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity byte2pix is
port(
clk, reset : in std_logic;
byte_data : in std_logic_vector(7 downto 0);
byte_valid : in std_logic;
byte_sof : in std_logic;
byte_eof : in std_logic;
pix_data : out std_logic_vector(13 downto 0);
pix_valid : out std_logic;
pix_sof : out std_logic;
pix_eof : out std_logic);
end byte2pix;
architecture rtl of byte2pix is
signal last_sof : std_logic;
signal msb : std_logic_vector(5 downto 0);
signal cnt : std_logic; -- used to skip msb sampling every other time
begin
process(clk, reset)
begin
if reset = '1' then
msb <= (others => '0');
cnt <= '0';
last_sof <= '0';
elsif rising_edge(clk) then
if byte_valid = '1' then
if cnt = '0' then
msb <= byte_data(5 downto 0);
last_sof <= byte_sof;
end if;
cnt <= not cnt;
end if;
end if;
end process;
process(clk, reset)
begin
if reset = '1' then
pix_data <= (others => '0');
pix_valid <= '0';
pix_sof <= '0';
pix_eof <= '0';
elsif rising_edge(clk) then
pix_data <= (others => '0');
pix_valid <= '0';
pix_sof <= '0';
pix_eof <= '0';
if byte_valid = '1' then
if cnt = '1' then
pix_data <= msb & byte_data;
pix_valid <= '1';
pix_sof <= last_sof;
pix_eof <= byte_eof;
end if;
end if;
end if;
end process;
end architecture rtl;

View File

@@ -0,0 +1,192 @@
-- megafunction wizard: %RAM: 2-PORT%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altsyncram
-- ============================================================
-- File Name: dual_ported_ram.vhd
-- Megafunction Name(s):
-- altsyncram
--
-- Simulation Library Files(s):
-- altera_mf
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 15.1.0 Build 185 10/21/2015 SJ Lite Edition
-- ************************************************************
--Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
--Your use of Altera Corporation's design tools, logic functions
--and other software and tools, and its AMPP partner logic
--functions, and any output files from any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Altera Program License
--Subscription Agreement, the Altera Quartus Prime License Agreement,
--the Altera MegaCore Function License Agreement, or other
--applicable license agreement, including, without limitation,
--that your use is for the sole purpose of programming logic
--devices manufactured by Altera and sold by Altera or its
--authorized distributors. Please refer to the applicable
--agreement for further details.
library ieee;
use ieee.std_logic_1164.all;
library altera_mf;
use altera_mf.altera_mf_components.all;
entity dual_ported_ram is
port(
clock : in std_logic := '1';
data : in std_logic_vector(15 downto 0);
rdaddress : in std_logic_vector(12 downto 0);
wraddress : in std_logic_vector(12 downto 0);
wren : in std_logic := '0';
q : out std_logic_vector(15 downto 0)
);
end dual_ported_ram;
architecture SYN of dual_ported_ram is
signal sub_wire0 : std_logic_vector(15 downto 0);
begin
q <= sub_wire0(15 downto 0);
altsyncram_component : altsyncram
generic map(
address_aclr_b => "NONE",
address_reg_b => "CLOCK0",
clock_enable_input_a => "BYPASS",
clock_enable_input_b => "BYPASS",
clock_enable_output_b => "BYPASS",
intended_device_family => "Cyclone V",
lpm_type => "altsyncram",
numwords_a => 8192,
numwords_b => 8192,
operation_mode => "DUAL_PORT",
outdata_aclr_b => "NONE",
outdata_reg_b => "CLOCK0",
power_up_uninitialized => "FALSE",
read_during_write_mode_mixed_ports => "DONT_CARE",
widthad_a => 13,
widthad_b => 13,
width_a => 16,
width_b => 16,
width_byteena_a => 1
)
port map(
address_a => wraddress,
address_b => rdaddress,
clock0 => clock,
data_a => data,
wren_a => wren,
q_b => sub_wire0
);
end SYN;
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
-- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
-- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
-- Retrieval info: PRIVATE: CLRdata NUMERIC "0"
-- Retrieval info: PRIVATE: CLRq NUMERIC "0"
-- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
-- Retrieval info: PRIVATE: CLRrren NUMERIC "0"
-- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
-- Retrieval info: PRIVATE: CLRwren NUMERIC "0"
-- Retrieval info: PRIVATE: Clock NUMERIC "0"
-- Retrieval info: PRIVATE: Clock_A NUMERIC "0"
-- Retrieval info: PRIVATE: Clock_B NUMERIC "0"
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
-- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0"
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B"
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
-- Retrieval info: PRIVATE: MEMSIZE NUMERIC "131072"
-- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
-- Retrieval info: PRIVATE: MIFfilename STRING ""
-- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2"
-- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "1"
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
-- Retrieval info: PRIVATE: REGdata NUMERIC "1"
-- Retrieval info: PRIVATE: REGq NUMERIC "1"
-- Retrieval info: PRIVATE: REGrdaddress NUMERIC "1"
-- Retrieval info: PRIVATE: REGrren NUMERIC "1"
-- Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
-- Retrieval info: PRIVATE: REGwren NUMERIC "1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
-- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
-- Retrieval info: PRIVATE: VarWidth NUMERIC "0"
-- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "16"
-- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "16"
-- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "16"
-- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "16"
-- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0"
-- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: enable NUMERIC "0"
-- Retrieval info: PRIVATE: rden NUMERIC "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE"
-- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "8192"
-- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "8192"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK0"
-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
-- Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE"
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "13"
-- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "13"
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "16"
-- Retrieval info: CONSTANT: WIDTH_B NUMERIC "16"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
-- Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL "data[15..0]"
-- Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL "q[15..0]"
-- Retrieval info: USED_PORT: rdaddress 0 0 13 0 INPUT NODEFVAL "rdaddress[12..0]"
-- Retrieval info: USED_PORT: wraddress 0 0 13 0 INPUT NODEFVAL "wraddress[12..0]"
-- Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren"
-- Retrieval info: CONNECT: @address_a 0 0 13 0 wraddress 0 0 13 0
-- Retrieval info: CONNECT: @address_b 0 0 13 0 rdaddress 0 0 13 0
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
-- Retrieval info: CONNECT: @data_a 0 0 16 0 data 0 0 16 0
-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
-- Retrieval info: CONNECT: q 0 0 16 0 @q_b 0 0 16 0
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram.cmp FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram.bsf FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram_inst.vhd FALSE
-- Retrieval info: LIB_FILE: altera_mf

View File

@@ -0,0 +1,288 @@
-- Lepton Avalon Memory-Mapped Slave Interface
-- Author: Philémon Favrod (philemon.favrod@epfl.ch)
-- Modified by: Sahand Kashani-Akhavan (sahand.kashani-akhavan@epfl.ch)
-- Revision: 2
-- Register map
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | RegNo | Name | Access | Description |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 0 | COMMAND | WO | Command |
-- | | | | - Writing 1 starts capturing a frame & resets the |
-- | | | | ERROR bit (bit 1) in the STATUS register. |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 1 | STATUS | RO | Status |
-- | | | | - Bit 0: 0 --> no capture in progress. |
-- | | | | 1 --> capture in progress. |
-- | | | | - Bit 1: 0 --> previous capture successful. |
-- | | | | 1 --> error during previous capture. |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 2 | MIN | RO | Minimum pixel value in frame. |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 3 | MAX | RO | Maximum pixel value in frame. |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 4 | SUM_LSB | RO | Sum of all pixels in frame (low 16 bits). |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 5 | SUM_MSB | RO | Sum of all pixels in frame (high 16 bits). |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 6 | ROW_IDX | RO | Current line being captured (1 <= ROW_IDX <= 60). |
-- | | | | Available for debugging purposes. |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 7 | RESERVED | - | Reserved |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 8 - 4807 | RAW BUFFER | RO | View into RAW pixel buffer. |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 4808 - 8191 | RESERVED | - | Reserved |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 8192 - 12991 | ADJUSTED BUFFER | RO | View into adjusted (scaled) pixel buffer. |
-- | | | | Values are scaled between MIN and MAX. |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 12992 - 16383 | RESERVED | - | Reserved |
-- +---------------+-----------------+--------+---------------------------------------------------+
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity lepton is
port(
clk : in std_logic;
reset : in std_logic;
address : in std_logic_vector(13 downto 0);
readdata : out std_logic_vector(15 downto 0);
writedata : in std_logic_vector(15 downto 0);
read : in std_logic;
write : in std_logic;
SCLK : out std_logic;
CSn : out std_logic;
MOSI : out std_logic;
MISO : in std_logic
);
end lepton;
architecture rtl of lepton is
signal spi_cs_n : std_logic;
signal spi_mosi_data : std_logic_vector(7 downto 0);
signal spi_mosi_valid : std_logic;
signal spi_mosi_ready : std_logic;
signal spi_miso_data : std_logic_vector(7 downto 0);
signal spi_miso_valid : std_logic;
signal lepton_manager_start : std_logic;
signal lepton_manager_error : std_logic;
signal byte_data : std_logic_vector(7 downto 0);
signal byte_valid : std_logic;
signal byte_sof : std_logic;
signal byte_eof : std_logic;
signal pix_data : std_logic_vector(13 downto 0);
signal pix_valid : std_logic;
signal pix_sof : std_logic;
signal pix_eof : std_logic;
signal stat_min : std_logic_vector(13 downto 0);
signal stat_max : std_logic_vector(13 downto 0);
signal stat_sum : std_logic_vector(26 downto 0);
signal stat_valid : std_logic;
signal ram_data : std_logic_vector(15 downto 0);
signal ram_wren : std_logic;
signal ram_wraddress : std_logic_vector(12 downto 0);
signal ram_rdaddress : std_logic_vector(12 downto 0);
signal ram_q : std_logic_vector(15 downto 0);
signal row_idx : std_logic_vector(5 downto 0);
signal raw_pixel : std_logic_vector(13 downto 0);
signal raw_max : std_logic_vector(13 downto 0);
signal raw_min : std_logic_vector(13 downto 0);
signal raw_sum : std_logic_vector(26 downto 0);
signal adjusted_pixel : std_logic_vector(13 downto 0);
constant COMMAND_REG_OFFSET : std_logic_vector(address'range) := "00000000000000";
constant STATUS_REG_OFFSET : std_logic_vector(address'range) := "00000000000001";
constant MIN_REG_OFFSET : std_logic_vector(address'range) := "00000000000010";
constant MAX_REG_OFFSET : std_logic_vector(address'range) := "00000000000011";
constant SUM_LSB_REG_OFFSET : std_logic_vector(address'range) := "00000000000100";
constant SUM_MSB_REG_OFFSET : std_logic_vector(address'range) := "00000000000101";
constant ROW_IDX_REG_OFFSET : std_logic_vector(address'range) := "00000000000110";
constant BUFFER_REG_OFFSET : unsigned(address'range) := "00000000001000";
constant ADJUSTED_BUFFER_REG_OFFSET : unsigned(address'range) := "10000000000000";
constant IMAGE_SIZE : integer := 80 * 60;
constant BUFFER_REG_LIMIT : unsigned(address'range) := unsigned(BUFFER_REG_OFFSET) + IMAGE_SIZE;
constant ADJUSTED_BUFFER_LIMIT : unsigned(address'range) := unsigned(ADJUSTED_BUFFER_REG_OFFSET) + IMAGE_SIZE;
signal max_reg : std_logic_vector(stat_max'range);
signal min_reg : std_logic_vector(stat_min'range);
signal sum_reg : std_logic_vector(stat_sum'range);
signal error_reg : std_logic;
begin
spi_controller0 : entity work.avalon_st_spi_master
port map(
clk => clk,
reset => reset,
spi_cs_n => spi_cs_n,
mosi_sink_data => spi_mosi_data,
mosi_sink_valid => spi_mosi_valid,
mosi_sink_ready => spi_mosi_ready,
miso_src_data => spi_miso_data,
miso_src_valid => spi_miso_valid,
SCLK => SCLK,
MISO => MISO,
MOSI => MOSI,
CS_n => CSn
);
lepton_manager0 : entity work.lepton_manager
port map(
clk => clk,
reset => reset,
spi_miso_sink_data => spi_miso_data,
spi_miso_sink_valid => spi_miso_valid,
spi_mosi_src_data => spi_mosi_data,
spi_mosi_src_valid => spi_mosi_valid,
spi_mosi_src_ready => spi_mosi_ready,
lepton_out_data => byte_data,
lepton_out_valid => byte_valid,
lepton_out_sof => byte_sof,
lepton_out_eof => byte_eof,
row_idx => row_idx,
error => lepton_manager_error,
start => lepton_manager_start,
spi_cs_n => spi_cs_n
);
byte2pix0 : entity work.byte2pix
port map(
clk => clk,
reset => reset,
byte_data => byte_data,
byte_valid => byte_valid,
byte_sof => byte_sof,
byte_eof => byte_eof,
pix_data => pix_data,
pix_valid => pix_valid,
pix_sof => pix_sof,
pix_eof => pix_eof
);
lepton_stats0 : entity work.lepton_stats
port map(
reset => reset,
clk => clk,
pix_data => pix_data,
pix_valid => pix_valid,
pix_sof => pix_sof,
pix_eof => pix_eof,
stat_min => stat_min,
stat_max => stat_max,
stat_sum => stat_sum,
stat_valid => stat_valid
);
ram_writer0 : entity work.ram_writer
port map(
clk => clk,
reset => reset,
pix_data => pix_data,
pix_valid => pix_valid,
pix_sof => pix_sof,
pix_eof => pix_eof,
ram_data => ram_data,
ram_wren => ram_wren,
ram_wraddress => ram_wraddress
);
dual_ported_ram0 : entity work.dual_ported_ram
port map(
clock => clk,
data => ram_data,
rdaddress => ram_rdaddress,
wraddress => ram_wraddress,
wren => ram_wren,
q => ram_q
);
level_adjuster0 : entity work.level_adjuster
port map(
clk => clk,
raw_pixel => ram_q(13 downto 0),
raw_max => max_reg,
raw_min => min_reg,
raw_sum => sum_reg,
adjusted_pixel => adjusted_pixel
);
p_lepton_start : process(clk, reset)
begin
if reset = '1' then
lepton_manager_start <= '0';
error_reg <= '0';
elsif rising_edge(clk) then
if write = '1' and address = COMMAND_REG_OFFSET then
lepton_manager_start <= writedata(0);
error_reg <= '0';
elsif pix_eof = '1' then
lepton_manager_start <= '0';
elsif lepton_manager_error = '1' then
error_reg <= '1';
end if;
end if;
end process p_lepton_start;
p_stat_reg : process(clk, reset)
begin
if reset = '1' then
min_reg <= (others => '0');
max_reg <= (others => '0');
sum_reg <= (others => '0');
elsif rising_edge(clk) then
if stat_valid = '1' then
min_reg <= stat_min;
max_reg <= stat_max;
sum_reg <= stat_sum;
end if;
end if;
end process p_stat_reg;
p_read : process(clk, reset)
begin
if reset = '1' then
readdata <= (others => '0');
ram_rdaddress <= (others => '0');
elsif rising_edge(clk) then
readdata <= (others => '0');
if read = '1' then
case address is
when STATUS_REG_OFFSET =>
readdata(1) <= error_reg;
readdata(0) <= lepton_manager_start;
when MIN_REG_OFFSET =>
readdata <= "00" & min_reg;
when MAX_REG_OFFSET =>
readdata <= "00" & max_reg;
when SUM_MSB_REG_OFFSET =>
readdata <= "00000" & sum_reg(26 downto 16);
when SUM_LSB_REG_OFFSET =>
readdata <= sum_reg(15 downto 0);
when ROW_IDX_REG_OFFSET =>
readdata(5 downto 0) <= row_idx;
when others =>
if unsigned(address) >= BUFFER_REG_OFFSET and unsigned(address) < BUFFER_REG_LIMIT then
ram_rdaddress <= std_logic_vector(resize(unsigned(address) - BUFFER_REG_OFFSET, ram_rdaddress'length));
readdata <= ram_q;
elsif unsigned(address) >= ADJUSTED_BUFFER_REG_OFFSET and unsigned(address) < ADJUSTED_BUFFER_LIMIT then
ram_rdaddress <= std_logic_vector(resize(unsigned(address) - ADJUSTED_BUFFER_REG_OFFSET, ram_rdaddress'length));
readdata <= "00" & adjusted_pixel;
end if;
end case;
end if;
end if;
end process p_read;
end rtl;

View File

@@ -0,0 +1,148 @@
# TCL File Generated by Component Editor 16.0
# Sun Feb 05 19:05:24 CET 2017
# DO NOT MODIFY
#
# lepton "lepton" v1.0
# Philemon Favrod & Sahand Kashani-Akhavan 2017.02.05.19:05:24
# IR Camera 80x60
#
#
# request TCL package from ACDS 16.0
#
package require -exact qsys 16.0
#
# module lepton
#
set_module_property DESCRIPTION "IR Camera 80x60"
set_module_property NAME lepton
set_module_property VERSION 1.0
set_module_property INTERNAL false
set_module_property OPAQUE_ADDRESS_MAP true
set_module_property GROUP Camera
set_module_property AUTHOR "Philemon Favrod & Sahand Kashani-Akhavan"
set_module_property DISPLAY_NAME lepton
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
set_module_property EDITABLE true
set_module_property REPORT_TO_TALKBACK false
set_module_property ALLOW_GREYBOX_GENERATION false
set_module_property REPORT_HIERARCHY false
#
# file sets
#
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
set_fileset_property QUARTUS_SYNTH TOP_LEVEL lepton
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
add_fileset_file avalon_st_spi_master.vhd VHDL PATH avalon_st_spi_master.vhd
add_fileset_file byte2pix.vhd VHDL PATH byte2pix.vhd
add_fileset_file dual_ported_ram.vhd VHDL PATH dual_ported_ram.vhd
add_fileset_file lepton.vhd VHDL PATH lepton.vhd TOP_LEVEL_FILE
add_fileset_file lepton_manager.vhd VHDL PATH lepton_manager.vhd
add_fileset_file lepton_stats.vhd VHDL PATH lepton_stats.vhd
add_fileset_file ram_writer.vhd VHDL PATH ram_writer.vhd
add_fileset_file utils.vhd VHDL PATH utils.vhd
add_fileset_file level_adjuster.vhd VHDL PATH level_adjuster.vhd
add_fileset_file lpm_divider.vhd VHDL PATH lpm_divider.vhd
#
# parameters
#
#
# display items
#
#
# connection point clock
#
add_interface clock clock end
set_interface_property clock clockRate 0
set_interface_property clock ENABLED true
set_interface_property clock EXPORT_OF ""
set_interface_property clock PORT_NAME_MAP ""
set_interface_property clock CMSIS_SVD_VARIABLES ""
set_interface_property clock SVD_ADDRESS_GROUP ""
add_interface_port clock clk clk Input 1
#
# connection point reset
#
add_interface reset reset end
set_interface_property reset associatedClock clock
set_interface_property reset synchronousEdges DEASSERT
set_interface_property reset ENABLED true
set_interface_property reset EXPORT_OF ""
set_interface_property reset PORT_NAME_MAP ""
set_interface_property reset CMSIS_SVD_VARIABLES ""
set_interface_property reset SVD_ADDRESS_GROUP ""
add_interface_port reset reset reset Input 1
#
# connection point avalon_slave_0
#
add_interface avalon_slave_0 avalon end
set_interface_property avalon_slave_0 addressUnits WORDS
set_interface_property avalon_slave_0 associatedClock clock
set_interface_property avalon_slave_0 associatedReset reset
set_interface_property avalon_slave_0 bitsPerSymbol 8
set_interface_property avalon_slave_0 burstOnBurstBoundariesOnly false
set_interface_property avalon_slave_0 burstcountUnits WORDS
set_interface_property avalon_slave_0 explicitAddressSpan 0
set_interface_property avalon_slave_0 holdTime 0
set_interface_property avalon_slave_0 linewrapBursts false
set_interface_property avalon_slave_0 maximumPendingReadTransactions 0
set_interface_property avalon_slave_0 maximumPendingWriteTransactions 0
set_interface_property avalon_slave_0 readLatency 0
set_interface_property avalon_slave_0 readWaitStates 9
set_interface_property avalon_slave_0 readWaitTime 9
set_interface_property avalon_slave_0 setupTime 0
set_interface_property avalon_slave_0 timingUnits Cycles
set_interface_property avalon_slave_0 writeWaitTime 0
set_interface_property avalon_slave_0 ENABLED true
set_interface_property avalon_slave_0 EXPORT_OF ""
set_interface_property avalon_slave_0 PORT_NAME_MAP ""
set_interface_property avalon_slave_0 CMSIS_SVD_VARIABLES ""
set_interface_property avalon_slave_0 SVD_ADDRESS_GROUP ""
add_interface_port avalon_slave_0 address address Input 14
add_interface_port avalon_slave_0 readdata readdata Output 16
add_interface_port avalon_slave_0 writedata writedata Input 16
add_interface_port avalon_slave_0 read read Input 1
add_interface_port avalon_slave_0 write write Input 1
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isFlash 0
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isMemoryDevice 0
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isNonVolatileStorage 0
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isPrintableDevice 0
#
# connection point spi
#
add_interface spi conduit end
set_interface_property spi associatedClock clock
set_interface_property spi associatedReset ""
set_interface_property spi ENABLED true
set_interface_property spi EXPORT_OF ""
set_interface_property spi PORT_NAME_MAP ""
set_interface_property spi CMSIS_SVD_VARIABLES ""
set_interface_property spi SVD_ADDRESS_GROUP ""
add_interface_port spi CSn cs_n Output 1
add_interface_port spi MISO miso Input 1
add_interface_port spi MOSI mosi Output 1
add_interface_port spi SCLK sclk Output 1

View File

@@ -0,0 +1,235 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity lepton_manager is
generic(
INPUT_CLK_FREQ : integer := 50000000);
port(
clk : in std_logic := '0';
reset : in std_logic := '0';
-- Avalon ST Sink to receive SPI data
spi_miso_sink_data : in std_logic_vector(7 downto 0);
spi_miso_sink_valid : in std_logic;
-- Avalon ST Source to send SPI data
spi_mosi_src_data : out std_logic_vector(7 downto 0);
spi_mosi_src_valid : out std_logic;
spi_mosi_src_ready : in std_logic := '0';
-- Filtered output to retransmit cleaned data (without the discard packets, see Lepton Datasheet on page 31)
-- lepton_out_data is valid on rising edge when lepton_src_valid = '1'
lepton_out_data : out std_logic_vector(7 downto 0);
lepton_out_valid : out std_logic;
lepton_out_sof : out std_logic;
lepton_out_eof : out std_logic;
-- Some status
row_idx : out std_logic_vector(5 downto 0);
error : out std_logic;
-- Avalon MM Slave interface for configuration
start : in std_logic;
-- The SPI Chip Select (Active low !)
spi_cs_n : out std_logic := '0');
end entity lepton_manager;
architecture rtl of lepton_manager is
type state_t is (Idle, CSn, ReadHeader, ReadPayload, DiscardPayload, WaitBeforeIdle);
signal state, next_state : state_t;
signal header_3_last_nibbles : std_logic_vector(11 downto 0);
constant CLOCK_TICKS_PER_37_MS : integer := 37 * (INPUT_CLK_FREQ / 1e3); -- the timeout delay for a frame
constant CLOCK_TICKS_PER_200_MS : integer := 200 * (INPUT_CLK_FREQ / 1e3);
constant CLOCK_TICKS_PER_200_NS : integer := (200 * (INPUT_CLK_FREQ / 1e6)) / 1e3;
constant BYTES_PER_HEADER : integer := 4;
constant BYTES_PER_PAYLOAD : integer := 160;
constant NUMBER_OF_LINES_PER_FRAME : positive := 60;
signal counter, counter_max : integer range 1 to CLOCK_TICKS_PER_200_MS;
signal line_counter : integer range 1 to NUMBER_OF_LINES_PER_FRAME;
signal timeout_counter : integer range 1 to CLOCK_TICKS_PER_37_MS;
signal counter_enabled : boolean;
signal waited_long_enough : boolean;
signal header_end, payload_end : boolean;
begin
-- purpose: register for state
p_fsm : process(clk, reset)
begin
if reset = '1' then
state <= Idle;
elsif rising_edge(clk) then
state <= next_state;
end if;
end process p_fsm;
-- purpose: compute the next state
p_nsl : process(header_3_last_nibbles, header_end, payload_end, start, spi_miso_sink_valid, state, waited_long_enough, line_counter)
begin
next_state <= state;
case state is
when Idle =>
if waited_long_enough and start = '1' then
next_state <= CSn;
end if;
when CSn =>
if waited_long_enough then
next_state <= ReadHeader;
end if;
when ReadHeader =>
if header_end then
if header_3_last_nibbles(11 downto 8) = X"F" then
next_state <= DiscardPayload;
else
next_state <= ReadPayload;
end if;
end if;
when DiscardPayload | ReadPayload =>
if payload_end then
next_state <= ReadHeader;
if line_counter = NUMBER_OF_LINES_PER_FRAME then
next_state <= WaitBeforeIdle;
end if;
end if;
when WaitBeforeIdle =>
if spi_miso_sink_valid = '1' then
next_state <= Idle;
end if;
end case;
end process p_nsl;
p_counter : process(clk, reset)
begin
if reset = '1' then
counter <= 1;
line_counter <= 1;
elsif rising_edge(clk) then
if counter = counter_max and counter_enabled then
counter <= 1;
if state = ReadPayload then
if line_counter = NUMBER_OF_LINES_PER_FRAME then
line_counter <= 1;
else
line_counter <= line_counter + 1;
end if;
end if;
elsif counter_enabled then
counter <= counter + 1;
end if;
end if;
end process p_counter;
p_error : process(clk, reset)
begin
if reset = '1' then
error <= '0';
timeout_counter <= 1;
elsif rising_edge(clk) then
if state /= ReadHeader and state /= ReadPayload and state /= ReadHeader then
timeout_counter <= 1;
error <= '0';
else
if timeout_counter = CLOCK_TICKS_PER_37_MS then
error <= '1';
else
timeout_counter <= timeout_counter + 1;
end if;
end if;
if state = ReadPayload and header_3_last_nibbles /= std_logic_vector(to_unsigned(line_counter - 1, header_3_last_nibbles'length)) then
error <= '1';
end if;
end if;
end process p_error;
-- purpose: wire the datapath
p_datapath : process(counter, counter_enabled, counter_max, line_counter, spi_miso_sink_data, spi_miso_sink_valid, spi_mosi_src_ready, state)
variable counter_ended : boolean;
begin
counter_max <= 1;
counter_enabled <= true;
waited_long_enough <= false;
lepton_out_data <= (others => '0');
lepton_out_valid <= '0';
lepton_out_sof <= '0';
lepton_out_eof <= '0';
spi_mosi_src_valid <= '0';
spi_mosi_src_data <= (others => '0');
spi_cs_n <= '0';
header_end <= false;
payload_end <= false;
counter_ended := (counter = counter_max and counter_enabled);
case state is
when Idle =>
counter_max <= CLOCK_TICKS_PER_200_MS;
waited_long_enough <= counter_ended;
spi_cs_n <= '1';
when CSn =>
counter_max <= CLOCK_TICKS_PER_200_NS;
waited_long_enough <= counter_ended;
when ReadHeader =>
counter_max <= BYTES_PER_HEADER;
counter_enabled <= spi_miso_sink_valid = '1';
header_end <= counter_ended;
spi_mosi_src_valid <= spi_mosi_src_ready;
when ReadPayload =>
counter_max <= BYTES_PER_PAYLOAD;
counter_enabled <= spi_miso_sink_valid = '1';
lepton_out_data <= spi_miso_sink_data;
lepton_out_valid <= spi_miso_sink_valid;
payload_end <= counter_ended;
spi_mosi_src_valid <= spi_mosi_src_ready;
if spi_miso_sink_valid = '1' then
if counter = 1 and counter_enabled and line_counter = 1 then
lepton_out_sof <= '1';
elsif counter_ended and line_counter = NUMBER_OF_LINES_PER_FRAME then
lepton_out_eof <= '1';
end if;
end if;
when DiscardPayload =>
counter_max <= BYTES_PER_PAYLOAD;
counter_enabled <= spi_miso_sink_valid = '1';
payload_end <= counter_ended;
spi_mosi_src_valid <= spi_mosi_src_ready;
when others => null;
end case;
end process p_datapath;
p_capture_header : process(clk, reset)
begin
if reset = '1' then
header_3_last_nibbles <= X"000";
elsif rising_edge(clk) then
if state = ReadHeader and spi_miso_sink_valid = '1' then
if counter = 1 then
header_3_last_nibbles(11 downto 8) <= spi_miso_sink_data(3 downto 0);
elsif counter = 2 then
header_3_last_nibbles(7 downto 0) <= spi_miso_sink_data;
end if;
end if;
end if;
end process p_capture_header;
row_idx <= std_logic_vector(to_unsigned(line_counter, row_idx'length));
end architecture rtl;

View File

@@ -0,0 +1,78 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity lepton_stats is
port(
clk : in std_logic;
reset : in std_logic;
pix_data : in std_logic_vector(13 downto 0);
pix_valid : in std_logic;
pix_sof : in std_logic;
pix_eof : in std_logic;
stat_min : out std_logic_vector(13 downto 0);
stat_max : out std_logic_vector(13 downto 0);
stat_sum : out std_logic_vector(26 downto 0);
stat_valid : out std_logic);
end lepton_stats;
architecture rtl of lepton_stats is
-- The accumulated sum, min and max of the pixel values
signal curr_min : unsigned(13 downto 0);
signal curr_max : unsigned(13 downto 0);
signal curr_sum : unsigned(26 downto 0);
-- The next value of the registers
signal next_min : unsigned(13 downto 0);
signal next_max : unsigned(13 downto 0);
signal next_sum : unsigned(26 downto 0);
begin
-- This is the synchronous transition logic
transition_logic : process(clk, reset)
begin
if reset = '1' then
curr_sum <= (others => '0');
curr_min <= (others => '0');
curr_max <= (others => '0');
elsif rising_edge(clk) then
curr_min <= next_min;
curr_max <= next_max;
curr_sum <= next_sum;
end if;
end process;
-- This is the combinatorial transition logic
next_min <=
curr_min when pix_valid = '0' else
unsigned(pix_data) when pix_sof = '1' else
curr_min when unsigned(pix_data) >= curr_min else
unsigned(pix_data);
next_max <=
curr_max when pix_valid = '0' else
unsigned(pix_data) when pix_sof = '1' else
curr_max when unsigned(pix_data) <= curr_max else
unsigned(pix_data);
next_sum <=
curr_sum when pix_valid = '0' else
unsigned((26 downto 14 => '0') & pix_data) when pix_sof = '1' else
curr_sum + unsigned((26 downto 14 => '0') & pix_data);
-- This is the synchronous output logic
output_logic : process(clk, reset)
begin
if rising_edge(clk) then
stat_valid <= pix_eof;
end if;
end process;
-- This is the combinatorial output logic
stat_min <= std_logic_vector(curr_min);
stat_max <= std_logic_vector(curr_max);
stat_sum <= std_logic_vector(curr_sum);
end rtl;

View File

@@ -0,0 +1,50 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity level_adjuster is
port(
clk : in std_logic;
raw_pixel : in std_logic_vector(13 downto 0);
raw_max : in std_logic_vector(13 downto 0);
raw_min : in std_logic_vector(13 downto 0);
raw_sum : in std_logic_vector(26 downto 0);
adjusted_pixel : out std_logic_vector(13 downto 0));
end level_adjuster;
architecture rtl of level_adjuster is
component lpm_divider
port(
clock : in std_logic;
denom : in std_logic_vector(13 downto 0);
numer : in std_logic_vector(27 downto 0);
quotient : out std_logic_vector(27 downto 0);
remain : out std_logic_vector(13 downto 0));
end component;
-- Intermediate signals needed by the divider
signal numer : std_logic_vector(27 downto 0);
signal denom : std_logic_vector(13 downto 0);
signal quot : std_logic_vector(27 downto 0);
begin
-- Computation of the intermediate signals
numer <= std_logic_vector((13 downto 0 => '1') * (unsigned(raw_pixel) - unsigned(raw_min)));
denom <= std_logic_vector(unsigned(raw_max) - unsigned(raw_min));
-- We compute the remaineder of (x - min) / (max - min)
divider : lpm_divider port map(
clock => clk,
numer => numer,
denom => denom,
quotient => quot,
remain => open
);
-- And we only keep the LSB of the quotient (we know the MSB must be 0)
adjusted_pixel <=
(adjusted_pixel'range => '0') when denom = (denom'range => '0') else
quot(13 downto 0);
end rtl;

View File

@@ -0,0 +1,133 @@
-- megafunction wizard: %LPM_DIVIDE%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: LPM_DIVIDE
-- ============================================================
-- File Name: lpm_divider.vhd
-- Megafunction Name(s):
-- LPM_DIVIDE
--
-- Simulation Library Files(s):
-- lpm
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 15.1.0 Build 185 10/21/2015 SJ Lite Edition
-- ************************************************************
--Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
--Your use of Altera Corporation's design tools, logic functions
--and other software and tools, and its AMPP partner logic
--functions, and any output files from any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Altera Program License
--Subscription Agreement, the Altera Quartus Prime License Agreement,
--the Altera MegaCore Function License Agreement, or other
--applicable license agreement, including, without limitation,
--that your use is for the sole purpose of programming logic
--devices manufactured by Altera and sold by Altera or its
--authorized distributors. Please refer to the applicable
--agreement for further details.
library ieee;
use ieee.std_logic_1164.all;
library lpm;
use lpm.all;
entity lpm_divider is
port(
clock : in std_logic;
denom : in std_logic_vector(13 downto 0);
numer : in std_logic_vector(27 downto 0);
quotient : out std_logic_vector(27 downto 0);
remain : out std_logic_vector(13 downto 0)
);
end lpm_divider;
architecture SYN of lpm_divider is
signal sub_wire0 : std_logic_vector(27 downto 0);
signal sub_wire1 : std_logic_vector(13 downto 0);
component lpm_divide
generic(
lpm_drepresentation : string;
lpm_hint : string;
lpm_nrepresentation : string;
lpm_pipeline : natural;
lpm_type : string;
lpm_widthd : natural;
lpm_widthn : natural
);
port(
clock : in std_logic;
denom : in std_logic_vector(13 downto 0);
numer : in std_logic_vector(27 downto 0);
quotient : out std_logic_vector(27 downto 0);
remain : out std_logic_vector(13 downto 0)
);
end component;
begin
quotient <= sub_wire0(27 downto 0);
remain <= sub_wire1(13 downto 0);
LPM_DIVIDE_component : LPM_DIVIDE
generic map(
lpm_drepresentation => "UNSIGNED",
lpm_hint => "LPM_REMAINDERPOSITIVE=TRUE",
lpm_nrepresentation => "UNSIGNED",
lpm_pipeline => 5,
lpm_type => "LPM_DIVIDE",
lpm_widthd => 14,
lpm_widthn => 28
)
port map(
clock => clock,
denom => denom,
numer => numer,
quotient => sub_wire0,
remain => sub_wire1
);
end SYN;
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
-- Retrieval info: PRIVATE: PRIVATE_LPM_REMAINDERPOSITIVE STRING "TRUE"
-- Retrieval info: PRIVATE: PRIVATE_MAXIMIZE_SPEED NUMERIC "-1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: USING_PIPELINE NUMERIC "1"
-- Retrieval info: PRIVATE: VERSION_NUMBER NUMERIC "2"
-- Retrieval info: PRIVATE: new_diagram STRING "1"
-- Retrieval info: LIBRARY: lpm lpm.lpm_components.all
-- Retrieval info: CONSTANT: LPM_DREPRESENTATION STRING "UNSIGNED"
-- Retrieval info: CONSTANT: LPM_HINT STRING "LPM_REMAINDERPOSITIVE=TRUE"
-- Retrieval info: CONSTANT: LPM_NREPRESENTATION STRING "UNSIGNED"
-- Retrieval info: CONSTANT: LPM_PIPELINE NUMERIC "5"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_DIVIDE"
-- Retrieval info: CONSTANT: LPM_WIDTHD NUMERIC "14"
-- Retrieval info: CONSTANT: LPM_WIDTHN NUMERIC "28"
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock"
-- Retrieval info: USED_PORT: denom 0 0 14 0 INPUT NODEFVAL "denom[13..0]"
-- Retrieval info: USED_PORT: numer 0 0 28 0 INPUT NODEFVAL "numer[27..0]"
-- Retrieval info: USED_PORT: quotient 0 0 28 0 OUTPUT NODEFVAL "quotient[27..0]"
-- Retrieval info: USED_PORT: remain 0 0 14 0 OUTPUT NODEFVAL "remain[13..0]"
-- Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
-- Retrieval info: CONNECT: @denom 0 0 14 0 denom 0 0 14 0
-- Retrieval info: CONNECT: @numer 0 0 28 0 numer 0 0 28 0
-- Retrieval info: CONNECT: quotient 0 0 28 0 @quotient 0 0 28 0
-- Retrieval info: CONNECT: remain 0 0 14 0 @remain 0 0 14 0
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider.cmp FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider.bsf FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider_inst.vhd FALSE
-- Retrieval info: LIB_FILE: lpm

View File

@@ -0,0 +1,38 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ram_writer is
port(
clk, reset : in std_logic;
pix_data : in std_logic_vector(13 downto 0);
pix_valid : in std_logic;
pix_sof : in std_logic;
pix_eof : in std_logic;
ram_data : out std_logic_vector(15 downto 0);
ram_wren : out std_logic;
ram_wraddress : out std_logic_vector(12 downto 0));
end ram_writer;
architecture rtl of ram_writer is
signal wraddress_counter : unsigned(ram_wraddress'range);
begin
p_address_gen : process(clk, reset)
begin
if reset = '1' then
wraddress_counter <= (others => '0');
elsif rising_edge(clk) then
if pix_eof = '1' then
wraddress_counter <= (others => '0');
elsif pix_valid = '1' then
wraddress_counter <= wraddress_counter + 1;
end if;
end if;
end process p_address_gen;
ram_data <= "00" & pix_data;
ram_wren <= pix_valid;
ram_wraddress <= std_logic_vector(wraddress_counter);
end rtl;

View File

@@ -0,0 +1,27 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package utils is
function bitlength(number : positive) return positive;
end package utils;
package body utils is
-- purpose: returns the minimum # of bits needed to represent the input number
function bitlength(number : positive) return positive is
variable acc : positive := 1;
variable i : natural := 0;
begin
while True loop
if acc > number then
return i;
end if;
acc := acc * 2;
i := i + 1;
end loop;
end function bitlength;
end package body utils;

View File

@@ -0,0 +1,77 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity lepton_tb is
end lepton_tb;
architecture tb of lepton_tb is
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal address : std_logic_vector(13 downto 0) := (others => '0');
signal readdata : std_logic_vector(15 downto 0) := (others => '0');
signal writedata : std_logic_vector(15 downto 0) := (others => '0');
signal read : std_logic := '0';
signal write : std_logic := '0';
signal SCLK : std_logic := '0';
signal CSn : std_logic := '0';
signal MOSI : std_logic := '0';
signal MISO : std_logic := '1';
constant CLK_PERIOD : time := 20 ns;
signal sim_ended : boolean := false;
begin
dut : entity work.lepton
port map(
clk => clk,
reset => reset,
address => address,
readdata => readdata,
writedata => writedata,
read => read,
write => write,
SCLK => SCLK,
CSn => CSn,
MOSI => MOSI,
MISO => MISO
);
clk <= not clk after CLK_PERIOD / 2 when not sim_ended else '0';
miso_gen : process
variable seed1, seed2 : positive;
variable rand : real;
begin
if sim_ended then
wait;
else
uniform(seed1, seed2, rand);
wait until rising_edge(SCLK);
MISO <= to_unsigned(integer(rand), 1)(0);
end if;
end process;
stimuli : process
begin
reset <= '1';
write <= '0';
wait for 2 * CLK_PERIOD;
reset <= '0';
wait for CLK_PERIOD;
write <= '1';
writedata(0) <= '1';
wait for CLK_PERIOD;
write <= '0';
wait for 17 ms;
sim_ended <= true;
wait;
end process;
end tb;

View File

@@ -0,0 +1,42 @@
-- #############################################################################
-- pwm.vhd
-- =======
-- PWM memory-mapped Avalon slave interface.
--
-- Author : <insert your name> (<insert your e-mail address>)
-- Author : <insert your name> (<insert your e-mail address>)
-- Revision : <insert revision>
-- Last modified : <insert date>
-- #############################################################################
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.pwm_constants.all;
entity pwm is
port(
-- Avalon Clock interface
clk : in std_logic;
-- Avalon Reset interface
reset : in std_logic;
-- Avalon-MM Slave interface
address : in std_logic_vector(1 downto 0);
read : in std_logic;
write : in std_logic;
readdata : out std_logic_vector(31 downto 0);
writedata : in std_logic_vector(31 downto 0);
-- Avalon Conduit interface
pwm_out : out std_logic
);
end pwm;
architecture rtl of pwm is
begin
end architecture rtl;

View File

@@ -0,0 +1,61 @@
-- #############################################################################
-- pwm_constants.vhd
-- =================
-- This package contains constants used in the PWM design files.
--
-- Author : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
-- Revision : 2
-- Last modified : 2018-02-28
-- #############################################################################
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package pwm_constants is
-- Register map
-- +--------+------------+--------+------------------------------------------------------------------------------+
-- | RegNo | Name | Access | Description |
-- +--------+------------+--------+------------------------------------------------------------------------------+
-- | 0 | PERIOD | R/W | Period in clock cycles [2 <= period <= (2**32) - 1]. |
-- | | | | |
-- | | | | This value can be read/written while the unit is in the middle of an ongoing |
-- | | | | PWM pulse. To allow safe behaviour, one cannot modify the period of an |
-- | | | | ongoing pulse, so we adopt the following semantics for this register: |
-- | | | | |
-- | | | | >> WRITING a value in this register indicates the NEW period to apply to the |
-- | | | | next pulse. |
-- | | | | |
-- | | | | >> READING a value from this register indicates the CURRENT period of the |
-- | | | | ongoing pulse. |
-- +--------+------------+--------+------------------------------------------------------------------------------+
-- | 1 | DUTY_CYCLE | R/W | Duty cycle of the PWM [1 <= duty cycle <= period] |
-- | | | | |
-- | | | | This value can be read/written while the unit is in the middle of an ongoing |
-- | | | | PWM pulse. To allow safe behaviour, one cannot modify the duty cycle of an |
-- | | | | ongoing pulse, so we adopt the following semantics for this register: |
-- | | | | |
-- | | | | >> WRITING a value in this register indicates the NEW duty cycle to apply to |
-- | | | | the next pulse. |
-- | | | | |
-- | | | | >> READING a value from this register indicates the CURRENT duty cycle of |
-- | | | | the ongoing pulse. |
-- +--------+------------+--------+------------------------------------------------------------------------------+
-- | 2 | CTRL | WO | >> Writing 0 to this register stops the PWM once the ongoing pulse has ended.|
-- | | | | Writing 1 to this register starts the PWM. |
-- | | | | |
-- | | | | >> Reading this register always returns 0. |
-- +--------+------------+--------+------------------------------------------------------------------------------+
constant REG_PERIOD_OFST : std_logic_vector(1 downto 0) := "00";
constant REG_DUTY_CYCLE_OFST : std_logic_vector(1 downto 0) := "01";
constant REG_CTRL_OFST : std_logic_vector(1 downto 0) := "10";
-- Default values of registers after reset (BEFORE writing START to the CTRL
-- register with a new configuration)
constant DEFAULT_PERIOD : natural := 4;
constant DEFAULT_DUTY_CYCLE : natural := 2;
end package pwm_constants;
package body pwm_constants is
end package body pwm_constants;

View File

@@ -0,0 +1,135 @@
# TCL File Generated by Component Editor 16.0
# Tue Feb 28 12:18:00 CET 2017
# DO NOT MODIFY
#
# pwm "pwm" v1.0
# 2017.02.28.12:18:00
# Pan-tilt
#
#
# request TCL package from ACDS 16.0
#
package require -exact qsys 16.0
#
# module pwm
#
set_module_property DESCRIPTION Pan-tilt
set_module_property NAME pwm
set_module_property VERSION 1.0
set_module_property INTERNAL false
set_module_property OPAQUE_ADDRESS_MAP true
set_module_property GROUP Pan-tilt
set_module_property AUTHOR ""
set_module_property DISPLAY_NAME pwm
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
set_module_property EDITABLE true
set_module_property REPORT_TO_TALKBACK false
set_module_property ALLOW_GREYBOX_GENERATION false
set_module_property REPORT_HIERARCHY false
#
# file sets
#
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
set_fileset_property QUARTUS_SYNTH TOP_LEVEL pwm
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
add_fileset_file pwm.vhd VHDL PATH pwm.vhd TOP_LEVEL_FILE
add_fileset_file pwm_constants.vhd VHDL PATH pwm_constants.vhd
#
# parameters
#
#
# display items
#
#
# connection point clock
#
add_interface clock clock end
set_interface_property clock clockRate 0
set_interface_property clock ENABLED true
set_interface_property clock EXPORT_OF ""
set_interface_property clock PORT_NAME_MAP ""
set_interface_property clock CMSIS_SVD_VARIABLES ""
set_interface_property clock SVD_ADDRESS_GROUP ""
add_interface_port clock clk clk Input 1
#
# connection point reset
#
add_interface reset reset end
set_interface_property reset associatedClock clock
set_interface_property reset synchronousEdges DEASSERT
set_interface_property reset ENABLED true
set_interface_property reset EXPORT_OF ""
set_interface_property reset PORT_NAME_MAP ""
set_interface_property reset CMSIS_SVD_VARIABLES ""
set_interface_property reset SVD_ADDRESS_GROUP ""
add_interface_port reset reset reset Input 1
#
# connection point avalon_slave_0
#
add_interface avalon_slave_0 avalon end
set_interface_property avalon_slave_0 addressUnits WORDS
set_interface_property avalon_slave_0 associatedClock clock
set_interface_property avalon_slave_0 associatedReset reset
set_interface_property avalon_slave_0 bitsPerSymbol 8
set_interface_property avalon_slave_0 burstOnBurstBoundariesOnly false
set_interface_property avalon_slave_0 burstcountUnits WORDS
set_interface_property avalon_slave_0 explicitAddressSpan 0
set_interface_property avalon_slave_0 holdTime 0
set_interface_property avalon_slave_0 linewrapBursts false
set_interface_property avalon_slave_0 maximumPendingReadTransactions 0
set_interface_property avalon_slave_0 maximumPendingWriteTransactions 0
set_interface_property avalon_slave_0 readLatency 0
set_interface_property avalon_slave_0 readWaitTime 1
set_interface_property avalon_slave_0 setupTime 0
set_interface_property avalon_slave_0 timingUnits Cycles
set_interface_property avalon_slave_0 writeWaitTime 0
set_interface_property avalon_slave_0 ENABLED true
set_interface_property avalon_slave_0 EXPORT_OF ""
set_interface_property avalon_slave_0 PORT_NAME_MAP ""
set_interface_property avalon_slave_0 CMSIS_SVD_VARIABLES ""
set_interface_property avalon_slave_0 SVD_ADDRESS_GROUP ""
add_interface_port avalon_slave_0 address address Input 2
add_interface_port avalon_slave_0 read read Input 1
add_interface_port avalon_slave_0 write write Input 1
add_interface_port avalon_slave_0 readdata readdata Output 32
add_interface_port avalon_slave_0 writedata writedata Input 32
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isFlash 0
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isMemoryDevice 0
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isNonVolatileStorage 0
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isPrintableDevice 0
#
# connection point conduit_end
#
add_interface conduit_end conduit end
set_interface_property conduit_end associatedClock clock
set_interface_property conduit_end associatedReset ""
set_interface_property conduit_end ENABLED true
set_interface_property conduit_end EXPORT_OF ""
set_interface_property conduit_end PORT_NAME_MAP ""
set_interface_property conduit_end CMSIS_SVD_VARIABLES ""
set_interface_property conduit_end SVD_ADDRESS_GROUP ""
add_interface_port conduit_end pwm_out pwm Output 1

View File

@@ -0,0 +1,205 @@
-- #############################################################################
-- tb_pwm.vhd
-- ==========
-- Testbench for PWM memory-mapped Avalon slave interface.
--
-- Modified by : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
-- Revision : 2
-- Last modified : 2018-02-28
-- #############################################################################
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.pwm_constants.all;
entity tb_pwm is
end entity;
architecture rtl of tb_pwm is
-- 50 MHz clock
constant CLK_PERIOD : time := 20 ns;
-- Signal used to end simulator when we finished submitting our test cases
signal sim_finished : boolean := false;
-- PWM PORTS
signal clk : std_logic;
signal reset : std_logic;
signal address : std_logic_vector(1 downto 0);
signal read : std_logic;
signal write : std_logic;
signal readdata : std_logic_vector(31 downto 0);
signal writedata : std_logic_vector(31 downto 0);
signal pwm_out : std_logic;
-- Values of registers we are going to use to configure the PWM unit
constant CONFIG_PERIOD : natural := 100;
constant CONFIG_DUTY_CYCLE : natural := 20;
constant CONFIG_CTRL_START : natural := 1;
constant CONFIG_CTRL_STOP : natural := 0;
begin
-- Instantiate DUT
dut : entity work.pwm
port map(
clk => clk,
reset => reset,
address => address,
read => read,
write => write,
readdata => readdata,
writedata => writedata,
pwm_out => pwm_out
);
-- Generate clk signal
clk_generation : process
begin
if not sim_finished then
clk <= '1';
wait for CLK_PERIOD / 2;
clk <= '0';
wait for CLK_PERIOD / 2;
else
wait;
end if;
end process clk_generation;
-- Test PWM
simulation : process
procedure async_reset is
begin
wait until rising_edge(clk);
wait for CLK_PERIOD / 4;
reset <= '1';
wait for CLK_PERIOD / 2;
reset <= '0';
wait for CLK_PERIOD / 4;
end procedure async_reset;
procedure write_register(constant ofst : in std_logic_vector(1 downto 0);
constant val : in natural) is
begin
wait until rising_edge(clk);
address <= ofst;
write <= '1';
writedata <= std_logic_vector(to_unsigned(val, writedata'length));
wait until rising_edge(clk);
address <= (others => '0');
write <= '0';
writedata <= (others => '0');
wait until rising_edge(clk);
end procedure write_register;
procedure read_register(constant ofst : in std_logic_vector(1 downto 0)) is
begin
wait until rising_edge(clk);
address <= ofst;
read <= '1';
-- The read has a 1 cycle wait-state, so we need to keep the read
-- signal high for 2 clock cycles.
wait until rising_edge(clk);
wait until rising_edge(clk);
address <= (others => '0');
read <= '0';
wait until rising_edge(clk);
end procedure read_register;
procedure read_register_check(constant ofst : in std_logic_vector(1 downto 0);
constant expected_val : in natural) is
begin
read_register(ofst);
case ofst is
when REG_PERIOD_OFST =>
assert to_integer(unsigned(readdata)) = expected_val
report "Unexpected PERIOD: " &
"PERIOD = " & integer'image(to_integer(unsigned(readdata))) & "; " &
"PERIOD_expected = " & integer'image(expected_val)
severity error;
when REG_DUTY_CYCLE_OFST =>
assert to_integer(unsigned(readdata)) = expected_val
report "Unexpected DUTY_CYCLE: " &
"DUTY_CYCLE = " & integer'image(to_integer(unsigned(readdata))) & "; " &
"DUTY_CYCLE_expected = " & integer'image(expected_val)
severity error;
when REG_CTRL_OFST =>
assert to_integer(unsigned(readdata)) = expected_val
report "Unexpected CTRL: " &
"CTRL = " & integer'image(to_integer(unsigned(readdata))) & "; " &
"CTRL_expected = " & integer'image(expected_val)
severity error;
when others =>
null;
end case;
end procedure read_register_check;
begin
-- Default values
reset <= '0';
address <= (others => '0');
read <= '0';
write <= '0';
writedata <= (others => '0');
wait until rising_edge(clk);
-- Reset the circuit
async_reset;
-- Write desired configuration to PWM Avalon-MM slave.
write_register(REG_PERIOD_OFST, CONFIG_PERIOD);
write_register(REG_DUTY_CYCLE_OFST, CONFIG_DUTY_CYCLE);
-- Read back configuration from PWM Avalon-MM slave. Note that we have
-- not started the PWM unit yet, so the new configuration must not be
-- read back at this point (as per the register map).
read_register_check(REG_PERIOD_OFST, DEFAULT_PERIOD);
read_register_check(REG_DUTY_CYCLE_OFST, DEFAULT_DUTY_CYCLE);
read_register_check(REG_CTRL_OFST, 0);
-- Start PWM
write_register(REG_CTRL_OFST, CONFIG_CTRL_START);
-- Wait until PWM pulses for the first time after we sent START.
wait until rising_edge(pwm_out);
-- Read back configuration from PWM Avalon-MM slave. Now that we have
-- started the PWM unit, we should be able to read back the
-- configuration we wrote (as per the register map).
read_register_check(REG_PERIOD_OFST, CONFIG_PERIOD);
read_register_check(REG_DUTY_CYCLE_OFST, CONFIG_DUTY_CYCLE);
read_register_check(REG_CTRL_OFST, 0);
-- Wait for 2 PWM periods to finish
wait for 2 * CLK_PERIOD * CONFIG_PERIOD;
-- Stop PWM.
write_register(REG_CTRL_OFST, CONFIG_CTRL_STOP);
-- Wait for PWM period to finish
wait for 1 * CLK_PERIOD * CONFIG_PERIOD;
-- Instruct "clk_generation" process to halt execution.
sim_finished <= true;
-- Make this process wait indefinitely (it will never re-execute from
-- its beginning again).
wait;
end process simulation;
end architecture rtl;

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<library>
<!-- date: 2017.03.19.20:51:30 -->
<!-- generated by: ip-make-ipx -->
<!-- -->
<!-- 3 in ../../hdl/ -->
<!-- -->
<component
name="lepton"
file="../../hdl/lepton/hdl/lepton_hw.tcl"
displayName="lepton"
version="1.0"
description="IR Camera 80x60"
tags="AUTHORSHIP=Philemon Favrod &amp; Sahand Kashani-Akhavan /// CONNECTION_TYPES=avalon,clock,conduit,reset /// INTERNAL_COMPONENT=false"
categories="Camera"
factory="TclModuleFactory">
<tag2 key="ALLOW_GREYBOX_GENERATION" value="false" />
<tag2 key="COMPONENT_EDITABLE" value="true" />
<tag2 key="COMPONENT_HIDE_FROM_SOPC" value="true" />
<tag2 key="INSTANTIATE_IN_SYSTEM_MODULE" value="true" />
<tag2 key="OPAQUE_ADDRESS_MAP" value="true" />
<tag2 key="REPORT_HIERARCHY" value="false" />
<tag2 key="SUPPORTED_FILE_SETS" value="QUARTUS_SYNTH" />
<tag2 key="TCL_PACKAGE_VERSION" value="16.0" />
</component>
<component
name="mcp3204"
file="../../hdl/joysticks/hdl/mcp3204_hw.tcl"
displayName="mcp3204"
version="1.0"
description="4-Channel 12-Bit A/D Converter with SPI Serial Interface"
tags="AUTHORSHIP=Philemon Favrod &amp; Sahand Kashani-Akhavan /// CONNECTION_TYPES=avalon,clock,conduit,reset /// INTERNAL_COMPONENT=false"
categories="Joystick"
factory="TclModuleFactory">
<tag2 key="ALLOW_GREYBOX_GENERATION" value="false" />
<tag2 key="COMPONENT_EDITABLE" value="true" />
<tag2 key="COMPONENT_HIDE_FROM_SOPC" value="true" />
<tag2 key="INSTANTIATE_IN_SYSTEM_MODULE" value="true" />
<tag2 key="OPAQUE_ADDRESS_MAP" value="true" />
<tag2 key="REPORT_HIERARCHY" value="false" />
<tag2 key="SUPPORTED_FILE_SETS" value="QUARTUS_SYNTH" />
<tag2 key="TCL_PACKAGE_VERSION" value="16.0" />
</component>
<component
name="pwm"
file="../../hdl/pantilt/hdl/pwm_hw.tcl"
displayName="pwm"
version="1.0"
description="Pan-tilt"
tags="AUTHORSHIP= /// CONNECTION_TYPES=avalon,clock,conduit,reset /// INTERNAL_COMPONENT=false"
categories="Pan-tilt"
factory="TclModuleFactory">
<tag2 key="ALLOW_GREYBOX_GENERATION" value="false" />
<tag2 key="COMPONENT_EDITABLE" value="true" />
<tag2 key="COMPONENT_HIDE_FROM_SOPC" value="true" />
<tag2 key="INSTANTIATE_IN_SYSTEM_MODULE" value="true" />
<tag2 key="OPAQUE_ADDRESS_MAP" value="true" />
<tag2 key="REPORT_HIERARCHY" value="false" />
<tag2 key="SUPPORTED_FILE_SETS" value="QUARTUS_SYNTH" />
<tag2 key="TCL_PACKAGE_VERSION" value="16.0" />
</component>
</library>

View File

@@ -0,0 +1,31 @@
# -------------------------------------------------------------------------- #
#
# Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
# Your use of Altera Corporation's design tools, logic functions
# and other software and tools, and its AMPP partner logic
# functions, and any output files from any of the foregoing
# (including device programming or simulation files), and any
# associated documentation or information are expressly subject
# to the terms and conditions of the Altera Program License
# Subscription Agreement, the Altera Quartus Prime License Agreement,
# the Altera MegaCore Function License Agreement, or other
# applicable license agreement, including, without limitation,
# that your use is for the sole purpose of programming logic
# devices manufactured by Altera and sold by Altera or its
# authorized distributors. Please refer to the applicable
# agreement for further details.
#
# -------------------------------------------------------------------------- #
#
# Quartus Prime
# Version 15.1.0 Build 185 10/21/2015 SJ Lite Edition
# Date created = 11:03:02 February 05, 2016
#
# -------------------------------------------------------------------------- #
QUARTUS_VERSION = "15.1"
DATE = "11:03:02 February 05, 2016"
# Revisions
PROJECT_REVISION = "lab_4_1"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
create_clock -period 20 [get_ports FPGA_CLK1_50]
create_clock -period 20 [get_ports FPGA_CLK2_50]
create_clock -period 20 [get_ports FPGA_CLK3_50]
derive_pll_clocks
derive_clock_uncertainty

View File

@@ -0,0 +1,915 @@
<?xml version="1.0" encoding="UTF-8"?>
<system name="$${FILENAME}">
<component
name="$${FILENAME}"
displayName="$${FILENAME}"
version="1.0"
description=""
tags=""
categories="System" />
<parameter name="bonusData"><![CDATA[bonusData
{
element clk_0
{
datum _sortIndex
{
value = "1";
type = "int";
}
}
element hps_0
{
datum _sortIndex
{
value = "0";
type = "int";
}
}
element lepton_0
{
datum _sortIndex
{
value = "5";
type = "int";
}
}
element lepton_0.avalon_slave_0
{
datum baseAddress
{
value = "262144";
type = "String";
}
}
element mcp3204_0
{
datum _sortIndex
{
value = "4";
type = "int";
}
}
element mcp3204_0.avalon_slave_0
{
datum baseAddress
{
value = "299008";
type = "String";
}
}
element pwm_0
{
datum _sortIndex
{
value = "2";
type = "int";
}
}
element pwm_0.avalon_slave_0
{
datum baseAddress
{
value = "299040";
type = "String";
}
}
element pwm_1
{
datum _sortIndex
{
value = "3";
type = "int";
}
}
element pwm_1.avalon_slave_0
{
datum baseAddress
{
value = "299024";
type = "String";
}
}
element soc_system
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system_nios_only
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system_nios_only
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system_nios_only
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system_nios_only
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system_nios_only
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system_nios_only
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
element soc_system_nios_only
{
datum _originalDeviceFamily
{
value = "Cyclone V";
type = "String";
}
}
}
]]></parameter>
<parameter name="clockCrossingAdapter" value="HANDSHAKE" />
<parameter name="device" value="5CSEMA4U23C6" />
<parameter name="deviceFamily" value="Cyclone V" />
<parameter name="deviceSpeedGrade" value="6" />
<parameter name="fabricMode" value="QSYS" />
<parameter name="generateLegacySim" value="false" />
<parameter name="generationId" value="0" />
<parameter name="globalResetBus" value="false" />
<parameter name="hdlLanguage" value="VERILOG" />
<parameter name="hideFromIPCatalog" value="false" />
<parameter name="lockedInterfaceDefinition" value="" />
<parameter name="maxAdditionalLatency" value="1" />
<parameter name="projectName" value="lab_4_1.qpf" />
<parameter name="sopcBorderPoints" value="false" />
<parameter name="systemHash" value="0" />
<parameter name="testBenchDutName" value="" />
<parameter name="timeStamp" value="0" />
<parameter name="useTestBenchNamingPattern" value="false" />
<instanceScript></instanceScript>
<interface name="clk" internal="clk_0.clk_in" type="clock" dir="end" />
<interface name="hps_0_ddr" internal="hps_0.memory" type="conduit" dir="end" />
<interface name="hps_0_io" internal="hps_0.hps_io" type="conduit" dir="end" />
<interface name="lepton_0_conduit_end" internal="lepton_0.conduit_end" />
<interface name="lepton_0_spi" internal="lepton_0.spi" type="conduit" dir="end" />
<interface
name="mcp3204_0_conduit_end"
internal="mcp3204_0.conduit_end"
type="conduit"
dir="end" />
<interface
name="pwm_0_conduit_end"
internal="pwm_0.conduit_end"
type="conduit"
dir="end" />
<interface
name="pwm_1_conduit_end"
internal="pwm_1.conduit_end"
type="conduit"
dir="end" />
<interface name="reset" internal="clk_0.clk_in_reset" type="reset" dir="end" />
<module name="clk_0" kind="clock_source" version="18.1" enabled="1">
<parameter name="clockFrequency" value="50000000" />
<parameter name="clockFrequencyKnown" value="true" />
<parameter name="inputClockFrequency" value="0" />
<parameter name="resetSynchronousEdges" value="NONE" />
</module>
<module name="hps_0" kind="altera_hps" version="18.1" enabled="1">
<parameter name="ABSTRACT_REAL_COMPARE_TEST" value="false" />
<parameter name="ABS_RAM_MEM_INIT_FILENAME" value="meminit" />
<parameter name="ACV_PHY_CLK_ADD_FR_PHASE" value="0.0" />
<parameter name="AC_PACKAGE_DESKEW" value="false" />
<parameter name="AC_ROM_USER_ADD_0" value="0_0000_0000_0000" />
<parameter name="AC_ROM_USER_ADD_1" value="0_0000_0000_1000" />
<parameter name="ADDR_ORDER" value="0" />
<parameter name="ADD_EFFICIENCY_MONITOR" value="false" />
<parameter name="ADD_EXTERNAL_SEQ_DEBUG_NIOS" value="false" />
<parameter name="ADVANCED_CK_PHASES" value="false" />
<parameter name="ADVERTIZE_SEQUENCER_SW_BUILD_FILES" value="false" />
<parameter name="AFI_DEBUG_INFO_WIDTH" value="32" />
<parameter name="ALTMEMPHY_COMPATIBLE_MODE" value="false" />
<parameter name="AP_MODE" value="false" />
<parameter name="AP_MODE_EN" value="0" />
<parameter name="AUTO_DEVICE_SPEEDGRADE" value="6" />
<parameter name="AUTO_PD_CYCLES" value="0" />
<parameter name="AUTO_POWERDN_EN" value="false" />
<parameter name="AVL_DATA_WIDTH_PORT" value="32,32,32,32,32,32" />
<parameter name="AVL_MAX_SIZE" value="4" />
<parameter name="BONDING_OUT_ENABLED" value="false" />
<parameter name="BOOTFROMFPGA_Enable" value="false" />
<parameter name="BSEL" value="1" />
<parameter name="BSEL_EN" value="false" />
<parameter name="BYTE_ENABLE" value="true" />
<parameter name="C2P_WRITE_CLOCK_ADD_PHASE" value="0.0" />
<parameter name="CALIBRATION_MODE" value="Skip" />
<parameter name="CALIB_REG_WIDTH" value="8" />
<parameter name="CAN0_Mode" value="N/A" />
<parameter name="CAN0_PinMuxing" value="Unused" />
<parameter name="CAN1_Mode" value="N/A" />
<parameter name="CAN1_PinMuxing" value="Unused" />
<parameter name="CFG_DATA_REORDERING_TYPE" value="INTER_BANK" />
<parameter name="CFG_REORDER_DATA" value="true" />
<parameter name="CFG_TCCD_NS" value="2.5" />
<parameter name="COMMAND_PHASE" value="0.0" />
<parameter name="CONTROLLER_LATENCY" value="5" />
<parameter name="CORE_DEBUG_CONNECTION" value="EXPORT" />
<parameter name="CPORT_TYPE_PORT">Bidirectional,Bidirectional,Bidirectional,Bidirectional,Bidirectional,Bidirectional</parameter>
<parameter name="CSEL" value="0" />
<parameter name="CSEL_EN" value="false" />
<parameter name="CTI_Enable" value="false" />
<parameter name="CTL_AUTOPCH_EN" value="false" />
<parameter name="CTL_CMD_QUEUE_DEPTH" value="8" />
<parameter name="CTL_CSR_CONNECTION" value="INTERNAL_JTAG" />
<parameter name="CTL_CSR_ENABLED" value="false" />
<parameter name="CTL_CSR_READ_ONLY" value="1" />
<parameter name="CTL_DEEP_POWERDN_EN" value="false" />
<parameter name="CTL_DYNAMIC_BANK_ALLOCATION" value="false" />
<parameter name="CTL_DYNAMIC_BANK_NUM" value="4" />
<parameter name="CTL_ECC_AUTO_CORRECTION_ENABLED" value="false" />
<parameter name="CTL_ECC_ENABLED" value="false" />
<parameter name="CTL_ENABLE_BURST_INTERRUPT" value="false" />
<parameter name="CTL_ENABLE_BURST_TERMINATE" value="false" />
<parameter name="CTL_HRB_ENABLED" value="false" />
<parameter name="CTL_LOOK_AHEAD_DEPTH" value="4" />
<parameter name="CTL_SELF_REFRESH_EN" value="false" />
<parameter name="CTL_USR_REFRESH_EN" value="false" />
<parameter name="CTL_ZQCAL_EN" value="false" />
<parameter name="CUT_NEW_FAMILY_TIMING" value="true" />
<parameter name="DAT_DATA_WIDTH" value="32" />
<parameter name="DEBUGAPB_Enable" value="false" />
<parameter name="DEBUG_MODE" value="false" />
<parameter name="DEVICE_DEPTH" value="1" />
<parameter name="DEVICE_FAMILY_PARAM" value="" />
<parameter name="DISABLE_CHILD_MESSAGING" value="false" />
<parameter name="DISCRETE_FLY_BY" value="true" />
<parameter name="DLL_SHARING_MODE" value="None" />
<parameter name="DMA_Enable">No,No,No,No,No,No,No,No</parameter>
<parameter name="DQS_DQSN_MODE" value="DIFFERENTIAL" />
<parameter name="DQ_INPUT_REG_USE_CLKN" value="false" />
<parameter name="DUPLICATE_AC" value="false" />
<parameter name="ED_EXPORT_SEQ_DEBUG" value="false" />
<parameter name="EMAC0_Mode" value="N/A" />
<parameter name="EMAC0_PTP" value="false" />
<parameter name="EMAC0_PinMuxing" value="Unused" />
<parameter name="EMAC1_Mode" value="RGMII" />
<parameter name="EMAC1_PTP" value="false" />
<parameter name="EMAC1_PinMuxing" value="HPS I/O Set 0" />
<parameter name="ENABLE_ABS_RAM_MEM_INIT" value="false" />
<parameter name="ENABLE_BONDING" value="false" />
<parameter name="ENABLE_BURST_MERGE" value="false" />
<parameter name="ENABLE_CTRL_AVALON_INTERFACE" value="true" />
<parameter name="ENABLE_DELAY_CHAIN_WRITE" value="false" />
<parameter name="ENABLE_EMIT_BFM_MASTER" value="false" />
<parameter name="ENABLE_EXPORT_SEQ_DEBUG_BRIDGE" value="false" />
<parameter name="ENABLE_EXTRA_REPORTING" value="false" />
<parameter name="ENABLE_ISS_PROBES" value="false" />
<parameter name="ENABLE_NON_DESTRUCTIVE_CALIB" value="false" />
<parameter name="ENABLE_NON_DES_CAL" value="false" />
<parameter name="ENABLE_NON_DES_CAL_TEST" value="false" />
<parameter name="ENABLE_SEQUENCER_MARGINING_ON_BY_DEFAULT" value="false" />
<parameter name="ENABLE_USER_ECC" value="false" />
<parameter name="EXPORT_AFI_HALF_CLK" value="false" />
<parameter name="EXTRA_SETTINGS" value="" />
<parameter name="F2H_AXI_CLOCK_FREQ" value="100" />
<parameter name="F2H_SDRAM0_CLOCK_FREQ" value="100" />
<parameter name="F2H_SDRAM1_CLOCK_FREQ" value="100" />
<parameter name="F2H_SDRAM2_CLOCK_FREQ" value="100" />
<parameter name="F2H_SDRAM3_CLOCK_FREQ" value="100" />
<parameter name="F2H_SDRAM4_CLOCK_FREQ" value="100" />
<parameter name="F2H_SDRAM5_CLOCK_FREQ" value="100" />
<parameter name="F2SCLK_COLDRST_Enable" value="false" />
<parameter name="F2SCLK_DBGRST_Enable" value="false" />
<parameter name="F2SCLK_PERIPHCLK_Enable" value="false" />
<parameter name="F2SCLK_PERIPHCLK_FREQ" value="0" />
<parameter name="F2SCLK_SDRAMCLK_Enable" value="false" />
<parameter name="F2SCLK_SDRAMCLK_FREQ" value="0" />
<parameter name="F2SCLK_WARMRST_Enable" value="false" />
<parameter name="F2SDRAM_Type" value="" />
<parameter name="F2SDRAM_Width" value="" />
<parameter name="F2SINTERRUPT_Enable" value="false" />
<parameter name="F2S_Width" value="0" />
<parameter name="FIX_READ_LATENCY" value="8" />
<parameter name="FORCED_NON_LDC_ADDR_CMD_MEM_CK_INVERT" value="false" />
<parameter name="FORCED_NUM_WRITE_FR_CYCLE_SHIFTS" value="0" />
<parameter name="FORCE_DQS_TRACKING" value="AUTO" />
<parameter name="FORCE_MAX_LATENCY_COUNT_WIDTH" value="0" />
<parameter name="FORCE_SEQUENCER_TCL_DEBUG_MODE" value="false" />
<parameter name="FORCE_SHADOW_REGS" value="AUTO" />
<parameter name="FORCE_SYNTHESIS_LANGUAGE" value="" />
<parameter name="FPGA_PERIPHERAL_INPUT_CLOCK_FREQ_EMAC0_RX_CLK_IN" value="100" />
<parameter name="FPGA_PERIPHERAL_INPUT_CLOCK_FREQ_EMAC0_TX_CLK_IN" value="100" />
<parameter name="FPGA_PERIPHERAL_INPUT_CLOCK_FREQ_EMAC1_RX_CLK_IN" value="100" />
<parameter name="FPGA_PERIPHERAL_INPUT_CLOCK_FREQ_EMAC1_TX_CLK_IN" value="100" />
<parameter
name="FPGA_PERIPHERAL_INPUT_CLOCK_FREQ_EMAC_PTP_REF_CLOCK"
value="100" />
<parameter name="FPGA_PERIPHERAL_INPUT_CLOCK_FREQ_I2C0_SCL_IN" value="100" />
<parameter name="FPGA_PERIPHERAL_INPUT_CLOCK_FREQ_I2C1_SCL_IN" value="100" />
<parameter name="FPGA_PERIPHERAL_INPUT_CLOCK_FREQ_I2C2_SCL_IN" value="100" />
<parameter name="FPGA_PERIPHERAL_INPUT_CLOCK_FREQ_I2C3_SCL_IN" value="100" />
<parameter name="FPGA_PERIPHERAL_INPUT_CLOCK_FREQ_SPIS0_SCLK_IN" value="100" />
<parameter name="FPGA_PERIPHERAL_INPUT_CLOCK_FREQ_SPIS1_SCLK_IN" value="100" />
<parameter name="FPGA_PERIPHERAL_INPUT_CLOCK_FREQ_USB0_CLK_IN" value="100" />
<parameter name="FPGA_PERIPHERAL_INPUT_CLOCK_FREQ_USB1_CLK_IN" value="100" />
<parameter name="FPGA_PERIPHERAL_OUTPUT_CLOCK_FREQ_EMAC0_GTX_CLK" value="125" />
<parameter name="FPGA_PERIPHERAL_OUTPUT_CLOCK_FREQ_EMAC0_MD_CLK" value="2.5" />
<parameter name="FPGA_PERIPHERAL_OUTPUT_CLOCK_FREQ_EMAC1_GTX_CLK" value="125" />
<parameter name="FPGA_PERIPHERAL_OUTPUT_CLOCK_FREQ_EMAC1_MD_CLK" value="2.5" />
<parameter name="FPGA_PERIPHERAL_OUTPUT_CLOCK_FREQ_I2C0_CLK" value="100" />
<parameter name="FPGA_PERIPHERAL_OUTPUT_CLOCK_FREQ_I2C1_CLK" value="100" />
<parameter name="FPGA_PERIPHERAL_OUTPUT_CLOCK_FREQ_I2C2_CLK" value="100" />
<parameter name="FPGA_PERIPHERAL_OUTPUT_CLOCK_FREQ_I2C3_CLK" value="100" />
<parameter name="FPGA_PERIPHERAL_OUTPUT_CLOCK_FREQ_QSPI_SCLK_OUT" value="100" />
<parameter name="FPGA_PERIPHERAL_OUTPUT_CLOCK_FREQ_SDIO_CCLK" value="100" />
<parameter name="FPGA_PERIPHERAL_OUTPUT_CLOCK_FREQ_SPIM0_SCLK_OUT" value="100" />
<parameter name="FPGA_PERIPHERAL_OUTPUT_CLOCK_FREQ_SPIM1_SCLK_OUT" value="100" />
<parameter name="GPIO_Enable">No,No,No,No,No,No,No,No,No,Yes,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,Yes,No,No,No,No,Yes,No,No,No,No,No,No,No,No,No,No,No,No,No,Yes,No,No,No,No,No,No,Yes,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No</parameter>
<parameter name="GP_Enable" value="false" />
<parameter name="H2F_AXI_CLOCK_FREQ" value="100" />
<parameter name="H2F_CTI_CLOCK_FREQ" value="100" />
<parameter name="H2F_DEBUG_APB_CLOCK_FREQ" value="100" />
<parameter name="H2F_LW_AXI_CLOCK_FREQ" value="50000000" />
<parameter name="H2F_TPIU_CLOCK_IN_FREQ" value="100" />
<parameter name="HARD_EMIF" value="true" />
<parameter name="HCX_COMPAT_MODE" value="false" />
<parameter name="HHP_HPS" value="true" />
<parameter name="HHP_HPS_SIMULATION" value="false" />
<parameter name="HHP_HPS_VERIFICATION" value="false" />
<parameter name="HLGPI_Enable" value="false" />
<parameter name="HPS_PROTOCOL" value="DDR3" />
<parameter name="I2C0_Mode" value="I2C" />
<parameter name="I2C0_PinMuxing" value="HPS I/O Set 0" />
<parameter name="I2C1_Mode" value="I2C" />
<parameter name="I2C1_PinMuxing" value="HPS I/O Set 0" />
<parameter name="I2C2_Mode" value="N/A" />
<parameter name="I2C2_PinMuxing" value="Unused" />
<parameter name="I2C3_Mode" value="N/A" />
<parameter name="I2C3_PinMuxing" value="Unused" />
<parameter name="INCLUDE_BOARD_DELAY_MODEL" value="false" />
<parameter name="INCLUDE_MULTIRANK_BOARD_DELAY_MODEL" value="false" />
<parameter name="IS_ES_DEVICE" value="false" />
<parameter name="LOANIO_Enable">No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No</parameter>
<parameter name="LOCAL_ID_WIDTH" value="8" />
<parameter name="LRDIMM_EXTENDED_CONFIG">0x000000000000000000</parameter>
<parameter name="LWH2F_Enable" value="true" />
<parameter name="MARGIN_VARIATION_TEST" value="false" />
<parameter name="MAX_PENDING_RD_CMD" value="32" />
<parameter name="MAX_PENDING_WR_CMD" value="16" />
<parameter name="MEM_ASR" value="Manual" />
<parameter name="MEM_ATCL" value="Disabled" />
<parameter name="MEM_AUTO_LEVELING_MODE" value="true" />
<parameter name="MEM_BANKADDR_WIDTH" value="3" />
<parameter name="MEM_BL" value="OTF" />
<parameter name="MEM_BT" value="Sequential" />
<parameter name="MEM_CK_PHASE" value="0.0" />
<parameter name="MEM_CK_WIDTH" value="1" />
<parameter name="MEM_CLK_EN_WIDTH" value="1" />
<parameter name="MEM_CLK_FREQ" value="400.0" />
<parameter name="MEM_CLK_FREQ_MAX" value="800.0" />
<parameter name="MEM_COL_ADDR_WIDTH" value="10" />
<parameter name="MEM_CS_WIDTH" value="1" />
<parameter name="MEM_DEVICE" value="MISSING_MODEL" />
<parameter name="MEM_DLL_EN" value="true" />
<parameter name="MEM_DQ_PER_DQS" value="8" />
<parameter name="MEM_DQ_WIDTH" value="32" />
<parameter name="MEM_DRV_STR" value="RZQ/6" />
<parameter name="MEM_FORMAT" value="DISCRETE" />
<parameter name="MEM_GUARANTEED_WRITE_INIT" value="false" />
<parameter name="MEM_IF_BOARD_BASE_DELAY" value="10" />
<parameter name="MEM_IF_DM_PINS_EN" value="true" />
<parameter name="MEM_IF_DQSN_EN" value="true" />
<parameter name="MEM_IF_SIM_VALID_WINDOW" value="0" />
<parameter name="MEM_INIT_EN" value="false" />
<parameter name="MEM_INIT_FILE" value="" />
<parameter name="MEM_MIRROR_ADDRESSING" value="0" />
<parameter name="MEM_NUMBER_OF_DIMMS" value="1" />
<parameter name="MEM_NUMBER_OF_RANKS_PER_DEVICE" value="1" />
<parameter name="MEM_NUMBER_OF_RANKS_PER_DIMM" value="1" />
<parameter name="MEM_PD" value="DLL off" />
<parameter name="MEM_RANK_MULTIPLICATION_FACTOR" value="1" />
<parameter name="MEM_ROW_ADDR_WIDTH" value="15" />
<parameter name="MEM_RTT_NOM" value="RZQ/6" />
<parameter name="MEM_RTT_WR" value="Dynamic ODT off" />
<parameter name="MEM_SRT" value="Normal" />
<parameter name="MEM_TCL" value="7" />
<parameter name="MEM_TFAW_NS" value="37.5" />
<parameter name="MEM_TINIT_US" value="500" />
<parameter name="MEM_TMRD_CK" value="4" />
<parameter name="MEM_TRAS_NS" value="35.0" />
<parameter name="MEM_TRCD_NS" value="13.75" />
<parameter name="MEM_TREFI_US" value="7.8" />
<parameter name="MEM_TRFC_NS" value="300.0" />
<parameter name="MEM_TRP_NS" value="13.75" />
<parameter name="MEM_TRRD_NS" value="7.5" />
<parameter name="MEM_TRTP_NS" value="7.5" />
<parameter name="MEM_TWR_NS" value="15.0" />
<parameter name="MEM_TWTR" value="4" />
<parameter name="MEM_USER_LEVELING_MODE" value="Leveling" />
<parameter name="MEM_VENDOR" value="Other" />
<parameter name="MEM_VERBOSE" value="true" />
<parameter name="MEM_VOLTAGE" value="1.5V DDR3" />
<parameter name="MEM_WTCL" value="7" />
<parameter name="MPU_EVENTS_Enable" value="false" />
<parameter name="MRS_MIRROR_PING_PONG_ATSO" value="false" />
<parameter name="MULTICAST_EN" value="false" />
<parameter name="NAND_Mode" value="N/A" />
<parameter name="NAND_PinMuxing" value="Unused" />
<parameter name="NEXTGEN" value="true" />
<parameter name="NIOS_ROM_DATA_WIDTH" value="32" />
<parameter name="NUM_DLL_SHARING_INTERFACES" value="1" />
<parameter name="NUM_EXTRA_REPORT_PATH" value="10" />
<parameter name="NUM_OCT_SHARING_INTERFACES" value="1" />
<parameter name="NUM_OF_PORTS" value="1" />
<parameter name="NUM_PLL_SHARING_INTERFACES" value="1" />
<parameter name="OCT_SHARING_MODE" value="None" />
<parameter name="P2C_READ_CLOCK_ADD_PHASE" value="0.0" />
<parameter name="PACKAGE_DESKEW" value="false" />
<parameter name="PARSE_FRIENDLY_DEVICE_FAMILY_PARAM" value="" />
<parameter name="PARSE_FRIENDLY_DEVICE_FAMILY_PARAM_VALID" value="false" />
<parameter name="PHY_CSR_CONNECTION" value="INTERNAL_JTAG" />
<parameter name="PHY_CSR_ENABLED" value="false" />
<parameter name="PHY_ONLY" value="false" />
<parameter name="PINGPONGPHY_EN" value="false" />
<parameter name="PLL_ADDR_CMD_CLK_DIV_PARAM" value="0" />
<parameter name="PLL_ADDR_CMD_CLK_FREQ_PARAM" value="0.0" />
<parameter name="PLL_ADDR_CMD_CLK_FREQ_SIM_STR_PARAM" value="" />
<parameter name="PLL_ADDR_CMD_CLK_MULT_PARAM" value="0" />
<parameter name="PLL_ADDR_CMD_CLK_PHASE_PS_PARAM" value="0" />
<parameter name="PLL_ADDR_CMD_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
<parameter name="PLL_AFI_CLK_DIV_PARAM" value="0" />
<parameter name="PLL_AFI_CLK_FREQ_PARAM" value="0.0" />
<parameter name="PLL_AFI_CLK_FREQ_SIM_STR_PARAM" value="" />
<parameter name="PLL_AFI_CLK_MULT_PARAM" value="0" />
<parameter name="PLL_AFI_CLK_PHASE_PS_PARAM" value="0" />
<parameter name="PLL_AFI_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
<parameter name="PLL_AFI_HALF_CLK_DIV_PARAM" value="0" />
<parameter name="PLL_AFI_HALF_CLK_FREQ_PARAM" value="0.0" />
<parameter name="PLL_AFI_HALF_CLK_FREQ_SIM_STR_PARAM" value="" />
<parameter name="PLL_AFI_HALF_CLK_MULT_PARAM" value="0" />
<parameter name="PLL_AFI_HALF_CLK_PHASE_PS_PARAM" value="0" />
<parameter name="PLL_AFI_HALF_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
<parameter name="PLL_AFI_PHY_CLK_DIV_PARAM" value="0" />
<parameter name="PLL_AFI_PHY_CLK_FREQ_PARAM" value="0.0" />
<parameter name="PLL_AFI_PHY_CLK_FREQ_SIM_STR_PARAM" value="" />
<parameter name="PLL_AFI_PHY_CLK_MULT_PARAM" value="0" />
<parameter name="PLL_AFI_PHY_CLK_PHASE_PS_PARAM" value="0" />
<parameter name="PLL_AFI_PHY_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
<parameter name="PLL_C2P_WRITE_CLK_DIV_PARAM" value="0" />
<parameter name="PLL_C2P_WRITE_CLK_FREQ_PARAM" value="0.0" />
<parameter name="PLL_C2P_WRITE_CLK_FREQ_SIM_STR_PARAM" value="" />
<parameter name="PLL_C2P_WRITE_CLK_MULT_PARAM" value="0" />
<parameter name="PLL_C2P_WRITE_CLK_PHASE_PS_PARAM" value="0" />
<parameter name="PLL_C2P_WRITE_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
<parameter name="PLL_CLK_PARAM_VALID" value="false" />
<parameter name="PLL_CONFIG_CLK_DIV_PARAM" value="0" />
<parameter name="PLL_CONFIG_CLK_FREQ_PARAM" value="0.0" />
<parameter name="PLL_CONFIG_CLK_FREQ_SIM_STR_PARAM" value="" />
<parameter name="PLL_CONFIG_CLK_MULT_PARAM" value="0" />
<parameter name="PLL_CONFIG_CLK_PHASE_PS_PARAM" value="0" />
<parameter name="PLL_CONFIG_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
<parameter name="PLL_DR_CLK_DIV_PARAM" value="0" />
<parameter name="PLL_DR_CLK_FREQ_PARAM" value="0.0" />
<parameter name="PLL_DR_CLK_FREQ_SIM_STR_PARAM" value="" />
<parameter name="PLL_DR_CLK_MULT_PARAM" value="0" />
<parameter name="PLL_DR_CLK_PHASE_PS_PARAM" value="0" />
<parameter name="PLL_DR_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
<parameter name="PLL_HR_CLK_DIV_PARAM" value="0" />
<parameter name="PLL_HR_CLK_FREQ_PARAM" value="0.0" />
<parameter name="PLL_HR_CLK_FREQ_SIM_STR_PARAM" value="" />
<parameter name="PLL_HR_CLK_MULT_PARAM" value="0" />
<parameter name="PLL_HR_CLK_PHASE_PS_PARAM" value="0" />
<parameter name="PLL_HR_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
<parameter name="PLL_LOCATION" value="Top_Bottom" />
<parameter name="PLL_MEM_CLK_DIV_PARAM" value="0" />
<parameter name="PLL_MEM_CLK_FREQ_PARAM" value="0.0" />
<parameter name="PLL_MEM_CLK_FREQ_SIM_STR_PARAM" value="" />
<parameter name="PLL_MEM_CLK_MULT_PARAM" value="0" />
<parameter name="PLL_MEM_CLK_PHASE_PS_PARAM" value="0" />
<parameter name="PLL_MEM_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
<parameter name="PLL_NIOS_CLK_DIV_PARAM" value="0" />
<parameter name="PLL_NIOS_CLK_FREQ_PARAM" value="0.0" />
<parameter name="PLL_NIOS_CLK_FREQ_SIM_STR_PARAM" value="" />
<parameter name="PLL_NIOS_CLK_MULT_PARAM" value="0" />
<parameter name="PLL_NIOS_CLK_PHASE_PS_PARAM" value="0" />
<parameter name="PLL_NIOS_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
<parameter name="PLL_P2C_READ_CLK_DIV_PARAM" value="0" />
<parameter name="PLL_P2C_READ_CLK_FREQ_PARAM" value="0.0" />
<parameter name="PLL_P2C_READ_CLK_FREQ_SIM_STR_PARAM" value="" />
<parameter name="PLL_P2C_READ_CLK_MULT_PARAM" value="0" />
<parameter name="PLL_P2C_READ_CLK_PHASE_PS_PARAM" value="0" />
<parameter name="PLL_P2C_READ_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
<parameter name="PLL_SHARING_MODE" value="None" />
<parameter name="PLL_WRITE_CLK_DIV_PARAM" value="0" />
<parameter name="PLL_WRITE_CLK_FREQ_PARAM" value="0.0" />
<parameter name="PLL_WRITE_CLK_FREQ_SIM_STR_PARAM" value="" />
<parameter name="PLL_WRITE_CLK_MULT_PARAM" value="0" />
<parameter name="PLL_WRITE_CLK_PHASE_PS_PARAM" value="0" />
<parameter name="PLL_WRITE_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
<parameter name="POWER_OF_TWO_BUS" value="false" />
<parameter name="PRIORITY_PORT" value="1,1,1,1,1,1" />
<parameter name="QSPI_Mode" value="N/A" />
<parameter name="QSPI_PinMuxing" value="Unused" />
<parameter name="RATE" value="Full" />
<parameter name="RDIMM_CONFIG" value="0000000000000000" />
<parameter name="READ_DQ_DQS_CLOCK_SOURCE" value="INVERTED_DQS_BUS" />
<parameter name="READ_FIFO_SIZE" value="8" />
<parameter name="REFRESH_BURST_VALIDATION" value="false" />
<parameter name="REFRESH_INTERVAL" value="15000" />
<parameter name="REF_CLK_FREQ" value="25.0" />
<parameter name="REF_CLK_FREQ_MAX_PARAM" value="0.0" />
<parameter name="REF_CLK_FREQ_MIN_PARAM" value="0.0" />
<parameter name="REF_CLK_FREQ_PARAM_VALID" value="false" />
<parameter name="S2FCLK_COLDRST_Enable" value="false" />
<parameter name="S2FCLK_PENDINGRST_Enable" value="false" />
<parameter name="S2FCLK_USER0CLK_Enable" value="false" />
<parameter name="S2FCLK_USER1CLK_Enable" value="false" />
<parameter name="S2FCLK_USER1CLK_FREQ" value="100.0" />
<parameter name="S2FCLK_USER2CLK" value="1" />
<parameter name="S2FCLK_USER2CLK_Enable" value="false" />
<parameter name="S2FCLK_USER2CLK_FREQ" value="100.0" />
<parameter name="S2FINTERRUPT_CAN_Enable" value="false" />
<parameter name="S2FINTERRUPT_CLOCKPERIPHERAL_Enable" value="false" />
<parameter name="S2FINTERRUPT_CTI_Enable" value="false" />
<parameter name="S2FINTERRUPT_DMA_Enable" value="false" />
<parameter name="S2FINTERRUPT_EMAC_Enable" value="false" />
<parameter name="S2FINTERRUPT_FPGAMANAGER_Enable" value="false" />
<parameter name="S2FINTERRUPT_GPIO_Enable" value="false" />
<parameter name="S2FINTERRUPT_I2CEMAC_Enable" value="false" />
<parameter name="S2FINTERRUPT_I2CPERIPHERAL_Enable" value="false" />
<parameter name="S2FINTERRUPT_L4TIMER_Enable" value="false" />
<parameter name="S2FINTERRUPT_NAND_Enable" value="false" />
<parameter name="S2FINTERRUPT_OSCTIMER_Enable" value="false" />
<parameter name="S2FINTERRUPT_QSPI_Enable" value="false" />
<parameter name="S2FINTERRUPT_SDMMC_Enable" value="false" />
<parameter name="S2FINTERRUPT_SPIMASTER_Enable" value="false" />
<parameter name="S2FINTERRUPT_SPISLAVE_Enable" value="false" />
<parameter name="S2FINTERRUPT_UART_Enable" value="false" />
<parameter name="S2FINTERRUPT_USB_Enable" value="false" />
<parameter name="S2FINTERRUPT_WATCHDOG_Enable" value="false" />
<parameter name="S2F_Width" value="0" />
<parameter name="SDIO_Mode" value="4-bit Data" />
<parameter name="SDIO_PinMuxing" value="HPS I/O Set 0" />
<parameter name="SEQUENCER_TYPE" value="NIOS" />
<parameter name="SEQ_MODE" value="0" />
<parameter name="SKIP_MEM_INIT" value="true" />
<parameter name="SOPC_COMPAT_RESET" value="false" />
<parameter name="SPEED_GRADE" value="7" />
<parameter name="SPIM0_Mode" value="N/A" />
<parameter name="SPIM0_PinMuxing" value="Unused" />
<parameter name="SPIM1_Mode" value="Single Slave Select" />
<parameter name="SPIM1_PinMuxing" value="HPS I/O Set 0" />
<parameter name="SPIS0_Mode" value="N/A" />
<parameter name="SPIS0_PinMuxing" value="Unused" />
<parameter name="SPIS1_Mode" value="N/A" />
<parameter name="SPIS1_PinMuxing" value="Unused" />
<parameter name="STARVE_LIMIT" value="10" />
<parameter name="STM_Enable" value="false" />
<parameter name="SYS_INFO_DEVICE_FAMILY" value="Cyclone V" />
<parameter name="TEST_Enable" value="false" />
<parameter name="TIMING_BOARD_AC_EYE_REDUCTION_H" value="0.0" />
<parameter name="TIMING_BOARD_AC_EYE_REDUCTION_SU" value="0.0" />
<parameter name="TIMING_BOARD_AC_SKEW" value="0.02" />
<parameter name="TIMING_BOARD_AC_SLEW_RATE" value="1.0" />
<parameter name="TIMING_BOARD_AC_TO_CK_SKEW" value="0.0" />
<parameter name="TIMING_BOARD_CK_CKN_SLEW_RATE" value="2.0" />
<parameter name="TIMING_BOARD_DELTA_DQS_ARRIVAL_TIME" value="0.0" />
<parameter name="TIMING_BOARD_DELTA_READ_DQS_ARRIVAL_TIME" value="0.0" />
<parameter name="TIMING_BOARD_DERATE_METHOD" value="AUTO" />
<parameter name="TIMING_BOARD_DQS_DQSN_SLEW_RATE" value="2.0" />
<parameter name="TIMING_BOARD_DQ_EYE_REDUCTION" value="0.0" />
<parameter name="TIMING_BOARD_DQ_SLEW_RATE" value="1.0" />
<parameter name="TIMING_BOARD_DQ_TO_DQS_SKEW" value="0.0" />
<parameter name="TIMING_BOARD_ISI_METHOD" value="AUTO" />
<parameter name="TIMING_BOARD_MAX_CK_DELAY" value="0.6" />
<parameter name="TIMING_BOARD_MAX_DQS_DELAY" value="0.6" />
<parameter name="TIMING_BOARD_READ_DQ_EYE_REDUCTION" value="0.0" />
<parameter name="TIMING_BOARD_SKEW_BETWEEN_DIMMS" value="0.05" />
<parameter name="TIMING_BOARD_SKEW_BETWEEN_DQS" value="0.02" />
<parameter name="TIMING_BOARD_SKEW_CKDQS_DIMM_MAX" value="0.01" />
<parameter name="TIMING_BOARD_SKEW_CKDQS_DIMM_MIN" value="-0.01" />
<parameter name="TIMING_BOARD_SKEW_WITHIN_DQS" value="0.02" />
<parameter name="TIMING_BOARD_TDH" value="0.0" />
<parameter name="TIMING_BOARD_TDS" value="0.0" />
<parameter name="TIMING_BOARD_TIH" value="0.0" />
<parameter name="TIMING_BOARD_TIS" value="0.0" />
<parameter name="TIMING_TDH" value="125" />
<parameter name="TIMING_TDQSCK" value="400" />
<parameter name="TIMING_TDQSCKDL" value="1200" />
<parameter name="TIMING_TDQSCKDM" value="900" />
<parameter name="TIMING_TDQSCKDS" value="450" />
<parameter name="TIMING_TDQSH" value="0.35" />
<parameter name="TIMING_TDQSQ" value="120" />
<parameter name="TIMING_TDQSS" value="0.25" />
<parameter name="TIMING_TDS" value="50" />
<parameter name="TIMING_TDSH" value="0.2" />
<parameter name="TIMING_TDSS" value="0.2" />
<parameter name="TIMING_TIH" value="250" />
<parameter name="TIMING_TIS" value="175" />
<parameter name="TIMING_TQH" value="0.38" />
<parameter name="TIMING_TQHS" value="300" />
<parameter name="TIMING_TQSH" value="0.38" />
<parameter name="TPIUFPGA_Enable" value="false" />
<parameter name="TPIUFPGA_alt" value="false" />
<parameter name="TRACE_Mode" value="N/A" />
<parameter name="TRACE_PinMuxing" value="Unused" />
<parameter name="TRACKING_ERROR_TEST" value="false" />
<parameter name="TRACKING_WATCH_TEST" value="false" />
<parameter name="TREFI" value="35100" />
<parameter name="TRFC" value="350" />
<parameter name="UART0_Mode" value="No Flow Control" />
<parameter name="UART0_PinMuxing" value="HPS I/O Set 0" />
<parameter name="UART1_Mode" value="N/A" />
<parameter name="UART1_PinMuxing" value="Unused" />
<parameter name="USB0_Mode" value="N/A" />
<parameter name="USB0_PinMuxing" value="Unused" />
<parameter name="USB1_Mode" value="SDR" />
<parameter name="USB1_PinMuxing" value="HPS I/O Set 0" />
<parameter name="USER_DEBUG_LEVEL" value="1" />
<parameter name="USE_AXI_ADAPTOR" value="false" />
<parameter name="USE_FAKE_PHY" value="false" />
<parameter name="USE_MEM_CLK_FREQ" value="false" />
<parameter name="USE_MM_ADAPTOR" value="true" />
<parameter name="USE_SEQUENCER_BFM" value="false" />
<parameter name="WEIGHT_PORT" value="0,0,0,0,0,0" />
<parameter name="WRBUFFER_ADDR_WIDTH" value="6" />
<parameter name="can0_clk_div" value="1" />
<parameter name="can1_clk_div" value="1" />
<parameter name="configure_advanced_parameters" value="false" />
<parameter name="customize_device_pll_info" value="false" />
<parameter name="dbctrl_stayosc1" value="true" />
<parameter name="dbg_at_clk_div" value="0" />
<parameter name="dbg_clk_div" value="1" />
<parameter name="dbg_trace_clk_div" value="0" />
<parameter name="desired_can0_clk_mhz" value="100.0" />
<parameter name="desired_can1_clk_mhz" value="100.0" />
<parameter name="desired_cfg_clk_mhz" value="100.0" />
<parameter name="desired_emac0_clk_mhz" value="250.0" />
<parameter name="desired_emac1_clk_mhz" value="250.0" />
<parameter name="desired_gpio_db_clk_hz" value="32000" />
<parameter name="desired_l4_mp_clk_mhz" value="100.0" />
<parameter name="desired_l4_sp_clk_mhz" value="100.0" />
<parameter name="desired_mpu_clk_mhz" value="800.0" />
<parameter name="desired_nand_clk_mhz" value="12.5" />
<parameter name="desired_qspi_clk_mhz" value="400.0" />
<parameter name="desired_sdmmc_clk_mhz" value="200.0" />
<parameter name="desired_spi_m_clk_mhz" value="200.0" />
<parameter name="desired_usb_mp_clk_mhz" value="200.0" />
<parameter name="device_name" value="5CSEMA4U23C6" />
<parameter name="device_pll_info_manual">{320000000 1600000000} {320000000 1000000000} {800000000 400000000 400000000}</parameter>
<parameter name="eosc1_clk_mhz" value="25.0" />
<parameter name="eosc2_clk_mhz" value="25.0" />
<parameter name="gpio_db_clk_div" value="6249" />
<parameter name="l3_mp_clk_div" value="1" />
<parameter name="l3_sp_clk_div" value="1" />
<parameter name="l4_mp_clk_div" value="1" />
<parameter name="l4_mp_clk_source" value="1" />
<parameter name="l4_sp_clk_div" value="1" />
<parameter name="l4_sp_clk_source" value="1" />
<parameter name="main_pll_c3" value="3" />
<parameter name="main_pll_c4" value="3" />
<parameter name="main_pll_c5" value="15" />
<parameter name="main_pll_m" value="63" />
<parameter name="main_pll_n" value="0" />
<parameter name="nand_clk_source" value="2" />
<parameter name="periph_pll_c0" value="3" />
<parameter name="periph_pll_c1" value="3" />
<parameter name="periph_pll_c2" value="1" />
<parameter name="periph_pll_c3" value="19" />
<parameter name="periph_pll_c4" value="4" />
<parameter name="periph_pll_c5" value="9" />
<parameter name="periph_pll_m" value="79" />
<parameter name="periph_pll_n" value="1" />
<parameter name="periph_pll_source" value="0" />
<parameter name="qspi_clk_source" value="1" />
<parameter name="quartus_ini_hps_emif_pll" value="false" />
<parameter
name="quartus_ini_hps_ip_enable_all_peripheral_fpga_interfaces"
value="false" />
<parameter name="quartus_ini_hps_ip_enable_bsel_csel" value="false" />
<parameter
name="quartus_ini_hps_ip_enable_emac0_peripheral_fpga_interface"
value="false" />
<parameter
name="quartus_ini_hps_ip_enable_low_speed_serial_fpga_interfaces"
value="false" />
<parameter name="quartus_ini_hps_ip_enable_test_interface" value="false" />
<parameter name="quartus_ini_hps_ip_f2sdram_bonding_out" value="false" />
<parameter name="quartus_ini_hps_ip_fast_f2sdram_sim_model" value="false" />
<parameter name="quartus_ini_hps_ip_suppress_sdram_synth" value="false" />
<parameter name="sdmmc_clk_source" value="2" />
<parameter name="show_advanced_parameters" value="false" />
<parameter name="show_debug_info_as_warning_msg" value="false" />
<parameter name="show_warning_as_error_msg" value="false" />
<parameter name="spi_m_clk_div" value="0" />
<parameter name="usb_mp_clk_div" value="0" />
<parameter name="use_default_mpu_clk" value="true" />
</module>
<module name="lepton_0" kind="lepton" version="1.0" enabled="1" />
<module name="mcp3204_0" kind="mcp3204" version="1.0" enabled="1" />
<module name="pwm_0" kind="pwm" version="1.0" enabled="1" />
<module name="pwm_1" kind="pwm" version="1.0" enabled="1" />
<connection
kind="avalon"
version="18.1"
start="hps_0.h2f_lw_axi_master"
end="pwm_0.avalon_slave_0">
<parameter name="arbitrationPriority" value="1" />
<parameter name="baseAddress" value="0x00049020" />
<parameter name="defaultConnection" value="false" />
</connection>
<connection
kind="avalon"
version="18.1"
start="hps_0.h2f_lw_axi_master"
end="pwm_1.avalon_slave_0">
<parameter name="arbitrationPriority" value="1" />
<parameter name="baseAddress" value="0x00049010" />
<parameter name="defaultConnection" value="false" />
</connection>
<connection
kind="avalon"
version="18.1"
start="hps_0.h2f_lw_axi_master"
end="mcp3204_0.avalon_slave_0">
<parameter name="arbitrationPriority" value="1" />
<parameter name="baseAddress" value="0x00049000" />
<parameter name="defaultConnection" value="false" />
</connection>
<connection
kind="avalon"
version="18.1"
start="hps_0.h2f_lw_axi_master"
end="lepton_0.avalon_slave_0">
<parameter name="arbitrationPriority" value="1" />
<parameter name="baseAddress" value="0x00040000" />
<parameter name="defaultConnection" value="false" />
</connection>
<connection kind="clock" version="18.1" start="clk_0.clk" end="pwm_0.clock" />
<connection kind="clock" version="18.1" start="clk_0.clk" end="pwm_1.clock" />
<connection kind="clock" version="18.1" start="clk_0.clk" end="mcp3204_0.clock" />
<connection kind="clock" version="18.1" start="clk_0.clk" end="lepton_0.clock" />
<connection
kind="clock"
version="18.1"
start="clk_0.clk"
end="hps_0.h2f_lw_axi_clock" />
<connection kind="reset" version="18.1" start="clk_0.clk_reset" end="pwm_0.reset" />
<connection kind="reset" version="18.1" start="clk_0.clk_reset" end="pwm_1.reset" />
<connection
kind="reset"
version="18.1"
start="clk_0.clk_reset"
end="mcp3204_0.reset" />
<connection
kind="reset"
version="18.1"
start="clk_0.clk_reset"
end="lepton_0.reset" />
<connection kind="reset" version="18.1" start="hps_0.h2f_reset" end="pwm_0.reset" />
<connection kind="reset" version="18.1" start="hps_0.h2f_reset" end="pwm_1.reset" />
<connection
kind="reset"
version="18.1"
start="hps_0.h2f_reset"
end="mcp3204_0.reset" />
<connection
kind="reset"
version="18.1"
start="hps_0.h2f_reset"
end="lepton_0.reset" />
<interconnectRequirement for="$system" name="qsys_mm.clockCrossingAdapter" value="HANDSHAKE" />
<interconnectRequirement for="$system" name="qsys_mm.enableEccProtection" value="FALSE" />
<interconnectRequirement for="$system" name="qsys_mm.insertDefaultSlave" value="FALSE" />
<interconnectRequirement for="$system" name="qsys_mm.maxAdditionalLatency" value="1" />
</system>

Binary file not shown.

View File

@@ -0,0 +1,14 @@
CC=g++
LDLIBS=`pkg-config --libs sfml-graphics sfml-window sfml-network`
all: main
main.o: main.cpp
main: main.o
run:
@./main
clean:
rm -f main.o main

View File

@@ -0,0 +1,120 @@
#include <SFML/Graphics.hpp>
#include <SFML/Network.hpp>
#include <iostream>
#include <type_traits>
using namespace std;
#define IMAGE_WIDTH 80
#define IMAGE_HEIGHT 60
#define SCALE_FACTOR 10
#define UPDATE_INTERVAL IMAGE_HEIGHT
#define SERVER_PORT 25700
#define BUFFER_SIZE (4 + IMAGE_WIDTH * 2)
#define HANDSHAKE_TIMEOUT 2000
void updateLine(uint8_t* buffer, uint32_t lineIndex, uint16_t* line);
void bernsteinRGB(uint8_t* rgba, double t);
void sendHandshake(sf::UdpSocket& socket, sf::IpAddress address, unsigned short port);
int main(int argc, char* argv[]) {
if (argc != 2) {
cout << "Invalid usage of client. You should pass the address of the server." << endl;
return -1;
}
// We create the window to which we render the image
sf::RenderWindow window(sf::VideoMode(IMAGE_WIDTH * SCALE_FACTOR, IMAGE_HEIGHT * SCALE_FACTOR), "Thermalizer", sf::Style::Close);
// The intermediate buffer in which the image is received before being sent to the GPU
uint8_t buffer[IMAGE_HEIGHT * IMAGE_WIDTH * 4]; // RGBA = 4 bytes per pixel
size_t lastRefresh = 0; // the number of lines since the last refresh
uint32_t lineIndex = 0; // the index of the last line that was received
// The texture to which the image will be drawn
sf::Texture texture;
texture.create(IMAGE_WIDTH, IMAGE_HEIGHT);
sf::Sprite sprite;
sprite.setTexture(texture);
sprite.setScale(SCALE_FACTOR, SCALE_FACTOR);
// The buffer in which the packet for the lines are received
char lineBuffer[BUFFER_SIZE];
size_t received;
sf::IpAddress serverAddress(argv[1]), senderAddress;
unsigned short serverPort = SERVER_PORT, senderPort;
// Create the UDP socket
cout << "Creating and binding a UDP socket..." << endl;
sf::UdpSocket socket;
sf::SocketSelector selector;
if (socket.bind(sf::UdpSocket::AnyPort) != sf::Socket::Done) {
cout << "Couldn't bind socket on port " << socket.getLocalPort() << endl;
return -1;
}
cout << "UDP Socket successfully bound." << endl;
sendHandshake(socket, serverAddress, serverPort);
selector.add(socket);
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
// If the user requested the window to be closed
if (event.type == sf::Event::Closed ||
(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Q)) {
// Inform the server about the client stopping
socket.send(nullptr, 0, serverAddress, serverPort);
window.close();
}
}
if (selector.wait(sf::milliseconds(500))) {
// If a packet was received, we update the intermediate buffer
socket.receive(lineBuffer, BUFFER_SIZE, received, senderAddress, senderPort);
lineIndex = *((uint32_t*) lineBuffer);
updateLine(buffer, lineIndex, (uint16_t*) (lineBuffer + sizeof(uint32_t)));
lastRefresh++;
} else {
// If no packet was received in a while, we re-send a handshake to try to reconnect
sendHandshake(socket, serverAddress, serverPort);
}
// We refresh the image every once in a while, so that if there is packet loss on the last
// line the screen is still updated.
if (lastRefresh == UPDATE_INTERVAL || lineIndex == IMAGE_HEIGHT - 1) {
// If enough packets were received, we update the texture
lastRefresh = 0;
texture.update(buffer);
// And draw it to the screen
window.clear();
window.draw(sprite);
window.display();
}
}
}
// Updates the line of the buffer with the packet that arrived
void updateLine(uint8_t* buffer, uint32_t lineIndex, uint16_t* line) {
uint8_t* lineBuffer = buffer + lineIndex * IMAGE_WIDTH * 4;
for (size_t x = 0; x < IMAGE_WIDTH; x++)
bernsteinRGB(lineBuffer + x * 4, (double) line[x] / 0x3FFF);
}
// Performs the color interpolation using Bernstein polynomials
void bernsteinRGB(uint8_t* rgba, double t) {
rgba[0] = (9 * (1 - t) * t * t * t) * 255;
rgba[1] = (15 * (1 - t) * (1 - t) * t * t) * 255;
rgba[2] = (9 * (1 - t) * (1 - t) * (1 - t) * t) * 255;
rgba[3] = 255;
}
// Sends a handshake to the server
void sendHandshake(sf::UdpSocket& socket, sf::IpAddress address, unsigned short port) {
cout << "Sending a handshake to the server..." << endl;
socket.send(nullptr, 0, address, port);
}

View File

@@ -0,0 +1,5 @@
LDLIBS= -lcaca
CFLAGS= -Wall
main: main.o
main.o: main.c

View File

@@ -0,0 +1,216 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <caca.h>
#define ERR -1
#define NO_ERR 0
#define M_REQUIRE(cond_, mess_, ...) \
do{ \
if(!(cond_)){ \
fprintf(stderr, mess_, ##__VA_ARGS__); \
return ERR; \
} \
}while(0);
#define M_REQUIRE_NO_ERR(v, mess_, ...)\
M_REQUIRE(v==NO_ERR, mess_, ##__VA_ARGS__)
#define M_REQUIRE_NO_NULL(v, mess_, ...)\
M_REQUIRE(v!=NULL, mess_, ##__VA_ARGS__)
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define DEFAULT_PORT 25700
#define IM_WIDTH 80
#define IM_HEIGHT 60
#define IM_BPP 16
#define IM_TOTAL IM_WIDTH*IM_HEIGHT
#define PCKT_SIZE (IM_WIDTH*sizeof(pix_t)+sizeof(uint32_t))
#define PX_MAX_V 0x3FFF
#define IM_MR 0xFF00
#define IM_MG 0x0000
#define IM_MB 0x00FF
#define IM_MA 0x0000
#define IM_5B 0x1F
#define REF_DIV 1
typedef uint16_t pix_t;
typedef struct sockaddr_in saddr_t;
/*=================================================================================================*/
pix_t IMG_IN[IM_TOTAL] = {0};
caca_canvas_t* cv = NULL;
caca_display_t* dp = NULL;
caca_dither_t* dither;
int ww = 0, wh = 0;
uint64_t msg_cnt = 0;
uint8_t refresh = 0;
char event = 0;
/*=================================================================================================*/
int setup_caca(){
cv = caca_create_canvas(IM_WIDTH,IM_HEIGHT);
M_REQUIRE_NO_NULL(cv, "Error: Unable to create caca canvas\n");
dp = caca_create_display(cv);
M_REQUIRE_NO_NULL(dp, "Error: Unable to create caca canvas\n");
caca_set_display_title(dp,"CACA HEAT VIEWER");
ww = caca_get_canvas_width(cv);
wh = caca_get_canvas_height(cv);
#ifdef COLORING_RB
dither = caca_create_dither(IM_BPP,IM_WIDTH,IM_HEIGHT,IM_WIDTH*sizeof(pix_t),IM_MR,IM_MG,IM_MB,IM_MA);
#else
dither = caca_create_dither(IM_BPP,IM_WIDTH,IM_HEIGHT,IM_WIDTH*sizeof(pix_t),IM_5B<<10,IM_5B<<5,IM_5B,IM_MA);
#endif
caca_refresh_display(dp);
return NO_ERR;
}
int clear_caca(){
caca_free_display(dp);
caca_free_canvas(cv);
return NO_ERR;
}
int get_server_addr(const char* ip, const uint16_t port, struct sockaddr_in* const p_server_addr){
assert(p_server_addr != NULL);
struct sockaddr_in server_addr = {0};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
if(ip == NULL){
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
}else{
M_REQUIRE(inet_aton(ip, &server_addr.sin_addr)== 1, "Error: Unable to set server adress (IP)\n");
}
*p_server_addr = server_addr;
return NO_ERR;
}
int bind_server(const int socket, const uint16_t port){
struct sockaddr_in server_addr;
M_REQUIRE_NO_ERR(get_server_addr(NULL, port, &server_addr), "Error: Unable to get server adress\n");
M_REQUIRE_NO_ERR(bind(socket, (const struct sockaddr*) &server_addr, sizeof(server_addr)), " Error: Unable to bind socket\n");
return NO_ERR;
}
pix_t bernstein_rgb(float f){
uint8_t r = (9*(1-f) *f *f *f)*IM_5B;
uint8_t g = (15*(1-f) *(1-f) *f *f)*IM_5B;
uint8_t b = (9*(1-f) *(1-f) *(1-f) *f)*IM_5B;
return r<<10 | g<<5 | b;
}
pix_t custom_rb(float f){
uint8_t r = f*0xFF ;
uint8_t b = (1-f)*0xFF;
return r<<8 | b;
}
void adjust_row(uint32_t row){
for(size_t i = 0; i < IM_WIDTH; ++i){
#ifdef COLORING_RB
IMG_IN[row*IM_WIDTH+i] = custom_rb((float)IMG_IN[row*IM_WIDTH+i]/PX_MAX_V);
#else
IMG_IN[row*IM_WIDTH+i] = bernstein_rgb((float)IMG_IN[row*IM_WIDTH+i]/PX_MAX_V);
#endif
}
}
int handle_message(ssize_t in_msg_len, uint8_t* in_msg){
M_REQUIRE_NO_NULL(in_msg,"Error: input message is null\n");
M_REQUIRE(in_msg_len >=0, "Error: server message timeout\n");
M_REQUIRE(in_msg_len == PCKT_SIZE, "Error: message with wrong length (%zu)\n",in_msg_len);
uint32_t row = (uint32_t) in_msg[0];
if(row < IM_HEIGHT){
memcpy(IMG_IN + row*IM_WIDTH, in_msg + sizeof(uint32_t), IM_WIDTH*sizeof(pix_t));
adjust_row(row);
}
if(row == IM_HEIGHT-1){
refresh = 1;
}
return NO_ERR;
}
int main (int argc, char** argv){
M_REQUIRE(argc==2,"Invalid usage of client. You should pass the address of the server.\n");
fprintf(stderr, "Starting Caca\n");
M_REQUIRE_NO_ERR(setup_caca(),"Error: Creating Caca\n");
memset(IMG_IN,0,IM_TOTAL*sizeof(pix_t));
M_REQUIRE_NO_ERR(caca_dither_bitmap(cv,0,0,IM_WIDTH,IM_HEIGHT,dither,IMG_IN), "Error: Unable to draw\n");
caca_refresh_display(dp);
fprintf(stderr, "Started CACA HEAT VIEWER successfully\n");
fprintf(stderr, "Starting Network\n");
int32_t s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
M_REQUIRE(s > 0, "Error: Unable to open socket\n");
M_REQUIRE_NO_ERR(bind_server(s, 0), "Error: Unable to bind socket\n");
saddr_t srv_addr;
M_REQUIRE_NO_ERR(get_server_addr(argv[1], DEFAULT_PORT, &srv_addr), "Error: Unable to get server adress\n");
fprintf(stderr, "Started Network\n");
fprintf(stderr, "Sending poke to server...\n");
char e = 0;
M_REQUIRE(sendto(s,&e,0,0,(struct sockaddr *)&srv_addr,sizeof(srv_addr))==0, " Error: Unable to send message to server\n");
fprintf(stderr, "Sent poke successfully\n");
uint8_t quit = 0;
while(!feof(stdin) && !ferror(stdin) && !quit){
caca_event_t ev;
if(caca_get_event(dp, CACA_EVENT_RESIZE | CACA_EVENT_QUIT | CACA_EVENT_KEY_PRESS, &ev, 0)){
if(caca_get_event_type(&ev) == CACA_EVENT_RESIZE){
caca_set_canvas_size(cv,IM_WIDTH,IM_HEIGHT);
}else if(caca_get_event_type(&ev) & CACA_EVENT_QUIT){
quit = 1;
}else {
switch(caca_get_event_key_ch(&ev)){
case 'Q':
case 'q':
quit=1;
break;
default:
break;
}
}
}
uint8_t in_msg[PCKT_SIZE] = {0};
ssize_t in_msg_len = recv(s, in_msg, PCKT_SIZE, 0);
M_REQUIRE_NO_ERR(handle_message(in_msg_len, in_msg), "Error: Couldn't handle message\n");
++msg_cnt;
if (msg_cnt%(IM_HEIGHT/REF_DIV)==0 || refresh){
refresh = 0;
msg_cnt = 0;
M_REQUIRE_NO_ERR(caca_dither_bitmap(cv,0,0,IM_WIDTH,IM_HEIGHT,dither,IMG_IN), "Error: Unable to draw\n");
caca_refresh_display(dp);
}
}
M_REQUIRE(sendto(s,&e,0,0,(struct sockaddr *)&srv_addr,sizeof(srv_addr))==0, " Error: Unable to send message to server\n");
M_REQUIRE_NO_ERR(clear_caca(),"Error: Clearing Caca\n" );
close(s);
return NO_ERR;
}

View File

@@ -0,0 +1,67 @@
#ifndef _ALTERA_HPS_SOC_SYSTEM_H_
#define _ALTERA_HPS_SOC_SYSTEM_H_
/*
* This file was automatically generated by the swinfo2header utility.
*
* Created from SOPC Builder system 'soc_system' in
* file 'hw/quartus/soc_system.sopcinfo'.
*/
/*
* This file contains macros for module 'hps_0' and devices
* connected to the following master:
* h2f_lw_axi_master
*
* Do not include this header file and another header file created for a
* different module or master group at the same time.
* Doing so may result in duplicate macro names.
* Instead, use the system header file which has macros with unique names.
*/
/*
* Macros for device 'lepton_0', class 'lepton'
* The macros are prefixed with 'LEPTON_0_'.
* The prefix is the slave descriptor.
*/
#define LEPTON_0_COMPONENT_TYPE lepton
#define LEPTON_0_COMPONENT_NAME lepton_0
#define LEPTON_0_BASE 0x40000
#define LEPTON_0_SPAN 32768
#define LEPTON_0_END 0x47fff
/*
* Macros for device 'mcp3204_0', class 'mcp3204'
* The macros are prefixed with 'MCP3204_0_'.
* The prefix is the slave descriptor.
*/
#define MCP3204_0_COMPONENT_TYPE mcp3204
#define MCP3204_0_COMPONENT_NAME mcp3204_0
#define MCP3204_0_BASE 0x49000
#define MCP3204_0_SPAN 16
#define MCP3204_0_END 0x4900f
/*
* Macros for device 'pwm_1', class 'pwm'
* The macros are prefixed with 'PWM_1_'.
* The prefix is the slave descriptor.
*/
#define PWM_1_COMPONENT_TYPE pwm
#define PWM_1_COMPONENT_NAME pwm_1
#define PWM_1_BASE 0x49010
#define PWM_1_SPAN 16
#define PWM_1_END 0x4901f
/*
* Macros for device 'pwm_0', class 'pwm'
* The macros are prefixed with 'PWM_0_'.
* The prefix is the slave descriptor.
*/
#define PWM_0_COMPONENT_TYPE pwm
#define PWM_0_COMPONENT_NAME pwm_0
#define PWM_0_BASE 0x49020
#define PWM_0_SPAN 16
#define PWM_0_END 0x4902f
#endif /* _ALTERA_HPS_SOC_SYSTEM_H_ */

View File

@@ -0,0 +1,24 @@
#ifndef __IORW_H__
#define __IORW_H__
#if defined(__nios2_arch__) // For the soft-core Nios processor
#include <io.h>
#define io_write_8(base, ofst, data) (IOWR_8DIRECT((base), (ofst), (data)))
#define io_write_16(base, ofst, data) (IOWR_16DIRECT((base), (ofst), (data)))
#define io_write_32(base, ofst, data) (IOWR_32DIRECT((base), (ofst), (data)))
#define io_read_8(base, ofst) (IORD_8DIRECT((base), (ofst)))
#define io_read_16(base, ofst) (IORD_16DIRECT((base), (ofst)))
#define io_read_32(base, ofst) (IORD_32DIRECT((base), (ofst)))
#else // For the hard-core ARM Cortex A9 processor
#include <socal/socal.h>
#define io_write_8(base, ofst, data) (alt_write_byte((uintptr_t) (base) + (ofst), (data)))
#define io_write_16(base, ofst, data) (alt_write_hword((uintptr_t) (base) + (ofst), (data)))
#define io_write_32(base, ofst, data) (alt_write_word((uintptr_t) (base) + (ofst), (data)))
#define io_read_8(base, ofst) (alt_read_byte((uintptr_t) (base) + (ofst)))
#define io_read_16(base, ofst) (alt_read_hword((uintptr_t) (base) + (ofst)))
#define io_read_32(base, ofst) (alt_read_word((uintptr_t) (base) + (ofst)))
#endif
#endif

View File

@@ -0,0 +1,9 @@
all: app
clean:
rm -rf *.o
rm -f app
server.o: server.c server.h
app.o: app.c server.h
app: app.o server.o

View File

@@ -0,0 +1,125 @@
#include "hps_soc_system.h"
#include "lepton/lepton.h"
#include "server.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <socal/hps.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
/** The port on which the server is available */
#define SERVER_PORT 25700
int main(int argc, char* argv[]) {
// Copy the old terminal configuration to restore it later
struct termios orig_term_attr, new_term_attr;
tcgetattr(fileno(stdin), &orig_term_attr);
memcpy(&new_term_attr, &orig_term_attr, sizeof(struct termios));
// Set the input to non-canonical mode, so that the keypresses are instantaneously recorded
new_term_attr.c_lflag &= ~(ECHO | ICANON);
new_term_attr.c_cc[VTIME] = 0;
new_term_attr.c_cc[VMIN] = 0;
tcsetattr(fileno(stdin), TCSANOW, &new_term_attr);
// Open the physical memory through the filesystem
int mem_fd = open("/dev/mem", O_SYNC | O_RDWR);
if(mem_fd == -1){
fprintf(stderr, "Failed to open /dev/mem. Exiting. Consider running this program with root privileges.\n");
tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
return -1;
}
// Map the physical memory into the virtual address space
size_t length = ALT_LWFPGASLVS_UB_ADDR - ALT_LWFPGASLVS_LB_ADDR + 1;
size_t offset = ALT_LWFPGASLVS_OFST;
void* mapped = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, offset);
if (mapped == MAP_FAILED){
fprintf(stderr, "Failed to map physical memory into virtual address space. Exiting.\n");
close(mem_fd);
tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
return -1;
}
// Initialize the lepton device with the mapped memory
lepton_dev lepton = lepton_inst(mapped + LEPTON_0_BASE);
lepton_init(&lepton);
// Create the socket
printf("Creating and binding a UDP socket on port %d...\n", SERVER_PORT);
int socket = create_upd_socket(SERVER_PORT);
if (socket == -1) {
fprintf(stderr, "Failed to create the UDP socket. Exiting.\n");
close(mem_fd);
munmap(mapped, length);
tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
return EXIT_FAILURE;
}
printf("Socket successfully bound.\n");
printf("Press 'q' to stop the server.\n");
while (1) {
// Wait for a client to connect
printf("Waiting for a new client to connect...\n");
struct sockaddr_in client_addr, sender_addr;
int event;
do {
// Wait for either a packet or the user quiting
event = wait_for_event(socket, &client_addr, -1);
} while (event == NO_EVENT);
if (event == QUIT_EVENT) {
printf("Stopping the server...\n");
munmap(mapped, length);
close(mem_fd);
close(socket);
tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
return EXIT_SUCCESS;
}
// Inform the user about the connection
char addr_string[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_addr.sin_addr, addr_string, INET_ADDRSTRLEN);
printf("Connected to client at address %s:%d.\n", addr_string, client_addr.sin_port);
// We continuously send the stream to the client until stopping is requested
do {
do {
lepton_start_capture(&lepton);
lepton_wait_until_eof(&lepton);
} while (lepton_error_check(&lepton));
uint16_t* image = lepton_get_image(&lepton, true);
send_image(socket, image, &client_addr);
event = wait_for_event(socket, &sender_addr, 0);
if (event == PACKET_EVENT &&
(sender_addr.sin_addr.s_addr != client_addr.sin_addr.s_addr
|| sender_addr.sin_port != client_addr.sin_port))
event = NO_EVENT;
} while (event == NO_EVENT);
// Stop the server if the user wants to
if (event == QUIT_EVENT) {
printf("Stopping the server...\n");
munmap(mapped, length);
close(mem_fd);
close(socket);
tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
return EXIT_SUCCESS;
}
printf("The client disconnected.\n");
}
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,79 @@
#include "joysticks.h"
#define JOYSTICK_RIGHT_VRY_MCP3204_CHANNEL (0)
#define JOYSTICK_RIGHT_VRX_MCP3204_CHANNEL (1)
#define JOYSTICK_LEFT_VRY_MCP3204_CHANNEL (2)
#define JOYSTICK_LEFT_VRX_MCP3204_CHANNEL (3)
/**
* joysticks_inst
*
* Instantiate a joysticks device structure.
*
* @param base Base address of the MCP3204 component connected to the joysticks.
*/
joysticks_dev joysticks_inst(void *mcp3204_base) {
joysticks_dev dev;
dev.mcp3204 = mcp3204_inst((void *) mcp3204_base);
return dev;
}
/**
* joysticks_init
*
* Initializes the joysticks device.
*
* @param dev joysticks device structure.
*/
void joysticks_init(joysticks_dev *dev) {
mcp3204_init(&(dev->mcp3204));
}
/**
* joysticks_read_left_vertical
*
* Returns the vertical position of the left joystick. Return value ranges
* between JOYSTICKS_MIN_VALUE and JOYSTICKS_MAX_VALUE.
*
* @param dev joysticks device structure.
*/
uint32_t joysticks_read_left_vertical(joysticks_dev *dev) {
return JOYSTICKS_MAX_VALUE - mcp3204_read(&dev->mcp3204, JOYSTICK_RIGHT_VRY_MCP3204_CHANNEL);
}
/**
* joysticks_read_left_horizontal
*
* Returns the horizontal position of the left joystick. Return value ranges
* between JOYSTICKS_MIN_VALUE and JOYSTICKS_MAX_VALUE.
*
* @param dev joysticks device structure.
*/
uint32_t joysticks_read_left_horizontal(joysticks_dev *dev) {
return mcp3204_read(&dev->mcp3204, JOYSTICK_LEFT_VRX_MCP3204_CHANNEL);
}
/**
* joysticks_read_right_vertical
*
* Returns the vertical position of the right joystick. Return value ranges
* between JOYSTICKS_MIN_VALUE and JOYSTICKS_MAX_VALUE.
*
* @param dev joysticks device structure.
*/
uint32_t joysticks_read_right_vertical(joysticks_dev *dev) {
return JOYSTICKS_MAX_VALUE - mcp3204_read(&dev->mcp3204, JOYSTICK_RIGHT_VRY_MCP3204_CHANNEL);
}
/**
* joysticks_read_right_horizontal
*
* Returns the horizontal position of the left joystick. Return value ranges
* between JOYSTICKS_MIN_VALUE and JOYSTICKS_MAX_VALUE.
*
* @param dev joysticks device structure.
*/
uint32_t joysticks_read_right_horizontal(joysticks_dev *dev) {
return mcp3204_read(&dev->mcp3204, JOYSTICK_RIGHT_VRX_MCP3204_CHANNEL);
}

View File

@@ -0,0 +1,27 @@
#ifndef __JOYSTICKS_H__
#define __JOYSTICKS_H__
#include "mcp3204/mcp3204.h"
/* joysticks device structure */
typedef struct joysticks_dev {
mcp3204_dev mcp3204; /* MCP3204 device handle */
} joysticks_dev;
/*******************************************************************************
* Public API
******************************************************************************/
#define JOYSTICKS_MIN_VALUE (MCP3204_MIN_VALUE)
#define JOYSTICKS_MAX_VALUE (MCP3204_MAX_VALUE)
joysticks_dev joysticks_inst(void *mcp3204_base);
void joysticks_init(joysticks_dev *dev);
uint32_t joysticks_read_left_vertical(joysticks_dev *dev);
uint32_t joysticks_read_left_horizontal(joysticks_dev *dev);
uint32_t joysticks_read_right_vertical(joysticks_dev *dev);
uint32_t joysticks_read_right_horizontal(joysticks_dev *dev);
#endif /* __JOYSTICKS_H__ */

View File

@@ -0,0 +1,44 @@
#include "mcp3204.h"
#include "iorw.h"
#define MCP3204_NUM_CHANNELS (4)
/**
* mcp3204_inst
*
* Instantiate a mcp3204 device structure.
*
* @param base Base address of the component.
*/
mcp3204_dev mcp3204_inst(void *base) {
mcp3204_dev dev;
dev.base = base;
return dev;
}
/**
* mcp3204_init
*
* Initializes the mcp3204 device.
*
* @param dev mcp3204 device structure.
*/
void mcp3204_init(mcp3204_dev *dev) {
return;
}
/**
* mcp3204_read
*
* Reads the register corresponding to the supplied channel parameter.
*
* @param dev mcp3204 device structure.
* @param channel channel to be read
*/
uint32_t mcp3204_read(mcp3204_dev *dev, uint32_t channel) {
if (channel >= 4)
return 0;
return io_read_32(dev->base, channel * 4);
}

View File

@@ -0,0 +1,23 @@
#ifndef __MCP3204_H__
#define __MCP3204_H__
#include <stdint.h>
/* mcp3204 device structure */
typedef struct mcp3204_dev {
void *base; /* Base address of component */
} mcp3204_dev;
/*******************************************************************************
* Public API
******************************************************************************/
#define MCP3204_MIN_VALUE (0)
#define MCP3204_MAX_VALUE (4095)
mcp3204_dev mcp3204_inst(void *base);
void mcp3204_init(mcp3204_dev *dev);
uint32_t mcp3204_read(mcp3204_dev *dev, uint32_t channel);
#endif /* __MCP3204_H__ */

View File

@@ -0,0 +1,9 @@
#ifndef __MCP3204_REGS_H__
#define __MCP3204_REGS_H__
#define MCP3204_CHANNEL_0_OFST (0 * 4) /* RO */
#define MCP3204_CHANNEL_1_OFST (1 * 4) /* RO */
#define MCP3204_CHANNEL_2_OFST (2 * 4) /* RO */
#define MCP3204_CHANNEL_3_OFST (3 * 4) /* RO */
#endif /* __MCP3204_REGS_H__ */

View File

@@ -0,0 +1,122 @@
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <unistd.h>
#include "lepton_regs.h"
#include "lepton.h"
#include "iorw.h"
/**
* lepton_inst
*
* Instantiate a lepton device structure.
*
* @param base Base address of the component.
*/
lepton_dev lepton_inst(void *base) {
lepton_dev dev;
dev.base = base;
return dev;
}
/**
* lepton_init
*
* Initializes the lepton device.
*
* @param dev lepton device structure.
*/
void lepton_init(lepton_dev *dev) {
return;
}
/**
* lepton_start_capture
*
* Instructs the device to start the frame capture process.
*
* @param dev lepton device structure.
*/
void lepton_start_capture(lepton_dev *dev) {
io_write_16(dev->base, LEPTON_REGS_COMMAND_OFST, 0x1);
}
/**
* lepton_error_check
*
* @abstract Check for errors at the device level.
* @param dev lepton device structure.
* @return true if there was an error, and false otherwise.
*/
bool lepton_error_check(lepton_dev *dev) {
return (io_read_16(dev->base, LEPTON_REGS_STATUS_OFST) & 0x2) != 0;
}
/**
* lepton_wait_until_eof
*
* Waits until the frame being captured has been fully received and saved in the
* internal memory.
*
* @param dev lepton device structure.
*/
void lepton_wait_until_eof(lepton_dev *dev) {
while (io_read_16(dev->base, LEPTON_REGS_STATUS_OFST) & 0x1);
}
/**
* lepton_save_capture
*
* Saves the captured frame on the host filesystem under the supplied filename.
* The frame will be saved in PGM format.
*
* @param dev lepton device structure.
* @param adjusted Setting this parameter to false will cause RAW sensor data to
* be written to the file.
* Setting this parameter to true will cause a preprocessed image
* (with a stretched dynamic range) to be saved to the file.
*
* @param fname the output file name.
*/
void lepton_save_capture(lepton_dev *dev, bool adjusted, FILE* file) {
assert(file);
const uint8_t num_rows = 60;
const uint8_t num_cols = 80;
uint16_t offset = LEPTON_REGS_RAW_BUFFER_OFST;
uint16_t max_value = io_read_16(dev->base, LEPTON_REGS_MAX_OFST);
if (adjusted) {
offset = LEPTON_REGS_ADJUSTED_BUFFER_OFST;
max_value = 0x3fff;
}
/* Write PGM header */
fprintf(file, "P2\n%" PRIu8 " %" PRIu8 "\n%" PRIu16, num_cols, num_rows, max_value);
/* Write body */
uint8_t row = 0;
for (row = 0; row < num_rows; ++row) {
fprintf(file, "\n");
uint8_t col = 0;
for (col = 0; col < num_cols; ++col) {
if (col > 0) {
fprintf(file, " ");
}
uint16_t current_ofst = offset + (row * num_cols + col) * sizeof(uint16_t);
uint16_t pix_value = io_read_16(dev->base, current_ofst);
fprintf(file, "%" PRIu16, pix_value);
}
}
assert(!fclose(file));
}
uint16_t* lepton_get_image(lepton_dev *dev, bool adjusted) {
size_t offset = adjusted ? LEPTON_REGS_ADJUSTED_BUFFER_OFST : LEPTON_REGS_RAW_BUFFER_OFST;
return (uint16_t*) ((uint8_t*) dev->base + offset);
}

View File

@@ -0,0 +1,26 @@
#ifndef __LEPTON_H__
#define __LEPTON_H__
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
/* lepton device structure */
typedef struct {
void *base; /* Base address of the component */
} lepton_dev;
/*******************************************************************************
* Public API
******************************************************************************/
lepton_dev lepton_inst(void *base);
void lepton_init(lepton_dev *dev);
void lepton_start_capture(lepton_dev *dev);
void lepton_wait_until_eof(lepton_dev *dev);
bool lepton_error_check(lepton_dev *dev);
void lepton_save_capture(lepton_dev *dev, bool adjusted, FILE* file);
uint16_t* lepton_get_image(lepton_dev *dev, bool adjusted);
#endif /* __LEPTON_H__ */

View File

@@ -0,0 +1,25 @@
#ifndef __LEPTON_REGS_H__
#define __LEPTON_REGS_H__
/* Register offsets */
#define LEPTON_REGS_COMMAND_OFST ( 0 * 2) /* WO */
#define LEPTON_REGS_STATUS_OFST ( 1 * 2) /* RO */
#define LEPTON_REGS_MIN_OFST ( 2 * 2) /* RO */
#define LEPTON_REGS_MAX_OFST ( 3 * 2) /* RO */
#define LEPTON_REGS_SUM_LSB_OFST ( 4 * 2) /* RO */
#define LEPTON_REGS_SUM_MSB_OFST ( 5 * 2) /* RO */
#define LEPTON_REGS_ROW_IDX_OFST ( 6 * 2) /* RO */
#define LEPTON_REGS_RAW_BUFFER_OFST ( 8 * 2) /* RO */
#define LEPTON_REGS_ADJUSTED_BUFFER_OFST (8192 * 2) /* RO */
/* Command register */
#define LEPTON_COMMAND_START (0x0001)
/* Status register */
#define LEPTON_STATUS_CAPTURE_IN_PROGRESS_MASK (1 << 0)
#define LEPTON_STATUS_ERROR_MASK (1 << 1)
#define LEPTON_REGS_BUFFER_NUM_PIXELS (80 * 60)
#define LEPTON_REGS_BUFFER_BYTELENGTH (LEPTON_REGS_BUFFER_NUM_PIXELS * 2)
#endif /* __LEPTON_REGS_H__ */

View File

@@ -0,0 +1,109 @@
#include "pantilt.h"
/**
* pantilt_inst
*
* Instantiate a pantilt device structure.
*
* @param pwm_v_base Base address of the vertical PWM component.
* @param pwm_h_base Base address of the horizontal PWM component.
*/
pantilt_dev pantilt_inst(void *pwm_v_base, void *pwm_h_base) {
pantilt_dev dev;
dev.pwm_v = pwm_inst(pwm_v_base);
dev.pwm_h = pwm_inst(pwm_h_base);
return dev;
}
/**
* pantilt_init
*
* Initializes the pantilt device.
*
* @param dev pantilt device structure.
*/
void pantilt_init(pantilt_dev *dev) {
pwm_init(&(dev->pwm_v));
pwm_init(&(dev->pwm_h));
}
/**
* pantilt_configure_vertical
*
* Configure the vertical PWM component.
*
* @param dev pantilt device structure.
* @param duty_cycle pwm duty cycle in us.
*/
void pantilt_configure_vertical(pantilt_dev *dev, uint32_t duty_cycle) {
// Need to compensate for inverted servo rotation.
duty_cycle = PANTILT_PWM_V_MAX_DUTY_CYCLE_US - duty_cycle + PANTILT_PWM_V_MIN_DUTY_CYCLE_US;
pwm_configure(&(dev->pwm_v),
duty_cycle,
PANTILT_PWM_PERIOD_US,
PANTILT_PWM_CLOCK_FREQ_HZ);
}
/**
* pantilt_configure_horizontal
*
* Configure the horizontal PWM component.
*
* @param dev pantilt device structure.
* @param duty_cycle pwm duty cycle in us.
*/
void pantilt_configure_horizontal(pantilt_dev *dev, uint32_t duty_cycle) {
// Need to compensate for inverted servo rotation.
duty_cycle = PANTILT_PWM_H_MAX_DUTY_CYCLE_US - duty_cycle + PANTILT_PWM_H_MIN_DUTY_CYCLE_US;
pwm_configure(&(dev->pwm_h),
duty_cycle,
PANTILT_PWM_PERIOD_US,
PANTILT_PWM_CLOCK_FREQ_HZ);
}
/**
* pantilt_start_vertical
*
* Starts the vertical pwm controller.
*
* @param dev pantilt device structure.
*/
void pantilt_start_vertical(pantilt_dev *dev) {
pwm_start(&(dev->pwm_v));
}
/**
* pantilt_start_horizontal
*
* Starts the horizontal pwm controller.
*
* @param dev pantilt device structure.
*/
void pantilt_start_horizontal(pantilt_dev *dev) {
pwm_start(&(dev->pwm_h));
}
/**
* pantilt_stop_vertical
*
* Stops the vertical pwm controller.
*
* @param dev pantilt device structure.
*/
void pantilt_stop_vertical(pantilt_dev *dev) {
pwm_stop(&(dev->pwm_v));
}
/**
* pantilt_stop_horizontal
*
* Stops the horizontal pwm controller.
*
* @param dev pantilt device structure.
*/
void pantilt_stop_horizontal(pantilt_dev *dev) {
pwm_stop(&(dev->pwm_h));
}

View File

@@ -0,0 +1,39 @@
#ifndef __PANTILT_H__
#define __PANTILT_H__
#include "pwm/pwm.h"
/* joysticks device structure */
typedef struct pantilt_dev {
pwm_dev pwm_v; /* Vertical PWM device handle */
pwm_dev pwm_h; /* Horizontal PWM device handle */
} pantilt_dev;
/*******************************************************************************
* Public API
******************************************************************************/
#define PANTILT_PWM_CLOCK_FREQ_HZ (50000000) // 50.00 MHz
#define PANTILT_PWM_PERIOD_US (25000) // 25.00 ms
/* Vertical servo */
#define PANTILT_PWM_V_MIN_DUTY_CYCLE_US (950) // 0.95 ms
#define PANTILT_PWM_V_MAX_DUTY_CYCLE_US (2150) // 2.15 ms
/* Horizontal servo */
#define PANTILT_PWM_H_MIN_DUTY_CYCLE_US (1000) // 1.00 ms
#define PANTILT_PWM_H_MAX_DUTY_CYCLE_US (2000) // 2.00 ms
pantilt_dev pantilt_inst(void *pwm_v_base, void *pwm_h_base);
void pantilt_init(pantilt_dev *dev);
void pantilt_configure_vertical(pantilt_dev *dev, uint32_t duty_cycle);
void pantilt_configure_horizontal(pantilt_dev *dev, uint32_t duty_cycle);
void pantilt_start_vertical(pantilt_dev *dev);
void pantilt_start_horizontal(pantilt_dev *dev);
void pantilt_stop_vertical(pantilt_dev *dev);
void pantilt_stop_horizontal(pantilt_dev *dev);
#endif /* __PANTILT_H__ */

View File

@@ -0,0 +1,68 @@
#include "pwm.h"
#include "pwm_regs.h"
#include "iorw.h"
#define MICROSEC_TO_CLK(time, freq) ((time) * ((freq) / 1000000))
/**
* pwm_inst
*
* Instantiate a pwm device structure.
*
* @param base Base address of the component.
*/
pwm_dev pwm_inst(void *base) {
pwm_dev dev;
dev.base = base;
return dev;
}
/**
* pwm_init
*
* Initializes the pwm device. This function stops the controller.
*
* @param dev pwm device structure.
*/
void pwm_init(pwm_dev *dev) {
pwm_stop(dev);
}
/**
* pwm_configure
*
* Configure pwm component.
*
* @param dev pwm device structure.
* @param duty_cycle pwm duty cycle in us.
* @param period pwm period in us.
* @param module_frequency frequency at which the component is clocked.
*/
void pwm_configure(pwm_dev *dev, uint32_t duty_cycle, uint32_t period, uint32_t module_frequency) {
io_write_32(dev->base, PWM_PERIOD_OFST, MICROSEC_TO_CLK(period, module_frequency));
io_write_32(dev->base, PWM_DUTY_CYCLE_OFST, MICROSEC_TO_CLK(duty_cycle, module_frequency));
}
/**
* pwm_start
*
* Starts the pwm controller.
*
* @param dev pwm device structure.
*/
void pwm_start(pwm_dev *dev) {
io_write_32(dev->base, PWM_CTRL_OFST, PWM_CTRL_START_MASK);
}
/**
* pwm_stop
*
* Stops the pwm controller.
*
* @param dev pwm device structure.
*/
void pwm_stop(pwm_dev *dev) {
io_write_32(dev->base, PWM_CTRL_OFST, PWM_CTRL_START_MASK);
}

View File

@@ -0,0 +1,21 @@
#ifndef __PWM_H__
#define __PWM_H__
#include <stdint.h>
/* pwm device structure */
typedef struct pwm_dev {
void *base; /* Base address of component */
} pwm_dev;
/*******************************************************************************
* Public API
******************************************************************************/
pwm_dev pwm_inst(void *base);
void pwm_init(pwm_dev *dev);
void pwm_configure(pwm_dev *dev, uint32_t duty_cycle, uint32_t period, uint32_t module_frequency);
void pwm_start(pwm_dev *dev);
void pwm_stop(pwm_dev *dev);
#endif /* __PWM_H__ */

View File

@@ -0,0 +1,11 @@
#ifndef __PWM_REGS_H__
#define __PWM_REGS_H__
#define PWM_PERIOD_OFST (0 * 4) /* RW */
#define PWM_DUTY_CYCLE_OFST (1 * 4) /* RW */
#define PWM_CTRL_OFST (2 * 4) /* WO */
#define PWM_CTRL_STOP_MASK (0)
#define PWM_CTRL_START_MASK (1)
#endif /* __PWM_REGS_H__ */

View File

@@ -0,0 +1,79 @@
#include "server.h"
#include <sys/socket.h> // for socket
#include <sys/types.h> // for AF_INET
#include <netinet/in.h> // for sockaddr_in
#include <arpa/inet.h> // for htonl
#include <stdint.h> // for uint16_t
#include <unistd.h> // for close
#include <string.h> // for memcpy
#include <poll.h> // for poll
#define ROW_SIZE (IMG_WIDTH * sizeof(uint16_t))
int create_upd_socket(uint16_t port) {
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == -1)
return -1;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr))) {
close(sock);
return -1;
}
return sock;
}
int wait_for_event(int socket, struct sockaddr_in* addr, int timeout) {
char c = 0;
struct pollfd fds[2];
// Wait for a packet
fds[0].fd = socket;
fds[0].events = POLLIN;
fds[0].revents = 0;
// Wait for a command line input
fds[1].fd = STDIN_FILENO;
fds[1].events = POLLIN;
fds[1].revents = 0;
// Wait for the two file descriptors in parallel
int ret = poll(fds, 2, timeout);
if (ret <= 0) // error or timeout
return NO_EVENT;
if (fds[1].revents & POLLIN) {
read(STDIN_FILENO, &c, 1);
if (c == 'q')
return QUIT_EVENT;
}
if (fds[0].revents & POLLIN) {
socklen_t addr_len = sizeof(struct sockaddr_in);
recvfrom(socket, &c, 1, 0, (struct sockaddr*) addr, &addr_len);
return PACKET_EVENT;
}
return NO_EVENT;
}
void send_image(int socket, uint16_t* img, const struct sockaddr_in* addr) {
// This buffer is used to hold the packet for a row
char row_buffer[sizeof(uint32_t) + ROW_SIZE];
// We send the rows one by one
uint8_t i = 0;
for (i = 0; i < IMG_HEIGHT; i++) {
*((uint32_t*) row_buffer) = i; // The first bytes of the packet contain the row index
memcpy(row_buffer + sizeof(uint32_t), img + i * IMG_WIDTH, ROW_SIZE); // The rest contains the actual row
sendto(socket, row_buffer, sizeof(uint32_t) + ROW_SIZE, 0, (const struct sockaddr*) addr, sizeof(*addr));
}
}

View File

@@ -0,0 +1,32 @@
#ifndef __SERVER_H__
#define __SERVER_H__
#include <netinet/in.h>
#include <stdint.h>
/** Image definitions - needs to move to another file later */
#define IMG_WIDTH 80
#define IMG_HEIGHT 60
#define IMG_SIZE (IMG_WIDTH * IMG_HEIGHT)
/**
* Creates and binds a socket on the given port, using the UDP protocol.
* If an error occured, -1 is returned, otherwise the socket is returned.
*/
int create_upd_socket(in_port_t port);
/**
* Polls the given socket for a message, and check if the user wants to quit by pressing q
* in the console. Returns what happened in the form of an integer.
*/
#define NO_EVENT 0
#define QUIT_EVENT 1
#define PACKET_EVENT 2
int wait_for_event(int socket, struct sockaddr_in* addr, int timeout);
/**
* Sends the entire image over udp, row by row, through the given socket.
*/
void send_image(int socket, uint16_t* img, const struct sockaddr_in* addr);
#endif

View File

@@ -0,0 +1,9 @@
all: app
clean:
rm -rf *.o
rm -f app
server.o: server.c server.h
app.o: app.c server.h
app: app.o server.o

View File

@@ -0,0 +1,94 @@
#include "server.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <termios.h>
/** The port on which the server is available */
#define SERVER_PORT 25700
// Creates a moving fake image
void generate_image(uint16_t* img, size_t t);
int main(int argc, char* argv[]) {
// Set the input to non-canonical mode, so that the keypresses are instantaneously recorded
struct termios term_attr;
tcgetattr(fileno(stdin), &term_attr);
term_attr.c_lflag &= ~(ECHO | ICANON);
term_attr.c_cc[VTIME] = 0;
term_attr.c_cc[VMIN] = 0;
tcsetattr(fileno(stdin), TCSANOW, &term_attr);
// This is the image that will be sent
uint16_t img[IMG_WIDTH * IMG_HEIGHT];
size_t t = 0;
// Create the socket
printf("Creating and binding a UDP socket on port %d...\n", SERVER_PORT);
int socket = create_upd_socket(SERVER_PORT);
if (socket == -1) {
fprintf(stderr, "Failed to create the UDP socket. Exiting.\n");
return EXIT_FAILURE;
}
printf("Socket successfully bound.\n");
printf("Press 'q' to stop the server.\n");
while (1) {
// Wait for a client to connect
printf("Waiting for a new client to connect...\n");
struct sockaddr_in client_addr, sender_addr;
int event;
do {
// Wait for either a packet or the user quiting
event = wait_for_event(socket, &client_addr, -1);
} while (event == NO_EVENT);
if (event == QUIT_EVENT) {
printf("Stopping the server...\n");
close(socket);
return EXIT_SUCCESS;
}
// Inform the user about the connection
char addr_string[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_addr.sin_addr, addr_string, INET_ADDRSTRLEN);
printf("Connected to client at address %s:%d.\n", addr_string, client_addr.sin_port);
// We continuously send the stream to the client until stopping is requested
do {
generate_image(img, t++);
send_image(socket, img, &client_addr);
event = wait_for_event(socket, &sender_addr, 100);
if (event == PACKET_EVENT &&
(sender_addr.sin_addr.s_addr != client_addr.sin_addr.s_addr
|| sender_addr.sin_port != client_addr.sin_port))
event = NO_EVENT;
} while (event == NO_EVENT);
// Stop the server if the user wants to
if (event == QUIT_EVENT) {
printf("Stopping the server...\n");
close(socket);
return EXIT_SUCCESS;
}
printf("The client disconnected.\n");
}
return EXIT_SUCCESS;
}
void generate_image(uint16_t* img, size_t t) {
for (size_t x = 0; x < IMG_WIDTH; x++) {
uint16_t val = ((x + t) % IMG_WIDTH) * 0x3FFF / IMG_WIDTH;
for (size_t y = 0; y < IMG_HEIGHT; y++)
img[y * IMG_WIDTH + x] = val;
}
}

View File

@@ -0,0 +1,79 @@
#include "server.h"
#include <sys/socket.h> // for socket
#include <sys/types.h> // for AF_INET
#include <netinet/in.h> // for sockaddr_in
#include <arpa/inet.h> // for htonl
#include <stdint.h> // for uint16_t
#include <unistd.h> // for close
#include <string.h> // for memcpy
#include <poll.h> // for poll
#define ROW_SIZE (IMG_WIDTH * sizeof(uint16_t))
int create_upd_socket(uint16_t port) {
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == -1)
return -1;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr))) {
close(sock);
return -1;
}
return sock;
}
int wait_for_event(int socket, struct sockaddr_in* addr, int timeout) {
char c = 0;
struct pollfd fds[2];
// Wait for a packet
fds[0].fd = socket;
fds[0].events = POLLIN;
fds[0].revents = 0;
// Wait for a command line input
fds[1].fd = STDIN_FILENO;
fds[1].events = POLLIN;
fds[1].revents = 0;
// Wait for the two file descriptors in parallel
int ret = poll(fds, 2, timeout);
if (ret <= 0) // error or timeout
return NO_EVENT;
if (fds[1].revents & POLLIN) {
read(STDIN_FILENO, &c, 1);
if (c == 'q')
return QUIT_EVENT;
}
if (fds[0].revents & POLLIN) {
socklen_t addr_len = sizeof(struct sockaddr_in);
recvfrom(socket, &c, 1, 0, (struct sockaddr*) addr, &addr_len);
return PACKET_EVENT;
}
return NO_EVENT;
}
void send_image(int socket, uint16_t* img, const struct sockaddr_in* addr) {
// This buffer is used to hold the packet for a row
char row_buffer[sizeof(uint32_t) + ROW_SIZE];
// We send the rows one by one
uint8_t i = 0;
for (i = 0; i < IMG_HEIGHT; i++) {
*((uint32_t*) row_buffer) = i; // The first bytes of the packet contain the row index
memcpy(row_buffer + sizeof(uint32_t), img + i * IMG_WIDTH, ROW_SIZE); // The rest contains the actual row
sendto(socket, row_buffer, sizeof(uint32_t) + ROW_SIZE, 0, (const struct sockaddr*) addr, sizeof(*addr));
}
}

View File

@@ -0,0 +1,32 @@
#ifndef __SERVER_H__
#define __SERVER_H__
#include <netinet/in.h>
#include <stdint.h>
/** Image definitions - needs to move to another file later */
#define IMG_WIDTH 80
#define IMG_HEIGHT 60
#define IMG_SIZE (IMG_WIDTH * IMG_HEIGHT)
/**
* Creates and binds a socket on the given port, using the UDP protocol.
* If an error occured, -1 is returned, otherwise the socket is returned.
*/
int create_upd_socket(in_port_t port);
/**
* Polls the given socket for a message, and check if the user wants to quit by pressing q
* in the console. Returns what happened in the form of an integer.
*/
#define NO_EVENT 0
#define QUIT_EVENT 1
#define PACKET_EVENT 2
int wait_for_event(int socket, struct sockaddr_in* addr, int timeout);
/**
* Sends the entire image over udp, row by row, through the given socket.
*/
void send_image(int socket, uint16_t* img, const struct sockaddr_in* addr);
#endif

View File

@@ -0,0 +1,22 @@
#!/bin/bash -x
# apt sources
# uncomment the "deb" lines (no need to uncomment "deb src" lines)
# Edit the “/etc/apt/sources.list” file to configure the package manager. This
# file contains a list of mirrors that the package manager queries. By default,
# this file has all fields commented out, so the package manager will not have
# access to any mirrors. The following command uncomments all commented out
# lines starting with "deb". These contain the mirrors we are interested in.
sudo perl -pi -e 's/^#+\s+(deb\s+http)/$1/g' "/etc/apt/sources.list"
# When writing our linux applications, we want to use ARM DS-5s remote
# debugging feature to automatically transfer our binaries to the target device
# and to start a debugging session. The remote debugging feature requires an SSH
# server and a remote gdb server to be available on the target. These are easy
# to install as we have a package manager available
sudo apt update
sudo apt -y install ssh gdbserver
# Allow root SSH login with password (needed so we can use ARM DS-5 for remote
# debugging)
sudo perl -pi -e 's/^(PermitRootLogin) without-password$/$1 yes/g' "/etc/ssh/sshd_config"

View File

@@ -0,0 +1,74 @@
#!/bin/bash -x
# Configure the locale to have proper language support.
localedef -i en_US -c -f UTF-8 en_US.UTF-8
dpkg-reconfigure locales
# Configure the timezone.
echo "Europe/Zurich" > "/etc/timezone"
dpkg-reconfigure -f noninteractive tzdata
# Set the machines hostname.
echo "DE0-Nano-SoC" > "/etc/hostname"
tee "/etc/hosts" >"/dev/null" <<EOF
127.0.0.1 localhost
127.0.1.1 DE0-Nano-SoC
EOF
# Create the “/etc/network/interfaces” file that describes the network
# interfaces available on the board.
tee "/etc/network/interfaces" > "/dev/null" <<EOF
# interfaces(5) file used by ifup(8) and ifdown(8)
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet dhcp
EOF
# DNS configuration for name resolution. We use google's public DNS server here.
sudo tee "/etc/resolv.conf" > "/dev/null" <<EOF
nameserver 8.8.8.8
EOF
# Configure Ubuntu Core to display a login shell on the serial console once the
# kernel boots. We had previously configured U-Boot to supply the command-line
# argument "console=ttyS0,115200" to the linux kernel. This argument instructs
# the kernel to use serial console “ttyS0” as the boot shell, so here we choose
# to use the same serial console for the login shell
tee "/etc/init/ttyS0.conf" > "/dev/null" <<EOF
# ttyS0 - getty
#
# This service maintains a getty on ttyS0
description "Get a getty on ttyS0"
start on runlevel [2345]
stop on runlevel [016]
respawn
exec /sbin/getty -L 115200 ttyS0 vt102
EOF
# Create a user and a password. In this example, we create a user called
# “sahand” with password "1234". Note that we compute an encrypted version of
# the password, because useradd does not allow plain text passwords to be used
# in non-interactive mode.
username="sahand"
password="1234"
encrypted_password="$(perl -e 'printf("%s\n", crypt($ARGV[0], "password"))' "${password}")"
useradd -m -p "${encrypted_password}" -s "/bin/bash" "${username}"
# Ubuntu requires the admin to be part of the "adm" and "sudo" groups, so add
# the previously-created user to the 2 groups.
addgroup ${username} adm
addgroup ${username} sudo
# Set root password to "1234" (same as previously-created user).
echo -e "${password}\n${password}\n" | passwd root
# Remove "/rootfs_config.sh" from /etc/rc.local to avoid reconfiguring system on
# next boot
tee "/etc/rc.local" > "/dev/null" <<EOF
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
exit 0
EOF