Čeština / English
Login

SVN Repository / Prohlížení

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

nec_full.vhd

   1  -- nec_full.vhd: NEC 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_NEC is
  49  
  50  --signaly prijimace
  51  type FSMstate is (S_IDLE, S_LEAD1, S_LEAD2, S_REP, S_NORM, S_BIT0, S_BIT1, S_STORE0, S_STORE1, S_CHECK, S_COMPLETE,S_DATA_REP);
  52  
  53  signal pstate       : FSMstate;
  54  signal nstate       : FSMState;
  55  signal cnt          : std_logic_vector(16 downto 0);
  56  signal rep_tmr      : std_logic_vector(19 downto 0);
  57  signal sh_reg       : std_logic_vector(32 downto 0);
  58  signal dout         : std_logic_vector(23 downto 0);
  59  signal sh_rst       : std_logic;
  60  signal sh_wr        : std_logic;
  61  signal sh_val       : std_logic;
  62  signal tim_rst      : std_logic;
  63  signal data_valid   : std_logic;
  64  signal recv_complet : std_logic;
  65  signal ir_reg_a     : std_logic;
  66  signal ir_reg_b     : std_logic;
  67  signal ir_down      : std_logic;
  68  signal ir_up        : std_logic;
  69  signal check_ok     : std_logic;
  70  signal repeat_data  : std_logic;
  71  signal rep_tout     : std_logic;
  72  signal last_valid   : std_logic;
  73  signal rep_tmr_rst  : std_logic;
  74  
  75  --signaly vysilace
  76  type TFSMstate is (S_IDLE, S_LOAD, S_HEADER, S_NORM, S_MARK, S_BIT0, S_BIT1, S_SHIFT, S_STOP,
  77                     S_TMRRST1, S_TMRRST2, S_TMRRST3, S_TMRRST4, S_WAIT, S_REPEAT);
  78  
  79  signal tr_pstate    : TFSMstate;
  80  signal tr_nstate    : TFSMState;
  81  signal gtics        : std_logic_vector(6 downto 0);
  82  signal space_cnt    : std_logic_vector(13 downto 0);
  83  signal tcnt         : std_logic_vector(9 downto 0);
  84  signal bitcount     : std_logic_vector(4 downto 0);
  85  signal sh_outreg    : std_logic_vector(31 downto 0);
  86  signal din          : std_logic_vector(31 downto 0);
  87  signal irout        : std_logic;
  88  signal out_en       : std_logic;
  89  signal gen_cmp      : std_logic;
  90  signal tx_init      : std_logic;
  91  signal tics_rst     : std_logic;
  92  signal dshift       : std_logic;
  93  signal sh_load      : std_logic;
  94  signal is_repeat    : std_logic;
  95  
  96  begin
  97  
  98     --kontrola prijatych dat na spravnost (komparator)
  99     check_ok <= '1' when (sh_reg(24 downto 17) = not sh_reg(32 downto 25)) else
 100                 '0';
 101  
 102  
 103     data_valid <= recv_complet and check_ok;
 104     DATA_VLD <= data_valid or repeat_data;
 105  
 106  
 107     --mapovani bitu na sbernici:
 108     -- msb | ADR15 - ADR0 | CMD7 - CMD0 | lsb
 109     DATA_OUT <= dout(15 downto 0) & dout(23 downto 16);
 110  
 111  
 112     --klopny obvod RS drzici informaci u platosti predchozich dat
 113     last_valid <= '1' when (data_valid='1') else
 114                   '0' when (rep_tout='1') else
 115                   last_valid;
 116  
 117     --komparator pro definovani maximalni doby cekani na opakovaci pulz  (115ms = cca +5%)
 118     rep_tout <= '1' when (rep_tmr="11001111000000000000") else
 119                 '0';
 120  
 121     rep_tmr_rst <= data_valid or repeat_data or rep_tout;
 122  
 123     --klopny obvod D pro pomatovani prijatych dat (do prichodu dalsich...)
 124     process(RST,CLK)
 125     begin
 126        if (RST='1') then
 127           dout <= (others => '0');
 128        elsif (CLK'event) and (CLK='1') then
 129           if (data_valid='1') then
 130              dout <= sh_reg(24 downto 1); --nezajima nas negovana podoba commandu
 131           end if;
 132        end if;
 133     end process;
 134  
 135  
 136     --detektor vzestupne a sestupne  hrany
 137     process(RST,CLK)
 138     begin
 139        if (RST = '1') then
 140           ir_reg_a  <= '1';
 141           ir_reg_b <= '1';
 142        elsif (CLK'event) and (CLK = '1') then
 143           ir_reg_a  <= IR_IN;
 144           ir_reg_b <= ir_reg_a;
 145        end if;
 146     end process;
 147     ir_down <= ir_reg_b and (not ir_reg_a);
 148     ir_up <= ( not ir_reg_b) and ir_reg_a;
 149  
 150  
 151     --citac casu pro mereni delky pulzu
 152     process(CLK,tim_rst)
 153     begin
 154       if (tim_rst='1') then
 155          cnt <= (others => '0');
 156       elsif (CLK'event) and (CLK='1') then
 157          cnt <= cnt + 1;
 158       end if;
 159     end process;
 160  
 161  
 162     --citac casu pro odpocet delky opakovaciho intervalu
 163     process(CLK, rep_tmr_rst)
 164     begin
 165       if (rep_tmr_rst='1') then
 166          rep_tmr <= (others => '0');
 167       elsif (CLK'event) and (CLK='1') then
 168          rep_tmr <= rep_tmr + 1;
 169       end if;
 170     end process;
 171  
 172  
 173     --posuvny registr vystupu
 174     -- msb | CMD'7 - CMD'0 | CMD7 - CMD0 | ADR15 - ADR0 | 1 lsb
 175     process(sh_rst,CLK)
 176     begin
 177        if (sh_rst='1') then
 178           sh_reg <= "100000000000000000000000000000000";
 179        elsif (CLK'event) and (CLK='1') then
 180           if (sh_wr='1') then
 181              sh_reg <= sh_val & sh_reg(32 downto 1);
 182           end if;
 183        end if;
 184     end process;
 185  
 186  
 187   --FSM Present State logic
 188     process(RST,CLK)
 189     begin
 190        if (RST='1') then
 191           pstate <= S_IDLE;
 192        elsif (CLK'event) and (CLK='1') then
 193           pstate <= nstate;
 194        end if;
 195     end process;
 196  
 197  
 198     --FSM Next State logic
 199     process(pstate,ir_down,ir_up,cnt,last_valid,sh_reg)
 200     begin
 201        nstate <= S_IDLE;
 202        tim_rst <= '0';
 203        case pstate is
 204  
 205           when S_IDLE =>
 206              tim_rst <= '1';
 207              nstate <= S_IDLE;
 208              if (ir_down='1') then            --sestupnou hranou zacni casovat
 209                 nstate <= S_LEAD1;
 210              end if;
 211  
 212           when S_LEAD1 =>
 213              nstate <= S_LEAD1;
 214              if (cnt="01111011000111101") then --vstup do validniho pasma (8.55ms = -5%)
 215                 nstate <= S_LEAD2;
 216              elsif (ir_up='1') then            --leader konci moc brzo -> chyba
 217                 nstate <= S_IDLE;
 218              end if;
 219  
 220           when S_LEAD2 =>
 221              nstate <= S_LEAD2;
 222              if (cnt="10001000000101000") then --timeout (9.45ms) (+5%)
 223                 nstate <= S_IDLE;
 224              elsif (ir_up='1') then            --nacten 9ms leader code, pokracuj
 225                 tim_rst <= '1';
 226                 nstate <= S_REP;               --detekci typu ramce (REP/NORM)
 227              end if;
 228  
 229           when S_REP =>
 230              nstate <= S_REP;
 231              if (cnt="00110000111101100") then --prepnuti na normalni (3.4ms)
 232                 nstate <= S_NORM;              --(stred mezi 4.5ms a 2.25ms)
 233              elsif (ir_down='1') then
 234                 if (last_valid='1') then
 235                    nstate <= S_DATA_REP;
 236                 else
 237                    nstate <= S_IDLE;
 238                 end if;
 239              end if;
 240  
 241           when S_NORM =>
 242              nstate <= S_NORM;
 243              if (cnt="01000100000010100") then --vyprseni limitu (4.725ms = +5%)
 244                 nstate <= S_IDLE;
 245              elsif (ir_down='1') then
 246                 tim_rst <= '1';
 247                 nstate <= S_BIT0;              --vlastni nacitani bitu
 248              end if;
 249  
 250           when S_BIT0 =>
 251              nstate <= S_BIT0;
 252              if (cnt="00011000011110110") then --prepnuti na bit o log 1 (1.7ms)
 253                 nstate <= S_BIT1;              --(stred mezi 1.125ms a 2.25ms)
 254              elsif (ir_down='1') then
 255                 nstate <= S_STORE0;             --nacten bit o hodnote "0"
 256              end if;
 257  
 258           when S_BIT1 =>
 259              nstate <= S_BIT1;
 260              if (cnt="00100010000001110") then --vyprseni limitu (2.363ms = +5%)
 261                 nstate <= S_IDLE;
 262              elsif (ir_down='1') then
 263                 nstate <= S_STORE1;             --nacten bit o hodnote "1"
 264              end if;
 265  
 266           when S_STORE0 =>
 267              tim_rst <= '1';
 268              nstate <= S_CHECK;
 269  
 270           when S_STORE1 =>
 271              tim_rst <= '1';
 272              nstate <= S_CHECK;
 273  
 274           when S_CHECK =>
 275              tim_rst <= '1';
 276              nstate <= S_BIT0;
 277              if (sh_reg(0)='1') then
 278                 nstate <= S_COMPLETE;
 279              end if;
 280  
 281           when S_COMPLETE =>
 282              nstate <= S_IDLE;
 283  
 284           when S_DATA_REP =>
 285              nstate <= S_IDLE;
 286  
 287           when others => null;
 288        end case;
 289     end process;
 290  
 291  
 292     --FSM Output logic
 293     process(pstate)
 294     begin
 295        sh_rst <= '0';
 296        recv_complet <= '0';
 297        sh_wr <= '0';
 298        sh_val <= '0';
 299        repeat_data <= '0';
 300  
 301        case pstate is
 302           when S_IDLE =>
 303              sh_rst <= '1';
 304  
 305           when S_STORE0 =>
 306              sh_wr <= '1';
 307  
 308           when S_STORE1 =>
 309              sh_val <= '1';
 310              sh_wr <= '1';
 311  
 312           when S_COMPLETE =>
 313              recv_complet <= '1';
 314  
 315           when S_DATA_REP =>
 316              repeat_data <= '1';
 317  
 318           when others => null;
 319        end case;
 320     end process;
 321  
 322  ------------vysilac--------------------------------------------------------
 323  
 324     --mapovani vstupnich dat  do posuvneho registru
 325     -- | neg CMD7 - CMD0 | CMD7 - CMD0 | ADR15 - ADR0 |
 326     din <= (not DATA_IN(7 downto 0)) & DATA_IN(7 downto 0) & DATA_IN (23 downto 8);
 327  
 328  
 329     IR_OUT <= irout when (out_en='1') else
 330              '0';
 331  
 332     --generator 38kHz   (97 x SMCLK) !!!!!!!!!!!!!!!!
 333     gen_cmp <= '1' when (gtics="1100001") else '0';
 334     process (tx_init,CLK)
 335     begin
 336        if (tx_init='1') then
 337           gtics <= (others => '0');
 338           irout <= '0';
 339        elsif (CLK='1') and (CLK'event) then
 340           if (gen_cmp='1') then
 341              gtics <= (others => '0');
 342              irout <= not irout;
 343           else
 344              gtics <= gtics + 1;
 345           end if;
 346        end if;
 347     end process;
 348  
 349  
 350     --pocitadlo 38kHz pulzu
 351     process (tics_rst, CLK)
 352     begin
 353        if (tics_rst='1') then
 354           tcnt <= (others => '0');
 355        elsif (CLK='1') and (CLK'event) then
 356           if (gen_cmp='1') then
 357              tcnt <= tcnt+1;
 358           end if;
 359        end if;
 360     end process;
 361  
 362  
 363     --pocitadlo vyslanych bitu
 364     process (tx_init, CLK)
 365     begin
 366        if (tx_init='1') then
 367           bitcount <= (others => '0');
 368        elsif (CLK='1') and (CLK'event) then
 369           if (dshift='1') then
 370              bitcount <= bitcount+1;
 371           end if;
 372        end if;
 373     end process;
 374  
 375  
 376     --pocitadlo delky za jakou se bude opakovat ramec
 377     process (tx_init, CLK)
 378     begin
 379        if (tx_init='1') then
 380           space_cnt <= (others => '0');
 381        elsif (CLK='1') and (CLK'event) then
 382           if (gen_cmp='1') then
 383              space_cnt <= space_cnt+1;
 384           end if;
 385        end if;
 386     end process;
 387  
 388  
 389     --posuvny registr s paralelnim vstupem
 390     process(CLK)
 391     begin
 392        if (CLK'event and CLK='1') then
 393           if (sh_load='1') then
 394              sh_outreg <= din;
 395           elsif (dshift='1') then
 396              sh_outreg <= '0' & sh_outreg(31 downto 1);
 397           end if;
 398        end if;
 399     end process;
 400  
 401  
 402     -- registr uchovavaji informaci zda jde o normalni ci opakovaci ramec
 403     process(CLK)
 404     begin
 405        if (CLK'event and CLK='1') then
 406           if (WR_REPEAT='1') then
 407              is_repeat <= '1';
 408           elsif (WRITE_EN='1') then
 409              is_repeat <= '0';
 410           end if;
 411        end if;
 412     end process;
 413  
 414  
 415     --FSM Present State logic
 416     process(RST,CLK)
 417     begin
 418        if (RST='1') then
 419           tr_pstate <= S_IDLE;
 420        elsif (CLK'event) and (CLK='1') then
 421           tr_pstate <= tr_nstate;
 422        end if;
 423     end process;
 424  
 425  
 426     --FSM Next State logic
 427     process(tr_pstate,WRITE_EN,WR_REPEAT,tcnt,bitcount,space_cnt,sh_outreg)
 428     begin
 429        tr_nstate <= S_IDLE;
 430  
 431        case tr_pstate is
 432  
 433           when S_IDLE =>
 434              tr_nstate <= S_IDLE;
 435              if (WRITE_EN='1') then
 436                 tr_nstate <= S_LOAD;
 437              elsif (WR_REPEAT='1') then
 438                 tr_nstate <= S_HEADER;
 439              end if;
 440  
 441           when S_LOAD =>
 442              tr_nstate <= S_HEADER;
 443  
 444           when S_HEADER =>              -- 9ms header
 445              tr_nstate <= S_HEADER;
 446              if (tcnt="1010101100") then
 447                 tr_nstate <= S_TMRRST1;
 448              end if;
 449  
 450           when S_TMRRST1 =>
 451              tr_nstate <= S_NORM;
 452              if (is_repeat='1') then
 453                 tr_nstate <= S_REPEAT;
 454              end if;
 455  
 456           when S_REPEAT =>              -- 2.25ms space
 457              tr_nstate <= S_REPEAT;
 458              if (tcnt="0010101010") then
 459                 tr_nstate <= S_TMRRST4;
 460              end if;
 461  
 462           when S_NORM =>                -- 4.5ms space
 463              tr_nstate <= S_NORM;
 464              if (tcnt="0101010110") then
 465                 tr_nstate <= S_TMRRST2;
 466              end if;
 467  
 468           when S_TMRRST2 =>
 469              tr_nstate <= S_MARK;
 470  
 471           when S_MARK =>                -- 560us mark
 472              tr_nstate <= S_MARK;
 473              if (tcnt="0000101010") then
 474                 tr_nstate <= S_TMRRST3;
 475              end if;
 476  
 477           when S_TMRRST3 =>
 478              if (sh_outreg(0)='1') then
 479                 tr_nstate <= S_BIT1;
 480              else
 481                 tr_nstate <= S_BIT0;
 482              end if;
 483  
 484           when S_BIT0 =>                -- 565us space
 485              tr_nstate <= S_BIT0;
 486              if (tcnt="0000101010") then
 487                 tr_nstate <= S_SHIFT;
 488              end if;
 489  
 490           when S_BIT1 =>                -- 1690us space
 491              tr_nstate <= S_BIT1;
 492              if (tcnt="0010000000") then
 493                 tr_nstate <= S_SHIFT;
 494              end if;
 495  
 496           when S_SHIFT =>
 497              tr_nstate <= S_TMRRST2;
 498              if (bitcount="11111") then
 499                 tr_nstate <= S_TMRRST4;
 500              end if;
 501  
 502           when S_TMRRST4 =>
 503              tr_nstate <= S_STOP;
 504  
 505           when S_STOP =>                -- 560us stopbit mark
 506              tr_nstate <= S_STOP;
 507              if (tcnt="0000101010") then
 508                 tr_nstate <= S_WAIT;
 509              end if;
 510  
 511           when S_WAIT =>                --ceka 8208 tiku, pak ukonci BUSY priznak
 512              tr_nstate <= S_WAIT;
 513              if (space_cnt="10000000010000") then
 514                 tr_nstate <= S_IDLE;
 515              end if;
 516  
 517           when others => null;
 518        end case;
 519     end process;
 520  
 521  
 522     --FSM Output logic
 523     process(tr_pstate)
 524     begin
 525        tx_init <= '0';
 526        BUSY <= '1';
 527        sh_load <= '0';
 528        out_en <= '0';
 529        dshift <= '0';
 530        tics_rst <= '0';
 531  
 532        case tr_pstate is
 533           when S_IDLE =>
 534              tics_rst <= '1';
 535              tx_init <= '1';
 536              BUSY <= '0';
 537  
 538           when S_LOAD =>
 539              tics_rst <= '1';
 540              sh_load <= '1';
 541              tx_init <= '1';
 542  
 543           when S_HEADER =>
 544              out_en <= '1';
 545  
 546           when S_TMRRST1 =>
 547              tics_rst <= '1';
 548  
 549           when S_TMRRST2 =>
 550              tics_rst <= '1';
 551  
 552           when S_MARK =>
 553              out_en <= '1';
 554  
 555           when S_TMRRST3 =>
 556              tics_rst <= '1';
 557  
 558           when S_SHIFT =>
 559              dshift <= '1';
 560  
 561           when S_TMRRST4 =>
 562              tics_rst <= '1';
 563  
 564           when S_STOP =>
 565              out_en <= '1';
 566  
 567           when others => null;
 568        end case;
 569     end process;
 570  
 571  end full;
 572  
Zobrazeno: 679479x Naposledy: 25.6.2022 22:05:31