Integration of mcpwm into toplevel entity.
authorMartin Prudek <prudemar@fel.cvut.cz>
Fri, 10 Apr 2015 09:57:54 +0000 (11:57 +0200)
committerMartin Prudek <prudemar@fel.cvut.cz>
Fri, 10 Apr 2015 09:57:54 +0000 (11:57 +0200)
pmsm-control/mcpwm.vhdl
pmsm-control/rpi_mc_simple_dc.vhdl
pmsm-control/syn.tcl

index 53604e7..f484cb0 100644 (file)
@@ -23,7 +23,7 @@ entity mcpwm is
     clock: in std_logic;
     sync: in std_logic; --flag that counter "restarts-overflows"
     data_valid:in std_logic; --indicates data is consistent
-    failsafe: in std_logic; --failmode turn of both transistors
+    failsafe: in std_logic; --failmode turn off both transistors
     en_p, en_n: in std_logic; --enable positive & enable inverse
     match: in std_logic_vector (pwm_width-1 downto 0); --posion of counter when we swap output logic
     count: in std_logic_vector (pwm_width-1 downto 0); --do we use external counter?
index 7b09532..3d188e0 100644 (file)
@@ -16,6 +16,9 @@ use ieee.numeric_std.all;
 use work.util.all;
 
 entity rpi_mc_simple_dc is
+generic(
+       pwm_width : natural:=11
+       );
 port (
        gpio2: in std_logic; -- SDA
        gpio3: in std_logic; -- SCL
@@ -113,6 +116,24 @@ architecture behavioral of rpi_mc_simple_dc is
        );
        end component;
 
+       component mcpwm is
+       generic (
+               pwm_width: natural
+       );
+       port (
+               clock: in std_logic;
+               sync: in std_logic;                             --flag that counter "restarts-overflows"
+               data_valid:in std_logic;                        --indicates data is consistent
+               failsafe: in std_logic;                         --turn off both transistors
+               en_p, en_n: in std_logic;                       --enable positive & enable shutdown
+               match: in std_logic_vector (pwm_width-1 downto 0); --posion of counter when we swap output logic
+               count: in std_logic_vector (pwm_width-1 downto 0); --we use an external counter
+               out_p, out_n: out std_logic                     --pwm outputs: positive & shutdown
+               --TODO add the rest of pwm signals, swap match to pwm_word
+       );
+       end component;
+       
+       
        type state_type is (f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,f15,r15,reset,rst_wait);
        signal state : state_type;
        
@@ -131,6 +152,19 @@ architecture behavioral of rpi_mc_simple_dc is
        signal position: std_logic_vector(31 downto 0); --pozice z qcounteru
        signal ce0_old: std_logic_vector(1 downto 0);
        
+       --pwm signals
+       constant pwm_n: natural := 3;                                   --number of pwm outputs
+       --number of ticks per pwm cycle, 2^11=2048
+       constant pwm_period : std_logic_vector (pwm_width-1 downto 0) := (others=>'1'); 
+       type pwm_res_type is array(1 to 3) of std_logic_vector (pwm_width-1 downto 0);
+       
+       signal pwm_match: pwm_res_type;                                 --point of reversion of pwm output, 0 to 2047
+       signal pwm_count: std_logic_vector (pwm_width-1 downto 0);      --counter, 0 to 2047
+       signal pwm_sync: std_logic;
+       signal pwm_en_p: std_logic_vector(1 to 3);
+       signal pwm_en_n: std_logic_vector(1 to 3);
+       
+       signal income_data_valid: std_logic;
        
        
        --  attribute syn_noprune of gpio2 : signal is true;
@@ -164,6 +198,30 @@ begin
                ab_error => open
        );
        
+       pwm_block: for i in pwm_n downto 1 generate
+               pwm_map: mcpwm
+               generic map (
+                       pwm_width => pwm_width
+               )
+               port map (
+                       clock => gpio_clk,                              --50 Mhz clk from gpclk on raspberry
+                       sync => pwm_sync,                               --counter restarts
+                       data_valid => income_data_valid,                        
+                       failsafe => '0',
+                       --
+                       -- pwm config bits & match word
+                       --
+                       en_n => pwm_en_n(i),                            --enable positive pwm
+                       en_p => pwm_en_p(i),                            --enable "negative" ->activate shutdown
+                       match => pwm_match(i),
+                       count => pwm_count,
+                       -- outputs
+                       out_p => pwm(i),                                --positive signal
+                       out_n => shdn(i)                                --reverse signal is in shutdown mode
+               );
+       end generate;
+       
+       
        
        --   pll: pll50to200
        --     port map (
@@ -197,14 +255,26 @@ begin
        rs485_dir <= '0';
 
 
-       shdn(1) <= '0';
-       shdn(2) <= '0';
-       shdn(3) <= '1';
-
-       pwm(1) <= '0';
-       pwm(2) <= '0';
-       pwm(3) <= '0';
+       --shdn(1) <= '0';
+       --shdn(2) <= '0';
+       --shdn(3) <= '1';
 
+       --pwm(1) <= '0';
+       --pwm(2) <= '0';
+       --pwm(3) <= '0';
+       
+       process
+       begin
+               wait until (gpio_clk'event and gpio_clk='1');
+               IF(pwm_count = pwm_period) THEN                         
+               --end of period reached
+                       pwm_count <= (others=>'0');      --reset counter
+                       pwm_sync <= '1';                                -- inform PWM logic about new period start
+               ELSE                                                    --end of period not reached
+                       pwm_count <= std_logic_vector(unsigned(pwm_count)+1);           --increment counter
+                       pwm_sync <= '0';
+               END IF;
+       end process;
        
        process
        begin
@@ -234,6 +304,7 @@ begin
                        
                --sestupna hrana SS, pripravime data pro prenos
                if (ce0_old = "10" ) then 
+                       income_data_valid<='0';
                        dat_reg(95 downto 64) <= position(31 downto 0); --pozice
                        dat_reg(63 downto 61) <= hal_in(1 to 3); --halovy sondy
                        dat_reg(60 downto 36) <= (others => '1'); --let the rest fill with ones
@@ -241,6 +312,13 @@ begin
                        adc_reset<='0'; --remove reset flag, and wait on its rising edge
                elsif (ce0_old = "01") then --rising edge of SS, we should read the data
                        adc_reset<=dat_reg(95);
+                       pwm_en_p(1 to 3)<=dat_reg(94 downto 92);
+                       pwm_en_n(1 to 3)<=dat_reg(91 downto 89);
+                       --11 bit pwm TODO: make it generic
+                       pwm_match(1)(pwm_width-1 downto 0)<=dat_reg(34 downto 24);
+                       pwm_match(2)(pwm_width-1 downto 0)<=dat_reg(22 downto 12);
+                       pwm_match(3)(pwm_width-1 downto 0)<=dat_reg(10 downto 0);
+                       income_data_valid<='1';
                end if;
        end process;
        
index 127a849..7fb9702 100644 (file)
@@ -7,6 +7,7 @@ impl -name syn0
 add_file util.vhdl
 add_file qcounter.vhdl
 add_file dff.vhdl
+add_file mcpwm.vhdl
 
 # top-level
 add_file rpi_mc_simple_dc.vhdl