53604e7849c2211af2f2f4c15154fbf6ff6b7530
[fpga/rpi-motor-control.git] / pmsm-control / mcpwm.vhdl
1 --
2 -- * motion-control PWM *
3 --  PWM controller with failsafe input
4 --
5 -- part of LXPWR motion control board (c) PiKRON Ltd
6 -- idea by Pavel Pisa PiKRON Ltd <pisa@cmp.felk.cvut.cz>
7 -- code by Marek Peca <mp@duch.cz>
8 -- 01/2013
9 --
10 -- license: GNU GPLv3
11 --
12
13 library ieee;
14 use ieee.std_logic_1164.all;
15 use ieee.numeric_std.all;
16
17 entity mcpwm is
18   generic (
19     pwm_width: natural := 12
20   );
21   port (
22     -- reset: in std_logic;
23     clock: in std_logic;
24     sync: in std_logic; --flag that counter "restarts-overflows"
25     data_valid:in std_logic; --indicates data is consistent
26     failsafe: in std_logic; --failmode turn of both transistors
27     en_p, en_n: in std_logic; --enable positive & enable inverse
28     match: in std_logic_vector (pwm_width-1 downto 0); --posion of counter when we swap output logic
29     count: in std_logic_vector (pwm_width-1 downto 0); --do we use external counter?
30     
31     out_p, out_n: out std_logic --pwm outputs
32   );
33 end mcpwm;
34
35 architecture behavioral of mcpwm is
36   signal match_reg, next_match_reg: std_logic_vector (match'range);
37   signal en_p_reg, en_n_reg : std_logic;  --enable positive + inverse output
38   signal next_en_p_reg, next_en_n_reg: std_logic; --enable - next value
39   signal q, next_q: std_logic; --logic value(level) of output
40 begin
41
42  -- setting the output (q holds the logic value)
43   out_p <= q and en_p_reg and not failsafe; 
44   -- out_n <= not q and en_n_reg and not failsafe; --Use this line when using "not inteligent" half-H bridge
45   out_n <= en_n_reg or failsafe; --switch off both transistors. Use this line when "inteligent" half-H bridge is at use
46   
47   --set next values - use old or new values
48   reg: process (data_valid, failsafe, match, match_reg,
49                 en_p, en_n, en_p_reg, en_n_reg)
50   begin
51   --when theres no new data & failsafe is unset - use old values
52     next_match_reg <= match_reg;
53     next_en_p_reg <= en_p_reg;
54     next_en_n_reg <= en_n_reg;
55     
56     --when failsafe is set disable both directions
57     if failsafe = '1' then --
58       --
59       -- little paranoia, costs nothing
60       --
61       next_en_p_reg <= '0';
62       next_en_n_reg <= '0';
63       --if theres no failsafe flag & data is valid, we can set next values
64     elsif data_valid = '1' then
65       next_match_reg <= match;
66       next_en_p_reg <= en_p;
67       next_en_n_reg <= en_n;
68     end if;
69   end process;
70
71   --swaping output logic when counter counts to match
72   rs: process (sync, count, match_reg, q)               --if theres event on sync(the counter "restarts") or count 
73   begin
74     if count = match_reg then           --when the counter counts to match, we swap the signals (~middle of duty cycle)
75       next_q <= '0';
76     elsif sync = '1' then                       --syncing signal (start of duty cycle)
77       next_q <= '1';
78     else
79       next_q <= q;
80     end if;
81   end process;
82
83   seq: process
84   begin
85   --set actual -> shift next registers
86     wait until clock'event and clock = '1';
87     match_reg <= next_match_reg;
88     en_p_reg <= next_en_p_reg;
89     en_n_reg <= next_en_n_reg;
90     q <= next_q;
91   end process;
92 end behavioral;