From Hamsterworks Wiki!
After a bit of thinking, this FPGA Project was completed in an hour in November 2012.
Here is a simple FM transmitter that is surprisingly good, and very, very simple. The spectral qualities of the RF output will be pretty awful - this is not supposed to be a production design for anything, it is just a hack!
A full explanation would most probably be longer than the actual code, but here goes. It is a cross between a one-bit DAC and a phase accumulator. The output is a jittery pulse train with a frequency that is 91.0MHz +/- 75kHz of modulation, plus a whole lot of nasty harmonics.
The project uses a DCM to generate a high frequency (320MHz), that runs a 32 bit accumulator.
- Every clock cycle it adds (desired freq)/320,000,000 * 2^32 to the accumulator.
- The upper bit then flips on and off at the desired frequency (however with around 3ns of jitter) - just plug in a wire and you are done.
- For 91.0Mhz at either side of the FM band gives constants of 1222387958 and 1220374692, with a centre frequency constant of 1221381325.
My simple demo makes a square wave, but you if you were to use 1221381325 +/- 1,000,000 (e.g, a 16 bit signed sample plus five zeros) you can transmit high quality mono audio.
Just poke a wire into the antenna socket, configure your FPGA and you are away. There is a video of me testing the range at http://youtu.be/4YbDjc3Xb1E
This code is running on a Spartan 6 LX9, and you also need to add a DCM to give you a nice fast clock - the faster the clock the better the signal. You can also need to adjust the timing constants to put the signal on any channel you want.
Once again - this is just a demo, it is not supposed to be used for anything. And you most probably shouldn't be broadcasting SOS unless you want your neighbors to call out search and rescue.
------------------------------------ - Simple FM transmitter - - Mike Field <firstname.lastname@example.org - ------------------------------------ library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity fm_xmit is Port ( clk32 : in STD_LOGIC; antenna : out STD_LOGIC); end fm_xmit; architecture Behavioral of fm_xmit is component clocking port ( CLK32 : in std_logic; CLK320 : out std_logic ); end component; signal clk320 : std_logic; signal shift_ctr : unsigned (4 downto 0) := (others => '0'); signal phase_accumulator : unsigned (31 downto 0) := (others => '0'); signal beep_counter : unsigned (19 downto 0):= (others => '0'); -- gives a 305Hz beep signal signal message : std_logic_vector(33 downto 0) := "1010100011101110111000101010000000"; begin antenna <= std_logic(phase_accumulator(31)); fast_clock : clocking port map ( CLK32 => CLK32, CLK320 => CLK320 ); process(clk320) begin if rising_edge(clk320) then if beep_counter = x"FFFFF" then if shift_ctr = "00000" then message <= message(0) & message(33 downto 1); end if; shift_ctr <= shift_ctr + 1; end if; -- The constants are calculated as (desired freq)/320Mhz*2^32 if message(0) = '1' then if beep_counter(19) = '1' then phase_accumulator <= phase_accumulator + 1222387958; -- gives a 91075kHz signal else phase_accumulator <= phase_accumulator + 1220374692; -- gives 90925kHz signal end if; else phase_accumulator <= phase_accumulator + 1221381325; -- gives 91000kHz signal end if; beep_counter <= beep_counter+1; end if; end process; end Behavioral;