Čeština / English
Login

SVN Repository / Prohlížení

Aktuální adresář: FITkit / trunk / fpga / ctrls / infra /

rc5_full.vhd

   1  -- rc5_full.vhd: Philips RC5x code IR transciever
   2  -- Copyright (C) 2009 Brno University of Technology,
   3  --                    Faculty of Information Technology
   4  -- Author(s): Michal RĹŻĹľek <xruzek01 AT stud.fit.vutbr.cz>
   5  --
   6  -- LICENSE TERMS
   7  --
   8  -- Redistribution and use in source and binary forms, with or without
   9  -- modification, are permitted provided that the following conditions
  10  -- are met:
  11  -- 1. Redistributions of source code must retain the above copyright
  12  --    notice, this list of conditions and the following disclaimer.
  13  -- 2. Redistributions in binary form must reproduce the above copyright
  14  --    notice, this list of conditions and the following disclaimer in
  15  --    the documentation and/or other materials provided with the
  16  --    distribution.
  17  -- 3. All advertising materials mentioning features or use of this software
  18  --    or firmware must display the following acknowledgement:
  19  --
  20  --      This product includes software developed by the University of
  21  --      Technology, Faculty of Information Technology, Brno and its
  22  --      contributors.
  23  --
  24  -- 4. Neither the name of the Company nor the names of its contributors
  25  --    may be used to endorse or promote products derived from this
  26  --    software without specific prior written permission.
  27  --
  28  -- This software or firmware is provided ``as is'', and any express or implied
  29  -- warranties, including, but not limited to, the implied warranties of
  30  -- merchantability and fitness for a particular purpose are disclaimed.
  31  -- In no event shall the company or contributors be liable for any
  32  -- direct, indirect, incidental, special, exemplary, or consequential
  33  -- damages (including, but not limited to, procurement of substitute
  34  -- goods or services; loss of use, data, or profits; or business
  35  -- interruption) however caused and on any theory of liability, whether
  36  -- in contract, strict liability, or tort (including negligence or
  37  -- otherwise) arising in any way out of the use of this software, even
  38  -- if advised of the possibility of such damage.
  39  --
  40  -- $Id$
  41  --
  42  --
  43  library IEEE;
  44  use IEEE.STD_LOGIC_1164.ALL;
  45  use IEEE.STD_LOGIC_ARITH.ALL;
  46  use IEEE.STD_LOGIC_UNSIGNED.ALL;
  47  
  48  architecture full of ir_RC5 is
  49  
  50  ------ signaly prijimace --------
  51  type FSMstate is (S_IDLE, S_WAIT, S_RECV, S_CNTRSET, S_SPACE1, S_SPACE2, S_COMPLETE);
  52  
  53  signal pstate     : FSMstate;
  54  signal nstate     : FSMState;
  55  
  56  signal cnt        : std_logic_vector(18 downto 0);
  57  signal cnt_rst    : std_logic;
  58  signal cnt_en     : std_logic;
  59  
  60  signal ir_reg_a   : std_logic;
  61  signal ir_reg_b   : std_logic;
  62  signal ir_down    : std_logic;
  63  signal ir_up      : std_logic;
  64  
  65  signal timeout_en : std_logic;
  66  signal timeout    : std_logic;
  67  signal reset      : std_logic;       --reset prijimace
  68  
  69  signal sh_wr      : std_logic;
  70  signal sh_en      : std_logic;
  71  signal sh_rst     : std_logic;
  72  signal sh_val     : std_logic;
  73  signal data_shreg : std_logic_vector(13 downto 0);
  74  signal dout       : std_logic_vector(12 downto 0);
  75  signal data_valid : std_logic;
  76  
  77  
  78  -------- signaly vysilace ---------
  79  type TrFSMstate is (S_IDLE, S_LOAD, S_TRANS, S_WAIT);
  80  
  81  signal tr_pstate    : TrFSMstate;
  82  signal tr_nstate    : TrFSMstate;
  83  
  84  signal tx_init      : std_logic;      --reset komponent vysilace
  85  signal gen_cmp      : std_logic;
  86  signal dclk         : std_logic;
  87  signal sh_load      : std_logic;
  88  signal data_end     : std_logic;
  89  signal frame_end    : std_logic;
  90  signal out_en       : std_logic;
  91  
  92  signal din          : std_logic_vector(13 downto 0);
  93  signal sh_reg       : std_logic_vector(13 downto 0);
  94  signal gtics        : std_logic_vector(6 downto 0);
  95  signal pcount       : std_logic_vector(12 downto 0);
  96  
  97  -------------------------------------------------------------------------------
  98  begin
  99  
 100     --------- POPIS PRIJIMACE --------
 101  
 102     DATA_VLD <= data_valid;
 103  
 104     --mapovani 13bitu dat na 24bit sbernici:
 105     -- msb | 0 0 0 0 0 0 0 TB | 0 0 0 ADR4 - ADR0 | 0 CMD6 - CMD0 | lsb
 106     DATA_OUT <= "0000000"&dout(11)&"000"&dout(10 downto 6)&'0'&(not dout(12))&dout(5 downto 0);
 107  
 108     --klopny obvod D pro pomatovani prijatych dat (do prichodu dalsich...)
 109     process(RST,CLK)
 110     begin
 111        if (RST='1') then
 112           dout <= (others => '0');
 113        elsif (CLK'event) and (CLK='1') then
 114           if (data_valid='1') then
 115              dout <= data_shreg(12 downto 0);
 116           end if;
 117        end if;
 118     end process;
 119  
 120     --detektor vzestupne a sestupne  hrany
 121     process(reset,CLK)
 122     begin
 123        if (reset = '1') then
 124           ir_reg_a  <= '1';
 125           ir_reg_b <= '1';
 126        elsif (CLK'event) and (CLK = '1') then
 127           ir_reg_a  <= IR_IN;
 128           ir_reg_b <= ir_reg_a;
 129        end if;
 130     end process;
 131     ir_down <= ir_reg_b and (not ir_reg_a);
 132     ir_up <= ( not ir_reg_b) and ir_reg_a;
 133  
 134  
 135     --hodnota do shift registru dana smerem hrany (dolu=1, nahoru=0)
 136     --staci ir_down protoze nemuzou nikdy byt oba v "1"
 137     sh_val <= ir_down;
 138  
 139  
 140     --signal povoluje zapis do posuvneho registru, v pripade nejake hrany
 141     sh_wr <= (ir_down or ir_up) and sh_en;
 142  
 143  
 144     --po dosazeni urciteho casu generovan timeout
 145     --timeout za 2*889us + 1/4*889us
 146     timeout <= '1' when (cnt="0000011100110011011") else '0';
 147  
 148     --signal reset jednak vstupnim RST, dale take timeoutem
 149     reset <= RST or  (timeout and timeout_en);
 150  
 151     --posuvny registr vystupu / format dat v data_shreg:
 152     -- msb | SB | CMD6 | TB | ADR4 - ADR0 | CMD5 - CMD0 | lsb
 153     process(sh_rst,CLK)
 154     begin
 155        if (sh_rst='1') then
 156           data_shreg <= "00000000000001";
 157        elsif (CLK'event) and (CLK='1') then
 158           if (sh_wr='1') then
 159              data_shreg <= data_shreg(12 downto 0) & sh_val;
 160           end if;
 161        end if;
 162     end process;
 163  
 164  
 165     --citac casu
 166     process(CLK,cnt_rst)
 167     begin
 168       if (cnt_rst='1') then
 169          cnt <= (others => '0');
 170       elsif (CLK'event) and (CLK='1') then
 171          if (cnt_en='1') then
 172             cnt <= cnt + 1;
 173          end if;
 174       end if;
 175     end process;
 176  
 177  
 178     --FSM Present State logic
 179     process(reset,CLK)
 180     begin
 181        if (reset='1') then
 182           pstate <= S_IDLE;
 183        elsif (CLK'event) and (CLK='1') then
 184           pstate <= nstate;
 185        end if;
 186     end process;
 187  
 188  
 189     --FSM Next State logic
 190     process(pstate,ir_down,sh_wr,cnt,data_shreg)
 191     begin
 192        nstate <= S_IDLE;
 193        case pstate is
 194  
 195           when S_IDLE =>
 196              nstate <= S_IDLE;
 197              if (ir_down='1') then
 198                 nstate <= S_WAIT;
 199              end if;
 200  
 201           when S_WAIT =>
 202              nstate <= S_WAIT;
 203              --dalsi korektni pulz ocekavan za 889us + 3/4*889us
 204              if (cnt="0000010110011001110") then
 205                 nstate <= S_RECV;
 206              end if;
 207  
 208           when S_RECV =>
 209              nstate <= S_RECV;
 210              if (data_shreg(13)='1') then
 211                 nstate <= S_SPACE1;
 212              elsif (sh_wr='1') then
 213                 nstate <= S_CNTRSET;
 214              end if;
 215  
 216           when S_CNTRSET =>
 217              nstate <= S_WAIT;
 218  
 219           when S_SPACE1 =>
 220              nstate <= S_SPACE2;
 221  
 222           when S_SPACE2 =>
 223              nstate <= S_SPACE2;
 224              if (ir_down='1') then
 225                 nstate <= S_IDLE;
 226              --po dobu 71ms nesmi prijit zadny pulz! (113ms perioda ramcu)
 227              elsif (cnt="1111111111111111111") then
 228                 nstate <= S_COMPLETE;
 229              end if;
 230  
 231           when S_COMPLETE =>
 232              nstate <= S_IDLE;
 233  
 234           when others => null;
 235        end case;
 236     end process;
 237  
 238  
 239     --FSM Output logic
 240     process(pstate)
 241     begin
 242        cnt_rst <= '0';
 243        sh_rst <= '0';
 244        data_valid <= '0';
 245        sh_en <= '0';
 246        cnt_en <= '0';
 247        timeout_en <= '1';
 248        case pstate is
 249           when S_IDLE =>
 250              cnt_rst <= '1';
 251              sh_rst <= '1';
 252  
 253           when S_WAIT =>
 254              cnt_en <= '1';
 255  
 256           when S_RECV =>
 257              sh_en <= '1';
 258              cnt_en <= '1';
 259  
 260           when S_CNTRSET =>
 261              cnt_rst <= '1';
 262  
 263           when S_SPACE1 =>
 264              cnt_rst <= '1';
 265  
 266           when S_SPACE2 =>
 267              cnt_en <= '1';
 268              timeout_en <= '0';
 269  
 270           when S_COMPLETE =>
 271              data_valid <= '1';
 272  
 273           when others => null;
 274        end case;
 275     end process;
 276  
 277  
 278     --------- POPIS VYSILACE --------
 279  
 280     --mapovani: msb | SB | CMD6 | TB | ADR4 - ADR0 | CMD5 - CMD0 | lsb
 281     din <= '1'&(not DATA_IN(6))&DATA_IN(16)&DATA_IN(12 downto 8)&DATA_IN(5 downto 0);
 282  
 283     IR_OUT <= pcount(0) when (((dclk xor sh_reg(13)) and out_en)='1') else '0';
 284  
 285     --generator 36kHz   (102 * SMCLK)
 286     gen_cmp <= '1' when (gtics="1100101") else '0';
 287     process (tx_init,CLK)
 288     begin
 289        if (tx_init='1') then
 290           gtics <= (others => '0');
 291        elsif (CLK='1') and (CLK'event) then
 292           if (gen_cmp='1') then
 293              gtics <= (others => '0');
 294           else
 295              gtics <= gtics + 1;
 296           end if;
 297        end if;
 298     end process;
 299  
 300  
 301     --pocitadlo 36kHz pulzu
 302     process (tx_init, CLK)
 303     begin
 304        if (tx_init='1') then
 305           pcount <= (others => '0');
 306        elsif (CLK='1') and (CLK'event) then
 307           if (gen_cmp='1') then
 308              pcount <= pcount+1;
 309           end if;
 310        end if;
 311     end process;
 312  
 313  
 314     --komparator pro detekci konce prenosu posledniho bitu
 315     data_end <= '1' when (pcount="0011011000000") else
 316                 '0';
 317  
 318     --komparator pro detekci konce prenosu celeho ramce
 319     frame_end <= '1' when (pcount="1111111111111") else
 320                  '0';
 321  
 322     --datove hodiny (32*36kHz)
 323     dclk <= pcount(6);
 324  
 325  
 326     --posuvny registr s asynchronnim paralelnim vstupem
 327     process(dclk,sh_load)
 328     begin
 329        if (sh_load='1') then
 330           sh_reg <= din;
 331        elsif (dclk'event and dclk='1') then
 332           sh_reg <= sh_reg(12 downto 0) & '0';
 333        end if;
 334     end process;
 335  
 336  
 337    --FSM Present State logic
 338     process(RST,CLK)
 339     begin
 340        if (RST='1') then
 341           tr_pstate <= S_IDLE;
 342        elsif (CLK'event) and (CLK='1') then
 343           tr_pstate <= tr_nstate;
 344        end if;
 345     end process;
 346  
 347  
 348     --FSM Next State logic
 349     process(tr_pstate,WRITE_EN,data_end,frame_end)
 350     begin
 351        tr_nstate <= S_IDLE;
 352        case tr_pstate is
 353  
 354           when S_IDLE =>
 355              tr_nstate <= S_IDLE;
 356              if (WRITE_EN='1') then
 357                 tr_nstate <= S_LOAD;
 358              end if;
 359  
 360           when S_LOAD =>
 361              tr_nstate <= S_TRANS;
 362  
 363           when S_TRANS =>
 364              tr_nstate <= S_TRANS;
 365              if (data_end='1') then
 366                 tr_nstate <= S_WAIT;
 367              end if;
 368  
 369           when S_WAIT =>
 370              tr_nstate <= S_WAIT;
 371              if (frame_end='1') then
 372                 tr_nstate <= S_IDLE;
 373              end if;
 374  
 375           when others => null;
 376        end case;
 377     end process;
 378  
 379  
 380     --FSM Output logic
 381     process(tr_pstate)
 382     begin
 383        tx_init <= '0';
 384        BUSY <= '1';
 385        sh_load <= '0';
 386        out_en <= '0';
 387  
 388        case tr_pstate is
 389           when S_IDLE =>
 390              tx_init <= '1';
 391              BUSY <= '0';
 392  
 393           when S_LOAD =>
 394              tx_init <= '1';
 395              sh_load <= '1';
 396  
 397           when S_TRANS =>
 398              out_en <= '1';
 399  
 400           when others => null;
 401        end case;
 402     end process;
 403  
 404  end full;
 405  
 406  
Zobrazeno: 679468x Naposledy: 25.6.2022 21:41:55