1
0
Fork 0
mirror of https://github.com/RobotechLille/cdf2018-principal synced 2025-09-05 09:35:56 +02:00

Gestion correcte de l'asservissement

This commit is contained in:
Geoffrey Frogeye 2018-05-11 15:58:18 +02:00
parent fe3ae8efe9
commit aa519e33bf
27 changed files with 972 additions and 449 deletions

View file

@ -5,14 +5,13 @@ use IEEE.NUMERIC_STD.ALL;
entity Principal is
Generic(
fFpga : INTEGER := 50_000_000;
fBaud : INTEGER := 115200
fFpga : INTEGER := 50_000_000
);
Port (
CLK : in std_logic;
BTN: in std_logic;
RX: in std_logic;
TX: out std_logic;
SDA: inout std_logic;
SCL: inout std_logic;
LEFTCHA: in std_logic;
LEFTCHB: in std_logic;
RIGHTCHA: in std_logic;
@ -25,11 +24,11 @@ entity Principal is
BACKRECHO: in std_logic;
ENAREF: out std_logic;
ENA: out std_logic;
IN1ENC: out std_logic;
IN1: out std_logic;
IN2: out std_logic;
ENBREF: out std_logic;
ENB: out std_logic;
IN3END: out std_logic;
IN3: out std_logic;
IN4: out std_logic
);
end Principal;
@ -41,7 +40,6 @@ architecture Behavioral of Principal is
-- Encoder
signal left : integer;
signal right : integer;
signal zerocoder : std_logic;
component hedm is
Port (
@ -101,11 +99,9 @@ architecture Behavioral of Principal is
-- Motor controller
signal enAd : std_logic_vector(7 downto 0);
signal in1enCd : std_logic_vector(7 downto 0);
signal in2d : std_logic;
signal enBd : std_logic_vector(7 downto 0);
signal in3enDd : std_logic_vector(7 downto 0);
signal in4d : std_logic;
signal ind : std_logic_vector(7 downto 0);
component PWM is
port (
clk : in std_logic;
@ -115,54 +111,46 @@ architecture Behavioral of Principal is
end component;
-- CF
component uart is
generic (
baud : positive := fBaud;
clock_frequency : positive := fFpga
);
port (
clock : in std_logic;
reset : in std_logic;
data_stream_in : in std_logic_vector(7 downto 0);
data_stream_in_stb : in std_logic;
data_stream_in_ack : out std_logic;
data_stream_out : out std_logic_vector(7 downto 0);
data_stream_out_stb : out std_logic;
tx : out std_logic;
rx : in std_logic
);
component I2CSLAVE
generic(
DEVICE: std_logic_vector(7 downto 0) := x"42"
);
port(
MCLK : in std_logic;
nRST : in std_logic;
SDA_IN : in std_logic;
SCL_IN : in std_logic;
SDA_OUT : out std_logic;
SCL_OUT : out std_logic;
ADDRESS : out std_logic_vector(7 downto 0);
DATA_OUT : out std_logic_vector(7 downto 0);
DATA_IN : in std_logic_vector(7 downto 0);
WR : out std_logic;
RD : out std_logic
);
end component;
signal sdaIn : std_logic;
signal sclIn : std_logic;
signal sdaOut : std_logic;
signal sclOut : std_logic;
signal address : std_logic_vector(7 downto 0);
signal dataOut : std_logic_vector(7 downto 0);
signal dataIn : std_logic_vector(7 downto 0);
signal wr : std_logic;
signal rd : std_logic;
signal rdP : std_logic;
signal txData : std_logic_vector(7 downto 0);
signal txStb : std_logic := '0';
signal txAck : std_logic := '0';
signal rxData : std_logic_vector(7 downto 0);
signal rxStb : std_logic := '0';
-- Handling
component communication is
Port (
clock : in std_logic;
reset : in std_logic;
left : in integer;
right : in integer;
zerocoder : out std_logic;
front : in integer;
back : in integer;
txData : out std_logic_vector(7 downto 0);
txStb : out std_logic;
txAck : in std_logic;
rxData : in std_logic_vector(7 downto 0);
rxStb : in std_logic;
enA : out std_logic_vector(7 downto 0);
in1enC : out std_logic_vector(7 downto 0);
in2 : out std_logic;
enB : out std_logic_vector(7 downto 0);
in3enD : out std_logic_vector(7 downto 0);
in4 : out std_logic
);
end component;
signal leftB : std_logic_vector(15 downto 0);
signal rightB : std_logic_vector(15 downto 0);
signal frontLRawB : std_logic_vector(15 downto 0);
signal frontRRawB : std_logic_vector(15 downto 0);
signal backLRawB : std_logic_vector(15 downto 0);
signal backRRawB : std_logic_vector(15 downto 0);
signal frontLB : std_logic_vector(15 downto 0);
signal frontRB : std_logic_vector(15 downto 0);
signal backLB : std_logic_vector(15 downto 0);
signal backRB : std_logic_vector(15 downto 0);
begin
@ -184,7 +172,7 @@ begin
chA => LEFTCHA,
chB => LEFTCHB,
reset => reset,
zero => zerocoder,
zero => '0',
counts => left
);
@ -193,80 +181,80 @@ begin
chA => RIGHTCHA,
chB => RIGHTCHB,
reset => reset,
zero => zerocoder,
zero => '0',
counts => right
);
frontLCapt: hcsr04 port map (
clk => CLK,
reset => reset,
echo => FRONTLECHO,
distance => frontLRaw,
trigger => FRONTTRIGGER,
start => '1',
finished => frontLFinished
);
clk => CLK,
reset => reset,
echo => FRONTLECHO,
distance => frontLRaw,
trigger => FRONTTRIGGER,
start => '1',
finished => frontLFinished
);
frontLFilter : FIR port map (
clock => CLK,
reset => reset,
signalIn => frontLRaw,
signalOut => frontL,
start => frontLFinished
-- done => done
);
clock => CLK,
reset => reset,
signalIn => frontLRaw,
signalOut => frontL,
start => frontLFinished
-- done => done
);
frontRCapt: hcsr04 port map (
clk => CLK,
reset => reset,
echo => FRONTRECHO,
distance => frontRRaw,
-- trigger => FRONTTRIGGER,
start => '1',
finished => frontRFinished
);
clk => CLK,
reset => reset,
echo => FRONTRECHO,
distance => frontRRaw,
-- trigger => FRONTTRIGGER,
start => '1',
finished => frontRFinished
);
frontRFilter : FIR port map (
clock => CLK,
reset => reset,
signalIn => frontRRaw,
signalOut => frontR,
start => frontRFinished
-- done => done
);
clock => CLK,
reset => reset,
signalIn => frontRRaw,
signalOut => frontR,
start => frontRFinished
-- done => done
);
backLCapt: hcsr04 port map (
clk => CLK,
reset => reset,
echo => BACKLECHO,
distance => backLRaw,
trigger => BACKTRIGGER,
start => '1',
finished => backLFinished
);
clk => CLK,
reset => reset,
echo => BACKLECHO,
distance => backLRaw,
trigger => BACKTRIGGER,
start => '1',
finished => backLFinished
);
backLFilter : FIR port map (
clock => CLK,
reset => reset,
signalIn => backLRaw,
signalOut => backL,
start => backLFinished
-- done => done
);
clock => CLK,
reset => reset,
signalIn => backLRaw,
signalOut => backL,
start => backLFinished
-- done => done
);
backRCapt: hcsr04 port map (
clk => CLK,
reset => reset,
echo => BACKRECHO,
distance => backRRaw,
-- trigger => BACKTRIGGER,
start => '1',
finished => backRFinished
);
clk => CLK,
reset => reset,
echo => BACKRECHO,
distance => backRRaw,
-- trigger => BACKTRIGGER,
start => '1',
finished => backRFinished
);
backRFilter : FIR port map (
clock => CLK,
reset => reset,
signalIn => backRRaw,
signalOut => backR,
start => backRFinished
-- done => done
);
clock => CLK,
reset => reset,
signalIn => backRRaw,
signalOut => backR,
start => backRFinished
-- done => done
);
enAp : PWM port map (
clk => pwmClk,
data => enAd,
@ -274,12 +262,8 @@ begin
);
ENAREF <= '1';
in1enCp : PWM port map (
clk => pwmClk,
data => in1enCd,
pulse => IN1ENC
);
IN2 <= in2d;
IN1 <= ind(0);
IN2 <= ind(1);
enBp : PWM port map (
clk => pwmClk,
@ -288,48 +272,69 @@ begin
);
ENBREF <= '1';
in3enDp : PWM port map (
clk => pwmClk,
data => in3enDd,
pulse => IN3END
IN3 <= ind(2);
IN4 <= ind(3);
FA : i2cslave port map (
MCLK => clk,
nRST => not reset,
SDA_IN => sdaIn,
SCL_IN => sclIn,
SDA_OUT => sdaOut,
SCL_OUT => sclOut,
ADDRESS => address,
DATA_OUT => dataOut,
DATA_IN => dataIn,
WR => wr,
RD => rd
);
IN4 <= in4d;
SCL <= 'Z' when sclOut = '1' else '0';
sclIn <= to_UX01(SCL);
SDA <= 'Z' when sdaOut = '1' else '0';
sdaIn <= to_UX01(SDA);
leftB <= std_logic_vector(to_signed(left, 16));
rightB <= std_logic_vector(to_signed(right, 16));
frontLRawB <= std_logic_vector(to_unsigned(frontLRaw, 16));
frontRRawB <= std_logic_vector(to_unsigned(frontRRaw, 16));
backLRawB <= std_logic_vector(to_unsigned(backLRaw, 16));
backRRawB <= std_logic_vector(to_unsigned(backRRaw, 16));
frontLB <= std_logic_vector(to_unsigned(frontL, 16));
frontRB <= std_logic_vector(to_unsigned(frontR, 16));
backLB <= std_logic_vector(to_unsigned(backL, 16));
backRB <= std_logic_vector(to_unsigned(backR, 16));
dataIn <= x"50" when address = x"00" else
leftB(15 downto 8) when address = x"10" else
leftB(7 downto 0) when address = x"11" else
rightB(15 downto 8) when address = x"12" else
rightB(7 downto 0) when address = x"13" else
frontLRawB(15 downto 8) when address = x"20" else
frontLRawB(7 downto 0) when address = x"21" else
frontRRawB(15 downto 8) when address = x"22" else
frontRRawB(7 downto 0) when address = x"23" else
backLRawB(15 downto 8) when address = x"24" else
backLRawB(7 downto 0) when address = x"25" else
backRRawB(15 downto 8) when address = x"26" else
backRRawB(7 downto 0) when address = x"27" else
frontLB(15 downto 8) when address = x"30" else
frontLB(7 downto 0) when address = x"31" else
frontRB(15 downto 8) when address = x"32" else
frontRB(7 downto 0) when address = x"33" else
backLB(15 downto 8) when address = x"34" else
backLB(7 downto 0) when address = x"35" else
backRB(15 downto 8) when address = x"36" else
backRB(7 downto 0) when address = x"37" else
ind when address = x"60" else
enAd when address = x"61" else
enBd when address = x"62" else
(others => '0');
ind <= dataOut when (address = x"60" and wr = '1') else ind;
enAd <= dataOut when (address = x"61" and wr = '1') else enAd;
enBd <= dataOut when (address = x"62" and wr = '1') else enBd;
FA: uart port map(
clock => CLK,
reset => reset,
data_stream_in => txData,
data_stream_in_stb => txStb,
data_stream_in_ack => txAck,
data_stream_out => rxData,
data_stream_out_stb => rxStb,
tx => TX,
rx => RX
);
frontMin <= frontLRaw when frontLRaw < frontRRaw else frontRRaw;
backMin <= backLRaw when backLRaw < backRRaw else backRRaw;
com: communication port map(
clock => CLK,
reset => reset,
left => left,
right => right,
zerocoder => zerocoder,
front => frontMin,
back => backMin,
txData => txData,
txStb => txStb,
txAck => txAck,
rxData => rxData,
rxStb => rxStb,
enA => enAd,
in1enC => in1enCd,
in2 => in2d,
enB => enBd,
in3enD => in3enDd,
in4 => in4d
);
end Behavioral;

View file

@ -97,6 +97,12 @@ begin
txStb <= '0';
zerocoder <= '0';
txData <= x"00";
enA <= (others => '0');
in1enC <= (others => '0');
enB <= (others => '0');
in3enD <= (others => '0');
in2 <= '0';
in4 <= '0';
else
if rising_edge(clock) then
zerocoder <= '0';

View file

@ -23,7 +23,7 @@ architecture Behavioral of fir is
constant N : INTEGER := 4; -- Nombre de coefficients
constant M : INTEGER := 2**6; -- Facteur multiplicatif
type INT_ARRAY is array (N-1 downto 0) of integer;
constant coefficients : INT_ARRAY := (16,16,16,16);
constant coefficients : INT_ARRAY := (32,16,8,8);
-- ↑ Coefficients du fir multipliés par M
signal echantillons : INT_ARRAY := (others => 0); -- stockage des entrées retardées

283
fpga/i2c.vhd Normal file
View file

@ -0,0 +1,283 @@
--###############################
--# Project Name : I2C slave
--# File : i2cslave.vhd
--# Project : i2c slave for FPGA
--# Engineer : Philippe THIRION
--# Modification History
--###############################
-- copyright Philippe Thirion
-- github.com/tirfil
--
-- Copyright 2016 Philippe THIRION
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity I2CSLAVE is
generic(
DEVICE : std_logic_vector(7 downto 0) := x"38"
);
port(
MCLK : in std_logic;
nRST : in std_logic;
SDA_IN : in std_logic;
SCL_IN : in std_logic;
SDA_OUT : out std_logic;
SCL_OUT : out std_logic;
ADDRESS : out std_logic_vector(7 downto 0);
DATA_OUT : out std_logic_vector(7 downto 0);
DATA_IN : in std_logic_vector(7 downto 0);
WR : out std_logic;
RD : out std_logic
);
end I2CSLAVE;
architecture rtl of I2CSLAVE is
type tstate is ( S_IDLE, S_START, S_SHIFTIN, S_RW, S_SENDACK, S_SENDACK2, S_SENDNACK,
S_ADDRESS, S_WRITE, S_SHIFTOUT, S_READ, S_WAITACK
);
type toperation is (OP_READ, OP_WRITE);
signal state : tstate;
signal next_state : tstate;
signal operation : toperation;
signal rising_scl, falling_scl : std_logic;
signal address_i : std_logic_vector(7 downto 0);
signal next_address : std_logic_vector(7 downto 0);
signal counter : integer range 0 to 7;
signal start_cond : std_logic;
signal stop_cond : std_logic;
signal sda_q, sda_qq, sda_qqq : std_logic;
signal scl_q, scl_qq, scl_qqq : std_logic;
signal shiftreg : std_logic_vector(7 downto 0);
signal sda: std_logic;
signal address_incr : std_logic;
signal rd_d : std_logic;
begin
ADDRESS <= address_i;
next_address <= (others=>'0') when (address_i = x"FF") else
std_logic_vector(to_unsigned(to_integer(unsigned( address_i )) + 1, 8));
S_RSY: process(MCLK,nRST)
begin
if (nRST = '0') then
sda_q <= '1';
sda_qq <= '1';
sda_qqq <= '1';
scl_q <= '1';
scl_qq <= '1';
scl_qqq <= '1';
elsif (MCLK'event and MCLK='1') then
sda_q <= SDA_IN;
sda_qq <= sda_q;
sda_qqq <= sda_qq;
scl_q <= SCL_IN;
scl_qq <= scl_q;
scl_qqq <= scl_qq;
end if;
end process S_RSY;
rising_scl <= scl_qq and not scl_qqq;
falling_scl <= not scl_qq and scl_qqq;
START_BIT: process(MCLK,nRST)
begin
if (nRST = '0') then
start_cond <= '0';
elsif (MCLK'event and MCLK='1') then
if (sda_qqq = '1' and sda_qq = '0' and scl_qq = '1') then
start_cond <= '1';
else
start_cond <= '0';
end if;
end if;
end process START_BIT;
STOP_BIT: process(MCLK,nRST)
begin
if (nRST = '0') then
stop_cond <= '0';
elsif (MCLK'event and MCLK='1') then
if (sda_qqq = '0' and sda_qq = '1' and scl_qq = '1') then
stop_cond <= '1';
else
stop_cond <= '0';
end if;
end if;
end process STOP_BIT;
sda <= sda_qq;
RD_DELAY: process(MCLK, nRST)
begin
if (nRST = '0') then
RD <= '0';
elsif (MCLK'event and MCLK='1') then
RD <= rd_d;
end if;
end process RD_DELAY;
OTO: process(MCLK, nRST)
begin
if (nRST = '0') then
state <= S_IDLE;
SDA_OUT <= '1';
SCL_OUT <= '1';
WR <= '0';
rd_d <= '0';
address_i <= (others=>'0');
DATA_OUT <= (others=>'0');
shiftreg <= (others=>'0');
elsif (MCLK'event and MCLK='1') then
if (stop_cond = '1') then
state <= S_IDLE;
SDA_OUT <= '1';
SCL_OUT <= '1';
operation <= OP_READ;
WR <= '0';
rd_d <= '0';
address_incr <= '0';
elsif(start_cond = '1') then
state <= S_START;
SDA_OUT <= '1';
SCL_OUT <= '1';
operation <= OP_READ;
WR <= '0';
rd_d <= '0';
address_incr <= '0';
elsif(state = S_IDLE) then
state <= S_IDLE;
SDA_OUT <= '1';
SCL_OUT <= '1';
operation <= OP_READ;
WR <= '0';
rd_d <= '0';
address_incr <= '0';
elsif(state = S_START) then
shiftreg <= (others=>'0');
state <= S_SHIFTIN;
next_state <= S_RW;
counter <= 6;
elsif(state = S_SHIFTIN) then
if (rising_scl = '1') then
shiftreg(7 downto 1) <= shiftreg(6 downto 0);
shiftreg(0) <= sda;
if (counter = 0) then
state <= next_state;
counter <= 7;
else
counter <= counter - 1;
end if;
end if;
elsif(state = S_RW) then
if (rising_scl = '1') then
if (shiftreg = DEVICE) then
state <= S_SENDACK;
if (sda = '1') then
operation <= OP_READ;
-- next_state <= S_READ; -- no needed
rd_d <= '1';
else
operation <= OP_WRITE;
next_state <= S_ADDRESS;
address_incr <= '0';
end if;
else
state <= S_SENDNACK;
end if;
end if;
elsif(state = S_SENDACK) then
WR <= '0';
rd_d <= '0';
if (falling_scl = '1') then
SDA_OUT <= '0';
counter <= 7;
if (operation= OP_WRITE) then
state <= S_SENDACK2;
else -- OP_READ
state <= S_SHIFTOUT;
shiftreg <= DATA_IN;
end if;
end if;
elsif(state = S_SENDACK2) then
if (falling_scl = '1') then
SDA_OUT <= '1';
state <= S_SHIFTIN;
shiftreg <= (others=>'0');
if (address_incr = '1') then
address_i <= next_address;
end if;
end if;
elsif(state = S_SENDNACK) then
if (falling_scl = '1') then
SDA_OUT <= '1';
state <= S_IDLE;
end if;
elsif(state = S_ADDRESS) then
address_i <= shiftreg;
next_state <= S_WRITE;
state <= S_SENDACK;
address_incr <= '0';
elsif(state = S_WRITE) then
DATA_OUT <= shiftreg;
next_state <= S_WRITE;
state <= S_SENDACK;
WR <= '1';
address_incr <= '1';
elsif(state = S_SHIFTOUT) then
if (falling_scl = '1') then
SDA_OUT <= shiftreg(7);
shiftreg(7 downto 1) <= shiftreg(6 downto 0);
shiftreg(0) <= '1';
if (counter = 0) then
state <= S_READ;
address_i <= next_address;
rd_d <= '1';
else
counter <= counter - 1;
end if;
end if;
elsif(state = S_READ) then
rd_d <= '0';
if (falling_scl = '1') then
SDA_OUT <= '1';
state <= S_WAITACK;
end if;
elsif(state = S_WAITACK) then
if (rising_scl = '1') then
if (sda = '0') then
state <= S_SHIFTOUT;
counter <= 7;
shiftreg <= DATA_IN;
else
state <= S_IDLE;
end if;
end if;
end if;
end if;
end process OTO;
end rtl;

View file

@ -8,10 +8,10 @@ TIMESPEC "TS_CLK" = PERIOD "CLK" 20 ns HIGH 50 %;
NET "BTN" LOC = "P41" | IOSTANDARD = LVTTL ;
# IO<10>
NET "RX" LOC = "P85" | IOSTANDARD = LVTTL ;
NET "SCL" LOC = "P85" | IOSTANDARD = LVTTL ;
# IO<11>
NET "TX" LOC = "P84" | IOSTANDARD = LVTTL ;
NET "SDA" LOC = "P84" | IOSTANDARD = LVTTL ;
# IO<12>
NET "LEFTCHA" LOC = "P83" | IOSTANDARD = LVTTL ;
@ -44,7 +44,7 @@ NET "ENAREF" LOC = "P5" | IOSTANDARD = LVTTL ;
NET "ENA" LOC = "P4" | IOSTANDARD = LVTTL ;
# IO<22>
NET "IN1ENC" LOC = "P6" | IOSTANDARD = LVTTL ;
NET "IN1" LOC = "P6" | IOSTANDARD = LVTTL ;
# IO<23>
NET "IN2" LOC = "P98" | IOSTANDARD = LVTTL ;
@ -56,7 +56,7 @@ NET "ENBREF" LOC = "P94" | IOSTANDARD = LVTTL ;
NET "ENB" LOC = "P93" | IOSTANDARD = LVTTL ;
# IO<26>
NET "IN3END" LOC = "P90" | IOSTANDARD = LVTTL ;
NET "IN3" LOC = "P90" | IOSTANDARD = LVTTL ;
# IO<27>
NET "IN4" LOC = "P89" | IOSTANDARD = LVTTL ;

View file

@ -5,5 +5,5 @@ PROGRAMMER = mercpcl
TOPLEVEL = Principal
# Prod
VHDSOURCE = $(TOPLEVEL).vhd communication.vhd uart.vhd hedm.vhd hcsr04.vhd fir.vhd pwm.vhd
VHDSOURCE = $(TOPLEVEL).vhd i2c.vhd hedm.vhd hcsr04.vhd fir.vhd pwm.vhd
CONSTRAINTS = principal.ucf