From df81b9a38fbe2b21957bba5de024274b3913c66e Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Tue, 7 Oct 2014 15:38:45 +0200 Subject: [PATCH] Simple DC motor control with IRC decode by kernel module rpi_gpio_irc_module. The interface to RPi is same as for wire-wrapped version described on LinTarget page http://lintarget.sourceforge.net/rpi-motor-control/index.html Signed-off-by: Pavel Pisa --- simple-dc/par.tcl | 84 +++++++++++++++++ simple-dc/program-agl.sh | 11 +++ simple-dc/rpi_mc_1.pdc | 152 ++++++++++++++++++++++++++++++ simple-dc/rpi_mc_simple_dc.vhdl | 161 ++++++++++++++++++++++++++++++++ simple-dc/syn.tcl | 21 +++++ simple-dc/synthetize-agl.sh | 4 + simple-dc/util.vhdl | 51 ++++++++++ 7 files changed, 484 insertions(+) create mode 100644 simple-dc/par.tcl create mode 100755 simple-dc/program-agl.sh create mode 100644 simple-dc/rpi_mc_1.pdc create mode 100644 simple-dc/rpi_mc_simple_dc.vhdl create mode 100644 simple-dc/syn.tcl create mode 100755 simple-dc/synthetize-agl.sh create mode 100644 simple-dc/util.vhdl diff --git a/simple-dc/par.tcl b/simple-dc/par.tcl new file mode 100644 index 0000000..2cec468 --- /dev/null +++ b/simple-dc/par.tcl @@ -0,0 +1,84 @@ +# designer SCRIPT:par.tcl LOGFILE:par.log + +# create a new design +new_design -name "rpi_mc_simple_dc" -family "IGLOO" + +set_device \ + -die AGL125V5 \ + -package "100 VQFP" \ + -speed STD \ + -voltage 1.5 \ + -iostd LVTTL \ + -jtag yes \ + -probe yes \ + -trst yes \ + -temprange COM \ + -voltrange COM + +# set default back-annotation base-name +set_defvar "BA_NAME" "rpi_mc_simple_dc_ba" + +# set working directory +set_defvar "DESDIR" "par0" + +# set back-annotation output directory +set_defvar "BA_DIR" "par0" + +# enable the export back-annotation netlist +set_defvar "BA_NETLIST_ALSO" "1" + +# setup status report options +set_defvar "EXPORT_STATUS_REPORT" "1" +set_defvar "EXPORT_STATUS_REPORT_FILENAME" "rpi_mc_simple_dc.rpt" + +# legacy audit-mode flags (left here for historical reasons) +set_defvar "AUDIT_NETLIST_FILE" "1" +set_defvar "AUDIT_DCF_FILE" "1" +set_defvar "AUDIT_PIN_FILE" "1" +set_defvar "AUDIT_ADL_FILE" "1" + +# import of input files +import_source \ +-format "edif" -edif_flavor "GENERIC" -netlist_naming "VHDL" "syn0/rpi_mc_simple_dc.edn" \ +-format "pdc" "rpi_mc_1.pdc" + +# export translation of original netlist +export -format "vhdl" "_map.vhdl" + +compile \ + -pdc_abort_on_error on \ + -pdc_eco_display_unmatched_objects off \ + -pdc_eco_max_warnings 10000 \ + -demote_globals off \ + -demote_globals_max_fanout 12 \ + -promote_globals off \ + -promote_globals_min_fanout 200 \ + -promote_globals_max_limit 0 \ + -localclock_max_shared_instances 12 \ + -localclock_buffer_tree_max_fanout 12 \ + -combine_register on \ + -delete_buffer_tree off \ + -delete_buffer_tree_max_fanout 12 \ + -report_high_fanout_nets_limit 10 + +# auxiliary source files +import_aux -format "sdc" "syn0/rpi_mc_simple_dc_sdc.sdc" + +save_design rpi_mc_simple_dc.adb + +layout \ + -timing_driven \ + -run_placer on \ + -place_incremental off \ + -run_router on \ + -route_incremental off \ + -placer_high_effort off + +save_design rpi_mc_simple_dc.adb + +export \ + -format bts_stp \ + -feature prog_fpga \ + rpi_mc_simple_dc.stp + +save_design rpi_mc_simple_dc.adb diff --git a/simple-dc/program-agl.sh b/simple-dc/program-agl.sh new file mode 100755 index 0000000..2af8b6c --- /dev/null +++ b/simple-dc/program-agl.sh @@ -0,0 +1,11 @@ +#!/usr/local/bin/urjtag-i386 + +cable ft2232 vid=0x0403 pid=0x6010 + +debug detail + +detect + +stapl prodlex.stp -aerase + +stapl rpi_mc_simple_dc.stp -aPROGRAM diff --git a/simple-dc/rpi_mc_1.pdc b/simple-dc/rpi_mc_1.pdc new file mode 100644 index 0000000..42938a2 --- /dev/null +++ b/simple-dc/rpi_mc_1.pdc @@ -0,0 +1,152 @@ +# +# rpi_mc_1 AGL125 +# +# Pavel Pisa +# Copyright PiKRON.com 2014 +# + +# +# IO banks setting +# +#set_iobank Bank3 -vcci 3.30 -fixed yes +#set_iobank Bank2 -vcci 3.30 -fixed yes +set_iobank Bank1 -vcci 3.30 -fixed yes +set_iobank Bank0 -vcci 3.30 -fixed yes + +# +# I/O constraints +# + +# RPi B+ P1 connector pins +# type LVTTL or LVCMOS33 + +# SDA +set_io {gpio2} -iostd LVCMOS33 -pinname 20 -fixed yes +# SCL +set_io {gpio3} -iostd LVCMOS33 -pinname 19 -fixed yes +# CLK +set_io {gpio4} -iostd LVCMOS33 -pinname 13 -fixed yes +# Tx +set_io {gpio14} -iostd LVCMOS33 -pinname 8 -fixed yes +# Rx +set_io {gpio15} -iostd LVCMOS33 -pinname 7 -fixed yes +# RTS +set_io {gpio17} -iostd LVCMOS33 -pinname 5 -fixed yes +# PWM0/PCMCLK +set_io {gpio18} -iostd LVCMOS33 -pinname 4 -fixed yes +# SD1DAT3 +set_io {gpio27} -iostd LVCMOS33 -pinname 3 -fixed yes +# SD1CLK +set_io {gpio22} -iostd LVCMOS33 -pinname 2 -fixed yes +# SD1CMD +set_io {gpio23} -iostd LVCMOS33 -pinname 98 -fixed yes +# SD1DAT0 +set_io {gpio24} -iostd LVCMOS33 -pinname 97 -fixed yes +# SPI0MOSI +set_io {gpio10} -iostd LVCMOS33 -pinname 96 -fixed yes +# SPI0MISO +set_io {gpio9} -iostd LVCMOS33 -pinname 95 -fixed yes +# SD1DAT1 +set_io {gpio25} -iostd LVCMOS33 -pinname 94 -fixed yes +# SPI0SCLK +set_io {gpio11} -iostd LVCMOS33 -pinname 93 -fixed yes +# SPI0CE0 +set_io {gpio8} -iostd LVCMOS33 -pinname 92 -fixed yes +# SPI0CE1 +set_io {gpio7} -iostd LVCMOS33 -pinname 91 -fixed yes +# GPCLK1 +set_io {gpio5} -iostd LVCMOS33 -pinname 84 -fixed yes +# GPCLK2 +set_io {gpio6} -iostd LVCMOS33 -pinname 83 -fixed yes +# PWM0 +set_io {gpio12} -iostd LVCMOS33 -pinname 82 -fixed yes +# PWM1 +set_io {gpio13} -iostd LVCMOS33 -pinname 81 -fixed yes +# PWM1/SPI1MISO/PCMFS +set_io {gpio19} -iostd LVCMOS33 -pinname 80 -fixed yes +# SPI1CE2 +set_io {gpio16} -iostd LVCMOS33 -pinname 79 -fixed yes +# SD1DAT2 +set_io {gpio26} -iostd LVCMOS33 -pinname 78 -fixed yes +# SPI1MOSI/PCMDIN/GPCLK0 +set_io {gpio20} -iostd LVCMOS33 -pinname 77 -fixed yes +# SPI1SCLK/PCMDOUT/GPCLK1 +set_io {gpio21} -iostd LVCMOS33 -pinname 76 -fixed yes + +# +# PWM +# +# Each PWM signal has cooresponding shutdown + +set_io {pwm[1]} -iostd LVCMOS33 -pinname 22 -fixed yes +set_io {shdn[1]} -iostd LVCMOS33 -pinname 21 -fixed yes +set_io {pwm[2]} -iostd LVCMOS33 -pinname 26 -fixed yes +set_io {shdn[2]} -iostd LVCMOS33 -pinname 23 -fixed yes +set_io {pwm[3]} -iostd LVCMOS33 -pinname 28 -fixed yes +set_io {shdn[3]} -iostd LVCMOS33 -pinname 27 -fixed yes + +# Fault/power stage status + +set_io {stat[1]} -iostd LVCMOS33 -pinname 29 -fixed yes +set_io {stat[2]} -iostd LVCMOS33 -pinname 30 -fixed yes +set_io {stat[3]} -iostd LVCMOS33 -pinname 31 -fixed yes + +# +# HAL inputs +# +set_io {hal_in[1]} -iostd LVCMOS33 -pinname 43 -fixed yes +set_io {hal_in[2]} -iostd LVCMOS33 -pinname 44 -fixed yes +set_io {hal_in[3]} -iostd LVCMOS33 -pinname 45 -fixed yes + +# +# IRC inputs +# +set_io {irc_a} -iostd LVCMOS33 -pinname 40 -fixed yes +set_io {irc_b} -iostd LVCMOS33 -pinname 41 -fixed yes +set_io {irc_i} -iostd LVCMOS33 -pinname 42 -fixed yes + +# +# Power status +# +set_io {power_stat} -iostd LVCMOS33 -pinname 32 -fixed yes + +# +# ADC for current +# +set_io {adc_miso} -iostd LVCMOS33 -pinname 33 -fixed yes +set_io {adc_mosi} -iostd LVCMOS33 -pinname 34 -fixed yes +set_io {adc_sclk} -iostd LVCMOS33 -pinname 35 -fixed yes +set_io {adc_scs} -iostd LVCMOS33 -pinname 36 -fixed yes + +# +# Extarnal SPI +# +set_io {ext_miso} -iostd LVCMOS33 -pinname 62 -fixed yes +set_io {ext_mosi} -iostd LVCMOS33 -pinname 61 -fixed yes +set_io {ext_sclk} -iostd LVCMOS33 -pinname 60 -fixed yes +set_io {ext_scs0} -iostd LVCMOS33 -pinname 59 -fixed yes +set_io {ext_scs1} -iostd LVCMOS33 -pinname 58 -fixed yes +set_io {ext_scs2} -iostd LVCMOS33 -pinname 57 -fixed yes + +# +# RS-485 Transceiver +# +set_io {rs485_rxd} -iostd LVCMOS33 -pinname 71 -fixed yes +set_io {rs485_txd} -iostd LVCMOS33 -pinname 69 -fixed yes +set_io {rs485_dir} -iostd LVCMOS33 -pinname 70 -fixed yes + +# +# CAN Transceiver +# +set_io {can_rx} -iostd LVCMOS33 -pinname 72 -fixed yes +set_io {can_tx} -iostd LVCMOS33 -pinname 73 -fixed yes + +# +# DIP switch +# +set_io {dip_sw[1]} -iostd LVCMOS33 -pinname 65 -fixed yes +set_io {dip_sw[2]} -iostd LVCMOS33 -pinname 64 -fixed yes +set_io {dip_sw[3]} -iostd LVCMOS33 -pinname 63 -fixed yes + +# Unused terminal to keep design tools silent +set_io {dummy_unused} -iostd LVCMOS33 -pinname 6 -fixed yes diff --git a/simple-dc/rpi_mc_simple_dc.vhdl b/simple-dc/rpi_mc_simple_dc.vhdl new file mode 100644 index 0000000..c0c7d6d --- /dev/null +++ b/simple-dc/rpi_mc_simple_dc.vhdl @@ -0,0 +1,161 @@ +-- +-- * LXPWR slave part * +-- common sioreg & common counter for several ADC&PWM blocks +-- +-- part of LXPWR motion control board (c) PiKRON Ltd +-- idea by Pavel Pisa PiKRON Ltd +-- code by Marek Peca +-- 01/2013 +-- +-- license: GNU GPLv3 +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.util.all; + +entity rpi_mc_simple_dc is + port ( + gpio2: in std_logic; -- SDA + gpio3: in std_logic; -- SCL + gpio4: in std_logic; -- CLK + gpio14: in std_logic; -- Tx + gpio15: in std_logic; -- Rx + gpio17: in std_logic; -- RTS + gpio18: in std_logic; -- PWM0/PCMCLK + gpio27: in std_logic; -- SD1DAT3 + gpio22: in std_logic; -- SD1CLK + gpio23: out std_logic; -- SD1CMD + gpio24: out std_logic; -- SD1DAT0 + gpio10: in std_logic; -- SPI0MOSI + gpio9: in std_logic; -- SPI0MISO + gpio25: in std_logic; -- SD1DAT1 + gpio11: in std_logic; -- SPI0SCLK + gpio8: out std_logic; -- SPI0CE0 + gpio7: out std_logic; -- SPI0CE1 + gpio5: in std_logic; -- GPCLK1 + gpio6: in std_logic; -- GPCLK2 + gpio12: in std_logic; -- PWM0 + gpio13: in std_logic; -- PWM1 + gpio19: in std_logic; -- PWM1/SPI1MISO/PCMFS + gpio16: in std_logic; -- SPI1CE2 + gpio26: in std_logic; -- SD1DAT2 + gpio20: in std_logic; -- SPI1MOSI/PCMDIN/GPCLK0 + gpio21: in std_logic; -- SPI1SCLK/PCMDOUT/GPCLK1 + -- + -- PWM + -- Each PWM signal has cooresponding shutdown + pwm: out std_logic_vector (1 to 3); + shdn: out std_logic_vector (1 to 3); + -- Fault/power stage status + stat: in std_logic_vector (1 to 3); + -- HAL inputs + hal_in: in std_logic_vector (1 to 3); + -- IRC inputs + irc_a: in std_logic; + irc_b: in std_logic; + irc_i: in std_logic; + -- Power status + power_stat: in std_logic; + -- ADC for current + adc_miso: in std_logic; + adc_mosi: in std_logic; + adc_sclk: in std_logic; + adc_scs: in std_logic; + -- Extarnal SPI + ext_miso: in std_logic; + ext_mosi: in std_logic; + ext_sclk: in std_logic; + ext_scs0: in std_logic; + ext_scs1: in std_logic; + ext_scs2: in std_logic; + -- RS-485 Transceiver + rs485_rxd: in std_logic; + rs485_txd: out std_logic; + rs485_dir: out std_logic; + -- CAN Transceiver + can_rx: in std_logic; + can_tx: in std_logic; + -- DIP switch + dip_sw: in std_logic_vector (1 to 3); + -- Unused terminal to keep design tools silent + dummy_unused : out std_logic + ); +end rpi_mc_simple_dc; + +architecture behavioral of rpi_mc_simple_dc is +attribute syn_noprune :boolean; +attribute syn_preserve :boolean; +attribute syn_keep :boolean; +attribute syn_hier :boolean; + -- Actel lib + -- component pll50to200 + -- port ( + -- powerdown, clka: in std_logic; + -- lock, gla: out std_logic + -- ); + -- end component; + -- component CLKINT + -- port (A: in std_logic; Y: out std_logic); + -- end component; + -- + signal pwm_in, pwm_dir_in: std_logic; + +-- attribute syn_noprune of gpio2 : signal is true; +-- attribute syn_preserve of gpio2 : signal is true; +-- attribute syn_keep of gpio2 : signal is true; +-- attribute syn_hier of gpio2 : signal is true; + +begin +-- PLL as a reset generator +-- copyclk: CLKINT +-- port map ( +-- a => clkm, +-- y => pll_clkin); +-- pll: pll50to200 +-- port map ( +-- powerdown => '1', +-- clka => pll_clkin, +-- gla => pll_clkout, +-- lock => pll_lock); +-- -- reset <= not pll_lock; +-- reset <= '0'; -- TODO: apply reset for good failsafe + -- upon power-on +-- clock <= clkm; + + dummy_unused <= gpio2 and gpio3 and gpio4 and + gpio5 and gpio6 and gpio9 and + gpio10 and gpio11 and gpio12 and gpio13 and gpio14 and + gpio15 and gpio16 and gpio17 and gpio19 and + gpio20 and gpio21 and + gpio25 and gpio26 and gpio27 and + stat(1) and stat(2) and stat(3) and + hal_in(1) and hal_in(2) and hal_in(3) and + irc_i and power_stat and adc_miso and adc_mosi and adc_sclk and adc_scs and + ext_miso and ext_mosi and ext_sclk and ext_scs0 and ext_scs1 and ext_scs2 and + rs485_rxd and + can_rx and can_tx and + dip_sw(1) and dip_sw(2) and dip_sw(3); + + rs485_txd <= '1'; + rs485_dir <= '0'; + + gpio23 <= irc_a; + gpio24 <= irc_a; + + gpio7 <= irc_b; + gpio8 <= irc_b; + + pwm_in <= gpio18; + pwm_dir_in <= gpio22; + + shdn(1) <= '0'; + shdn(2) <= '0'; + shdn(3) <= '1'; + + pwm(1) <= pwm_in and not pwm_dir_in; + pwm(2) <= pwm_in and pwm_dir_in; + pwm(3) <= '0'; + +end behavioral; diff --git a/simple-dc/syn.tcl b/simple-dc/syn.tcl new file mode 100644 index 0000000..2d12ea8 --- /dev/null +++ b/simple-dc/syn.tcl @@ -0,0 +1,21 @@ +# synplify_pro -licensetype synplifypro_actel -batch syn.tcl + +project -new rpi_mc_simple_dc +impl -name syn0 + +#add_file pll50to200.vhd +add_file util.vhdl + +# top-level +add_file rpi_mc_simple_dc.vhdl +#add_file rpi_mc_simple_dc.sdc + +set_option -technology IGLOO +set_option -part AGL250V5 +set_option -package VQFP100 +set_option -speed_grade std + +set_option -frequency 40.0 + +project -run +project -save diff --git a/simple-dc/synthetize-agl.sh b/simple-dc/synthetize-agl.sh new file mode 100755 index 0000000..872622a --- /dev/null +++ b/simple-dc/synthetize-agl.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +synplify_pro -licensetype synplifypro_actel -batch syn.tcl || exit 1 +designer SCRIPT:par.tcl LOGFILE:par.log || exit 1 diff --git a/simple-dc/util.vhdl b/simple-dc/util.vhdl new file mode 100644 index 0000000..a8bfa98 --- /dev/null +++ b/simple-dc/util.vhdl @@ -0,0 +1,51 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +package util is + -- ceil(log2(n)) + function ceil_log2(n: natural) return natural; + -- ceil(a/b) + function ceil_div(a: integer; b: integer) return integer; + -- + function max(left, right: integer) return integer; + function min(left, right: integer) return integer; +end; + +--- + +package body util is + + function ceil_log2(n: natural) return natural is + begin + if n <= 1 then + return 0; + else + if n mod 2 = 0 then + return 1 + ceil_log2(n/2); + else + return 1 + ceil_log2((n+1)/2); + end if; + end if; + end function ceil_log2; + + function ceil_div(a: integer; b: integer) return integer is + begin + return (a+b-1)/b; + end function ceil_div; + + function max(left, right: integer) return integer is + begin + if left > right then return left; + else return right; + end if; + end; + + function min(left, right: integer) return integer is + begin + if left < right then return left; + else return right; + end if; + end; + +end util; -- 2.39.2