From: Pavel Pisa Date: Tue, 6 Oct 2015 17:06:37 +0000 (+0200) Subject: Correct logic to detect failed SPI communication and add option switch PWM to pass... X-Git-Url: https://rtime.felk.cvut.cz/gitweb/fpga/rpi-motor-control.git/commitdiff_plain/ade9ac01fc3d82eaf5d4e95c51efc238cd31a2af Correct logic to detect failed SPI communication and add option switch PWM to pass-through modes. DIP SW 1 ON enabled direct IRC pass-through to GPIO pins. When DIP SW2 is selected then PWM can be controlled by GPIO. SW3 select between direction and PWM mode and complete 3 phase and 3 enables signals control mode. Signed-off-by: Pavel Pisa --- diff --git a/pmsm-control/rpi_pmsm_control.vhdl b/pmsm-control/rpi_pmsm_control.vhdl index 22b9f7d..e900e8d 100644 --- a/pmsm-control/rpi_pmsm_control.vhdl +++ b/pmsm-control/rpi_pmsm_control.vhdl @@ -31,28 +31,28 @@ generic( port ( gpio2: in std_logic; -- SDA gpio3: in std_logic; -- SCL - gpio4: in std_logic; -- CLK + gpio4: in std_logic; -- CLK (gpio_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: in std_logic; -- SD1CMD - gpio24: in std_logic; -- SD1DAT0 - gpio10: in std_logic; -- SPI0MOSI - gpio9: out std_logic; -- SPI0MISO - gpio25: in std_logic; -- SD1DAT1 - gpio11: in std_logic; -- SPI0SCLK + gpio17: inout std_logic; -- RTS (irc_i) + gpio18: in std_logic; -- PWM0/PCMCLK (pwm_in/pwm1) + gpio27: inout std_logic; -- SD1DAT3 (irc_b) + gpio22: in std_logic; -- SD1CLK (pwm_dir_in/pwm1_en) + gpio23: inout std_logic; -- SD1CMD (irc_a) + gpio24: inout std_logic; -- SD1DAT0 (irc_a) + gpio10: in std_logic; -- SPI0MOSI (spi_mosi) + gpio9: out std_logic; -- SPI0MISO (spi_miso) + gpio25: inout std_logic; -- SD1DAT1 (irc_b) + gpio11: in std_logic; -- SPI0SCLK (spi_clk) gpio8: in std_logic; -- SPI0CE0 - gpio7: in std_logic; -- SPI0CE1 + gpio7: in std_logic; -- SPI0CE1 (spi_ce) 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 + gpio12: in std_logic; -- PWM0 (pwm3) + gpio13: in std_logic; -- PWM1 (pwm2) + gpio19: in std_logic; -- PWM1/SPI1MISO/PCMFS (pwm2_en) gpio16: in std_logic; -- SPI1CE2 - gpio26: in std_logic; -- SD1DAT2 + gpio26: in std_logic; -- SD1DAT2 (pwm3_en) gpio20: in std_logic; -- SPI1MOSI/PCMDIN/GPCLK0 gpio21: in std_logic; -- SPI1SCLK/PCMDOUT/GPCLK1 -- @@ -233,13 +233,23 @@ architecture behavioral of rpi_pmsm_control is signal pwm_en_p: std_logic_vector(1 to 3); signal pwm_en_n: std_logic_vector(1 to 3); signal pwm_sig: std_logic_vector(1 to 3); + signal shdn_sig: std_logic_vector (1 to 3); signal income_data_valid: std_logic; + signal spi_timout_pulse: std_logic; signal clk_4M17: std_logic; -- irc signals processing signal irc_i_prev: std_logic; + + -- function configuration options + -- direct IRC channel A, B and I output to RPi/SoC + signal fnccfg_direct_irc: std_logic; + -- direct 3 phase PWM output + signal fnccfg_direct_3ph_pwm: std_logic; + -- PWM1 and PWM2 controlled by PWM input and direction + signal fnccfg_pwm12_by_pwm_and_dir: std_logic; --filetered irc signals signal irc_a_dff3: std_logic; @@ -248,8 +258,7 @@ architecture behavioral of rpi_pmsm_control is --16k3 clk signal signal clk_16k3: std_logic; --detekce prichazejicich prikazu po SPI - signal spi_command_lost: 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; @@ -272,9 +281,6 @@ begin gla => pll_clkout, lock => pll_lock); - -- the failasfe signal from communication block if CRC is used - next_failsafe <= '0'; - reset_async <= not pll_lock or clkmon_fail; pll_clkin <= gpio_clk; @@ -313,12 +319,15 @@ begin count => pwm_count, -- outputs out_p => pwm_sig(i), --positive signal - out_n => shdn(i) --reverse signal is in shutdown mode + out_n => shdn_sig(i) --reverse signal is in shutdown mode ); end generate; div12_map: cnt_div + generic map ( + cnt_width_g => 4 + ) port map( clk_i => gpio_clk, en_i =>'1', @@ -326,25 +335,36 @@ begin ratio_i =>"1101", --POZN.: counter detekuje cnt<=1 q_out_o =>clk_4M17 ); - - div256_map: div256 + + clk_16k3_div: cnt_div + generic map ( + cnt_width_g => 8 + ) port map( - clk_in => clk_4M17, - div256 => clk_16k3 + clk_i => gpio_clk, + en_i => clk_4M17, + reset_i => '0', + ratio_i => "11111111", + q_out_o => clk_16k3 ); - - div128_map: div128 + + spi_timeout_div : cnt_div + generic map ( + cnt_width_g => 7 + ) port map( - clk_in => clk_16k3, - rst => income_data_valid, - fail_safe => spi_command_lost -); + clk_i => gpio_clk, + en_i => clk_16k3, + reset_i => income_data_valid, + ratio_i => "1111111", + q_out_o => spi_timout_pulse + ); -- ADC needs 3.2 MHz clk when powered from +5V Vcc -- 2.0 MHz clk when +2.7V Vcc -- on the input is 4.17Mhz,but this frequency is divided inside adc_reader by 2 to 2.08 Mhz, - -- while we use +3.3V Vcc - adc_reader_map: adc_reader + -- while we use +3.3V Vcc + adc_reader_map: adc_reader port map( clk => gpio_clk, divided_clk => clk_4M17, @@ -362,14 +382,14 @@ begin port map( clk_i => gpio_clk, d_i => irc_a, - q_o => irc_a_dff3 + q_o => irc_a_dff3 ); dff3_b: dff3 port map( clk_i => gpio_clk, d_i => irc_b, - q_o => irc_b_dff3 + q_o => irc_b_dff3 ); dummy_unused <= gpio2 and gpio3 and @@ -379,15 +399,18 @@ begin gpio20 and gpio21 and gpio26 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 + irc_i and power_stat and + adc_miso and rs485_rxd and can_rx and can_tx and - dip_sw(1) and dip_sw(2) and dip_sw(3) and irc_a and irc_b and gpio17 and gpio18 and gpio27 and gpio22 and gpio23 and gpio24 and gpio25 and gpio8 and ext_scs1 and ext_scs2 and ext_miso and ext_mosi and ext_sclk and ext_scs0; + + fnccfg_direct_irc <= not dip_sw(1); + fnccfg_direct_3ph_pwm <= not dip_sw(2) and dip_sw(3); + fnccfg_pwm12_by_pwm_and_dir <= not dip_sw(2) and not dip_sw(3); rs485_txd <= '1'; rs485_dir <= '0'; @@ -397,11 +420,50 @@ begin spi_mosi <= gpio10; gpio9 <= spi_miso; - pwm(1) <= pwm_sig(1) and dip_sw(1) and not spi_command_lost; - pwm(2) <= pwm_sig(2) and dip_sw(2) and not spi_command_lost; - pwm(3) <= pwm_sig(3) and dip_sw(3) and not spi_command_lost; - - + irc_direct_output_selection: process(fnccfg_direct_irc, irc_a, irc_b, irc_i) + begin + if fnccfg_direct_irc = '1' then + gpio23 <= irc_a; + gpio24 <= irc_a; + gpio27 <= irc_b; + gpio25 <= irc_b; + gpio17 <= irc_i; + else + gpio23 <= 'Z'; + gpio24 <= 'Z'; + gpio27 <= 'Z'; + gpio25 <= 'Z'; + gpio17 <= 'Z'; + end if; + end process; + + pwm_output_selection: process(pwm_sig, shdn_sig, + fnccfg_direct_3ph_pwm, fnccfg_pwm12_by_pwm_and_dir, + fnccfg_pwm12_by_pwm_and_dir, gpio12, gpio13, gpio18, gpio19, + gpio22, gpio26) + begin + if fnccfg_direct_3ph_pwm = '1' then + pwm(1) <= gpio18; + pwm(2) <= gpio13; + pwm(3) <= gpio12; + shdn(1) <= not gpio22; + shdn(2) <= not gpio19; + shdn(3) <= not gpio26; + elsif fnccfg_pwm12_by_pwm_and_dir = '1' then + -- pwm(1) <= pwm_in and not pwm_dir_in; + pwm(1) <= gpio18 and not gpio22; + -- pwm(2) <= pwm_in and pwm_dir_in;; + pwm(2) <= gpio18 and gpio22; + pwm(3) <= '0'; + shdn(1) <= '0'; + shdn(2) <= '0'; + shdn(3) <= '1'; + else + pwm <= pwm_sig; + shdn <= shdn_sig; + end if; + end process; + process begin wait until (gpio_clk'event and gpio_clk='1'); @@ -457,10 +519,15 @@ begin end if; end if; - + + if (ce0_old = "10" ) then + income_data_valid <= '1'; + else + income_data_valid <= '0'; + end if; + --sestupna hrana SS, pripravime data pro prenos - if (ce0_old = "10" ) then - income_data_valid<='0'; + if (ce0_old = "10" ) then dat_reg(127 downto 96) <= position(31 downto 0); --pozice dat_reg(95 downto 93) <= hal_in(1 to 3); --halovy sondy dat_reg(92 downto 81) <= index_position(11 downto 0); --position of irc_i @@ -475,7 +542,6 @@ begin pwm_match(1)(pwm_width-1 downto 0)<=dat_reg(pwm_width+31 downto 32); pwm_match(2)(pwm_width-1 downto 0)<=dat_reg(pwm_width+15 downto 16); pwm_match(3)(pwm_width-1 downto 0)<=dat_reg(pwm_width-1 downto 0); - income_data_valid<='1'; end if; end process; @@ -498,6 +564,19 @@ begin end if; end process; + failsafe_spi_monitor: process (failsafe, spi_timout_pulse, income_data_valid) + begin + -- the failasfe signal from communication block if CRC is used + -- or simple watchdog for SPI communication + if income_data_valid = '1' then + next_failsafe <= '0'; + elsif spi_timout_pulse = '1' then + next_failsafe <= '1'; + else + next_failsafe <= failsafe; + end if; + end process; + async_rst: process (gpio_clk, reset_async, reset_sync) begin if reset_async = '1' then