Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL code for implementing the infrared

Status
Not open for further replies.

urakiki

Junior Member level 1
Joined
Feb 15, 2007
Messages
15
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,369
Hi everybody,

Could anybody provide me with a VHDL code implementing the infrared.
 

clk_en vhdl std_logic timer

Please clarify how an HDL relates to a wavelength of light.
 

    urakiki

    Points: 2
    Helpful Answer Positive Rating
pulse repetition frequency vhdl

sorry for lack info.

I wish to design a IR receiver with APB interface. It may support RC5 or NEC format.
 

vhdl infrared control

is it the AMBA APB.
IR is analog u can buy anyone from a hobby shop but make sure it's a wavelength matched with the IR Tx. then sample data from the IR Rx(it depends how u r transmitting @ the transmitting end) bcos u need to convert it to digital first then when u r done with this u need to interfaceit to the APB bus making ur module or design as master or slave for which u need to writea wrapper file.
 

edge interrupt vhdl

--#########################################################################################################
-- This code implements an RC5 decoder for infrared remote controls.It waits until infrared activity occurs
-- and then starts sampling the signal.First the start bits must be valid, then the toggle bit is sampled,
-- followed by the five system bits and finally the six command bits. The second phase of each bit is used
-- to check the data, whenever the data appears to be invalid, sampling is stoppen and no data or interrupt
-- is generated.The status and data registers are double buffered. A pending interrupt is cleared upon reading
-- the status register and the status register is cleared upon reading the system or the command register.
--#########################################################################################################

-- Registers:
-- [Name] [Addr] [7] [6] [5] [4] [3] [2] [1] [0]
-- Status x0 0 0 0 0 0 0 TOG RF
-- Control x1 IE EN 0 0 0 0 0 0
-- System x2 0 0 0 S4 S3 S2 S1 S0
-- Command x3 0 0 C5 C4 C3 C2 C1 C0

-- TOG - Toggle, Shows the state of the received toggle bit
-- RF - Register Full, High when new data is available
-- IE - Interrupt Enable, Generate an interrupt when the decoder is enabled and data received
-- EN - Enable, Enable/disable the decoder
-- Sx - System, The 5 System bits of the received RC5 code
-- Cx - Command, The 6 Command bits of the received RC5 code

--#########################################################################################################

library ieee;
use ieee.std_logic_1164.all;

entity rc5 is
port( clk :in std_logic; -- Clock signal
rst :in std_logic; -- Low logic reset
rd :in std_logic; -- Low logic read
wr :in std_logic; -- Low logic write
cs :in std_logic; -- Low logic chip select
rc5 :in std_logic; -- infrared data input
addr :in std_logic_vector(1 downto 0); -- Address bus input
data_in :in std_logic_vector(7 downto 0); -- Data bus input
data_out:eek:ut std_logic_vector(7 downto 0); -- output
int :eek:ut std_logic); -- Low logic interrupt output
end entity;

architecture rtl of rc5 is
--system clock frequency in Hz.The clock is preferred to be an integer multiple of 2248Hz
constant SYS_CLK:integer := 200000; -- Example: 200kHz
constant CLKS4BIT:integer := SYS_CLK/562;-- Calculate the number of clock cycled in each RC5 bittime(which is 1.778ms)
constant BUSOFF :std_logic := 'Z';-- Set this to 'Z' when making bidirectional busses

-- Signals generated by Decoder...
type STATES is (IDLE, START, TOGGLE, SYSTEM, COMMAND, FINISH);
signal state :STATES; -- States for the RC5 data frame

signal interstate :integer range 0 to 1;
signal bit_cnt :integer range 0 to 5;-- Counter for data bits
signal sys_buf,sys_reg :std_logic_vector(4 downto 0);
signal com_buf,cmd_reg :std_logic_vector(5 downto 0);

signal toggle_buf,toggle_reg,reg_full,clk_en : std_logic;
signal enable_bit,int_enable,sample : std_logic;-- Signals generated by Write-- Sample clock

-- Signals generated by ClockGen...
signal cnt :integer range 0 to CLKS4BIT;

begin

-- This state machine sequences through an expected RC5 bit sequence after a first edge has been detected.
-- The first half of each biphase bit is used as the data designator. The second half is used for
-- verification. When any of these second parts fails, the entire transmission is considered invalid and
-- no data is kept and no interrupt generated.

Decoder: process(rst, clk)
begin
if(rst = '0') then sys_reg <= (others => '0');
cmd_reg <= (others => '0');
toggle_reg <= '0';
clk_en <= '0';
interstate <= 0;
state <= IDLE;
elsif(clk'event and clk = '1') then
if(state = idle and rc5 = '1' and interstate = 0) then
clk_en <='1';
interstate <=1;
end if;
if(sample = '1') then interstate <= interstate + 1;
case state is
when IDLE => interstate <= 0;
if(interstate = 1) then
if(rc5 = '1') then state <= START;
else clk_en <= '0';
end if;
end if;
when START =>
if(interstate = 0) then
if(rc5 = '1') then state <= IDLE;
clk_en <= '0';
end if;
else
if(rc5 = '0') then state <= IDLE;
clk_en <= '0';
else state <= TOGGLE;
end if;
end if;
when TOGGLE =>
if(interstate = 0) then toggle_buf<= not rc5;
else state <= IDLE;
interstate<= 0;
if(toggle_buf = rc5) then state <= SYSTEM;
bit_cnt <= 0;
end if;
end if;
when SYSTEM =>
if(interstate = 0) then sys_buf <= (not rc5) & sys_buf(4 downto 1);
else interstate <= 0;
bit_cnt <= bit_cnt + 1;
if(sys_buf(4) /= rc5) then state <= IDLE;
end if;
if(bit_cnt = 4) then state <= COMMAND;
bit_cnt <= 0;
end if;
end if;
when COMMAND =>
if(interstate = 0) then com_buf <= (not rc5) & com_buf(5 downto 1);
else interstate <= 0;
bit_cnt <= bit_cnt + 1;
if(com_buf(5) /= rc5) then state<=IDLE;
end if;
if(bit_cnt = 5) then state<=FINISH;
end if;
end if;
when FINISH =>
if(interstate = 0) then
if(rc5 = '1') then state <=IDLE;
end if;
else
state <=IDLE;
clk_en <='0';
if(rc5 = '0') then sys_reg <=sys_buf;
cmd_reg <=com_buf;
toggle_reg <=toggle_buf;
reg_full <='1';
end if;
end if;
when others => state <=IDLE;
interstate <=0;
end case;
end if;
end if;
end process Decoder;

-- Data is latched on the falling edge of RD (and thus ample ready on the falling edge, where the data is
-- read by the CPU).

ReadOut: process(rst, rd)
begin
if(rst = '0') then data_out <= (others => BUSOFF);
elsif(rd'event and rd = '0') then
if(cs = '0') then
case addr is
when "00"=> data_out <= "000000" & toggle_reg & reg_full;
when "01"=> data_out <= int_enable & enable_bit & "000000";
when "10"=> data_out <= "000" & sys_reg;
when "11"=> data_out <= "00" & cmd_reg;
when others=> null;
end case;
else data_out <= (others => BUSOFF);
end if;
end if;
end process ReadOut;

-- Data is registered on the rising edge of the WR signal.

Write: process(rst, wr)
begin
if(rst = '0') then int_enable <= '0'; enable_bit <= '0';
elsif(wr'event and wr = '1') then
if(cs = '0') then
case addr is
when "01" => int_enable <= data_in(7);enable_bit <= data_in(6);
when others => null;
end case;
end if;
end if;
end process Write;

-- The clock generator produces the sampling clock for the RC5 data A sample pulse is produced at a quarter
-- and at three quarters of each bit. (in the middle of each biphase level)

ClockGen: process(clk_en, clk)
begin
if(clk_en = '0') then sample <= '0';cnt <= 0;
elsif(clk'event and clk = '1') then sample <= '0';cnt <= cnt + 1;
if(cnt = CLKS4BIT) then sample <= '1';
elsif(cnt = (CLKS4BIT * 3)) then sample <= '1';
elsif(cnt = ((CLKS4BIT * 4) - 1)) then cnt <= 0;
end if;
end if;
end process ClockGen;

-- An interrupt is generated at the time the status register is written (therefore the status register
-- must be updated last) When a read action starts on the device, the interrupt is cleared.
-- NOTE: It is possible to miss an interrupt, namely when a new sequence is received while the host CPU
-- is busy reading on of the registers. That is however a rare occurence since RC5 sequences should have
-- an repetition time of 114 ms. It is possible to have a new intterrupt waiting for the read action to end.

Interrupt: process(rst, cs, rd, reg_full)
begin
if(rst = '0' or (cs = '0' and rd = '0')) then int <= '1';
elsif(reg_full'event and reg_full = '1') then
if(int_enable = '1') then int <= '0'; end if;
end if;
end process Interrupt;

end rtl;
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top