]> rtime.felk.cvut.cz Git - fpga/rpi-motor-control.git/blob - pmsm-control/rpi_mc_simple_dc.vhdl
35de1b8ecaecd4c4fa5d0b781b82adf6f904a44b
[fpga/rpi-motor-control.git] / pmsm-control / rpi_mc_simple_dc.vhdl
1 --
2 -- * LXPWR slave part *
3 --  common sioreg & common counter for several ADC&PWM blocks
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 use work.util.all;
17
18 entity rpi_mc_simple_dc is
19 port (
20         gpio2: in std_logic; -- SDA
21         gpio3: in std_logic; -- SCL
22         gpio4: in std_logic; -- CLK
23         gpio14: in std_logic; -- Tx
24         gpio15: in std_logic; -- Rx
25         gpio17: out std_logic; -- RTS
26         gpio18: out std_logic; -- PWM0/PCMCLK
27         gpio27: out std_logic; -- SD1DAT3
28         gpio22: out std_logic; -- SD1CLK
29         gpio23: out std_logic; -- SD1CMD
30         gpio24: out std_logic; -- SD1DAT0
31         gpio10: in std_logic; -- SPI0MOSI
32         gpio9: out std_logic; -- SPI0MISO
33         gpio25: out std_logic; -- SD1DAT1
34         gpio11: in std_logic; -- SPI0SCLK
35         gpio8: in std_logic; -- SPI0CE0
36         gpio7: in std_logic; -- SPI0CE1
37         gpio5: in std_logic; -- GPCLK1
38         gpio6: in std_logic; -- GPCLK2
39         gpio12: in std_logic; -- PWM0
40         gpio13: in std_logic; -- PWM1
41         gpio19: in std_logic; -- PWM1/SPI1MISO/PCMFS
42         gpio16: in std_logic; -- SPI1CE2
43         gpio26: in std_logic; -- SD1DAT2
44         gpio20: in std_logic; -- SPI1MOSI/PCMDIN/GPCLK0
45         gpio21: in std_logic; -- SPI1SCLK/PCMDOUT/GPCLK1
46         --
47         -- PWM
48         -- Each PWM signal has cooresponding shutdown
49         pwm: out std_logic_vector (1 to 3);
50         shdn: out std_logic_vector (1 to 3);
51         -- Fault/power stage status
52         stat: in std_logic_vector (1 to 3);
53         -- HAL inputs
54         hal_in: in std_logic_vector (1 to 3);
55         -- IRC inputs
56         irc_a: in std_logic;
57         irc_b: in std_logic;
58         irc_i: in std_logic;
59         -- Power status
60         power_stat: in std_logic;
61         -- ADC for current
62         adc_miso: in std_logic;
63         adc_mosi: out std_logic;
64         adc_sclk: out std_logic;
65         adc_scs: out std_logic;
66         -- Extarnal SPI
67         ext_miso: in std_logic; --master in slave out
68         ext_mosi: in std_logic; --master out slave in
69         ext_sclk: in std_logic;
70         ext_scs0: in std_logic;
71         ext_scs1: in std_logic;
72         ext_scs2: in std_logic;
73         -- RS-485 Transceiver
74         rs485_rxd: in std_logic;
75         rs485_txd: out std_logic;
76         rs485_dir: out std_logic;
77         -- CAN Transceiver
78         can_rx: in std_logic;
79         can_tx: in std_logic;
80         -- DIP switch
81         dip_sw: in std_logic_vector (1 to 3); --na desce je prohozene cislovanni
82         -- Unused terminal to keep design tools silent
83         dummy_unused : out std_logic
84 );
85 end rpi_mc_simple_dc;
86
87
88 architecture behavioral of rpi_mc_simple_dc is
89         attribute syn_noprune :boolean;
90         attribute syn_preserve :boolean;
91         attribute syn_keep :boolean;
92         attribute syn_hier :boolean;
93         -- Actel lib
94         -- component pll50to200
95         --   port (
96         --     powerdown, clka: in std_logic;
97         --     lock, gla: out std_logic
98         --   );
99         -- end component;
100         
101         component CLKINT
102                 port (A: in std_logic; Y: out std_logic);
103         end component;
104         
105         component qcounter
106         port (
107                 clock: in std_logic;
108                 reset: in std_logic;
109                 a0, b0: in std_logic;
110                 qcount: out std_logic_vector (31 downto 0);
111                 a_rise, a_fall, b_rise, b_fall, ab_event: out std_logic;
112                 ab_error: out std_logic
113         );
114         end component;
115
116         type state_type is (f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15);
117         signal state : state_type;
118         signal adc_data: std_logic_vector(11 downto 0); --ADC income data
119         
120         signal spiclk_old: std_logic_vector(1 downto 0); --pro detekci hrany SPI hodin
121         signal pwm_in, pwm_dir_in: std_logic;
122         signal gpio_clk: std_logic;
123         signal dat_reg : STD_LOGIC_VECTOR (95 downto 0); --shift register for spi
124         signal position: std_logic_vector(31 downto 0); --pozice z qcounteru
125         signal ce0_old: std_logic_vector(1 downto 0);
126         
127         
128         
129         --  attribute syn_noprune of gpio2 : signal is true;
130         --  attribute syn_preserve of gpio2 : signal is true;
131         --  attribute syn_keep of gpio2 : signal is true;
132         --  attribute syn_hier of gpio2 : signal is true;
133
134 begin
135         -- PLL as a reset generator
136         
137         --zesileni signalu GPIO CLK
138         copyclk2: CLKINT
139         port map (
140                 a => gpio4,
141                 y => gpio_clk
142         );
143         
144         
145         qcount: qcounter
146         port map (
147                 clock => gpio_clk,
148                 reset => '0',
149                 a0 => irc_a,
150                 b0 => irc_b,
151                 qcount => position,
152                 a_rise => open,
153                 a_fall => open,
154                 b_rise => open,
155                 b_fall => open,
156                 ab_event => open,
157                 ab_error => open
158         );
159         
160         
161         --   pll: pll50to200
162         --     port map (
163         --       powerdown => '1',
164         --       clka => pll_clkin,
165         --       gla => pll_clkout,
166         --       lock => pll_lock);
167         -- --  reset <= not pll_lock;
168         --   reset <= '0';                         -- TODO: apply reset for good failsafe
169                                            -- upon power-on
170         --   clock <= clkm;
171
172         dummy_unused <= gpio2 and gpio3  and gpio4 and
173                 gpio5 and gpio6 and
174                 gpio12 and gpio13 and gpio14 and
175                 gpio15 and gpio16 and gpio19 and
176                 gpio20 and gpio21 and gpio26 and
177                 stat(1) and stat(2) and stat(3) and
178                 hal_in(1) and hal_in(2) and hal_in(3) and
179                 irc_i and power_stat and 
180                 adc_miso and 
181                 rs485_rxd and
182                 can_rx and can_tx and
183                 dip_sw(1) and dip_sw(2) and dip_sw(3) and
184                 irc_a and irc_b and
185                 -- gpio17 and gpio18 and gpio27 and gpio22 and
186                 gpio8  and gpio11 and gpio7 and gpio10 and
187                 ext_scs1 and ext_scs2 and ext_miso and ext_mosi and ext_sclk and ext_scs0;
188                         
189         rs485_txd <= '1';
190         rs485_dir <= '0';
191
192
193         shdn(1) <= '0';
194         shdn(2) <= '0';
195         shdn(3) <= '1';
196
197         pwm(1) <= '0';
198         pwm(2) <= '0';
199         pwm(3) <= '0';
200
201         
202         process
203         begin
204                 --position is obtained on rising edge -> we should write it on next cycle
205                 wait until (gpio_clk'event and gpio_clk='1');
206                 
207                 --SCLK edge detection
208                 spiclk_old(0)<=gpio11;
209                 spiclk_old(1)<=spiclk_old(0);
210                 
211                 --SS edge detection
212                 ce0_old(0)<=gpio7;
213                 ce0_old(1)<=ce0_old(0);
214                 
215                 if (spiclk_old="01") then --rising edge, faze cteni
216                         if (gpio7 = '0') then             -- SPI CS must be selected
217                                 -- shift serial data into dat_reg on each rising edge
218                                 -- of SCK, MSB first
219                                 dat_reg(95 downto 0) <= dat_reg(94 downto 0) & gpio10;
220                                 end if;
221                 elsif (spiclk_old="10" ) then --falling edge, faze zapisu
222                         if (gpio7 = '0') then
223                                 gpio9 <= dat_reg(95); --zapisujeme nejdriv MSB
224                         end if;
225                 end if;
226                 
227                         
228                 --sestupna hrana SS, pripravime data pro prenos
229                 if ((ce0_old = "10") ) then 
230                         dat_reg(95 downto 64) <= position(31 downto 0); --pozice
231                         dat_reg(63 downto 61) <= hal_in(1 to 3); --halovy sondy
232                         dat_reg(60 downto 0) <= (others => '1'); --zbytek zatim nuly
233
234                 end if;
235         end process;
236         
237         process 
238         begin
239                 wait until (gpio_clk'event and gpio_clk='1');
240                 case state is
241                         when f1=>
242                                 adc_sclk<='0'; --clk
243                                 adc_scs<='0'; --active-high SS
244                                 adc_mosi<='1'; --start bit
245                                 state<=r1; --next state
246                         when r1=>       --rising edge
247                                 adc_sclk<='1';
248                                 adc_data(5)<=adc_miso;
249                                 state<=f2;
250                         when f2=> --2nd falling edge
251                                 adc_sclk<='0';
252                                 adc_mosi<='0'; --A2 address
253                                 state<=r2;
254                         when r2=> --rising edge
255                                 adc_sclk<='1';
256                                 adc_data(4)<=adc_miso;
257                                 state<=f3;
258                         when f3=> --3rd falling edge
259                                 adc_sclk<='0';
260                                 adc_mosi<='0'; --A1 address
261                                 state<=r3;
262                         when r3=> --rising edge
263                                 adc_sclk<='1';
264                                 adc_data(3)<=adc_miso;
265                                 state<=f4;      
266                         when f4=> --4th falling edge
267                                 adc_sclk<='0';
268                                 adc_mosi<='1'; --A0 address
269                                 state<=r4;
270                         when r4=> --rising edge
271                                 adc_sclk<='1';
272                                 adc_data(2)<=adc_miso;
273                                 state<=f5;      
274                         when f5=> --5th falling edge
275                                 adc_sclk<='0';
276                                 adc_mosi<='0'; --MODE (LOW -12bit)
277                                 state<=r5;
278                         when r5=> --rising edge
279                                 adc_sclk<='1';
280                                 adc_data(1)<=adc_miso;
281                                 state<=f6;      
282                         when f6=> --6th falling edge
283                                 adc_sclk<='0';
284                                 adc_mosi<='1'; --SGL/DIF (HIGH - SGL=Single Ended)
285                                 state<=r6;
286                         when r6=> --rising edge
287                                 adc_sclk<='1';
288                                 adc_data(0)<=adc_miso;
289                                 state<=f7;              
290                         when f7=> -- 7th falling edge
291                                 adc_sclk<='0';
292                                 adc_mosi<='0'; --PD1 (power down - PD1=PD0=0 -> power down between conversion)
293                                 state<=r7;
294                         when r7=> --rising edge, data ready
295                                 adc_sclk<='1';
296                                 state<=f8;      
297                         when f8=> --8th falling edge
298                                 adc_sclk<='0';
299                                 adc_mosi<='0'; --PD0
300                                 state<=r8;
301                         when r8=> --rising edge
302                                 adc_sclk<='1';
303                                 state<=f9;
304                         when f9=> --busy state between conversion, 9th falling edge
305                                 adc_sclk<='0';
306                                 state<=r9;
307                         when r9=>  --10th rising edge
308                                 adc_sclk<='1';
309                                 adc_data(11)<=adc_miso;
310                                 state<=f10;
311                         when f10=>
312                                 adc_sclk<='0';
313                                 state<=r10;
314                         when r10=>  --11th rising edge
315                                 adc_sclk<='1';
316                                 adc_data(10)<=adc_miso;
317                                 state<=f11;
318                         when f11=>
319                                 adc_sclk<='0';
320                                 state<=r11;
321                         when r11=>  --12th rising edge
322                                 adc_sclk<='1';
323                                 adc_data(9)<=adc_miso;
324                                 state<=f12;
325                         when f12=>
326                                 adc_sclk<='0';
327                                 state<=r12;
328                         when r12=>  --13th rising edge
329                                 adc_sclk<='1';
330                                 adc_data(8)<=adc_miso;
331                                 state<=f13;
332                         when f13=>
333                                 adc_sclk<='0';
334                                 state<=r13;
335                         when r13=>  --14th rising edge
336                                 adc_sclk<='1';
337                                 adc_data(7)<=adc_miso;
338                                 state<=f14;
339                         when f14=>
340                                 adc_sclk<='0';
341                                 state<=r14;
342                         when r14=> --15th rising edge
343                                 adc_data(6)<=adc_miso;
344                                 state<=f1;
345                 end case;
346         end process;
347                         
348         
349                 
350 end behavioral;
351