Correct logic to detect failed SPI communication and add option switch PWM to pass... untested
authorPavel Pisa <ppisa@pikron.com>
Tue, 6 Oct 2015 17:06:37 +0000 (19:06 +0200)
committerPavel Pisa <ppisa@pikron.com>
Tue, 6 Oct 2015 17:06:37 +0000 (19:06 +0200)
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 <ppisa@pikron.com>
pmsm-control/rpi_pmsm_control.vhdl

index 22b9f7d..e900e8d 100644 (file)
@@ -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