OpenCores
URL https://opencores.org/ocsvn/wbfmtx/wbfmtx/trunk

Subversion Repositories wbfmtx

[/] [wbfmtx/] [trunk/] [doc/] [src/] [spec.tex] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 dgisselq
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
%%
3
%% Filename:    spec.tex
4
%%
5
%% Project:     Wishbone controlled FM Transmitter Hack
6
%%
7
%% Purpose:     This LaTeX file contains all of the documentation/description
8
%%              currently provided with this FM transmitter hack.  It's not
9
%%              nearly as interesting as the PDF file it creates, so I'd
10
%%              recommend reading that before diving into this file.  You
11
%%              should be able to find the PDF file in the SVN distribution
12
%%              together with this PDF file and a copy of the GPL-3.0 license
13
%%              this file is distributed under.  If not, just type 'make'
14
%%              in the doc directory and it (should) build without a problem.
15
%%
16
%%
17
%% Creator:     Dan Gisselquist
18
%%              Gisselquist Technology, LLC
19
%%
20
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21
%%
22
%% Copyright (C) 2016, Gisselquist Technology, LLC
23
%%
24
%% This program is free software (firmware): you can redistribute it and/or
25
%% modify it under the terms of  the GNU General Public License as published
26
%% by the Free Software Foundation, either version 3 of the License, or (at
27
%% your option) any later version.
28
%%
29
%% This program is distributed in the hope that it will be useful, but WITHOUT
30
%% ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
31
%% FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
32
%% for more details.
33
%%
34
%% You should have received a copy of the GNU General Public License along
35
%% with this program.  (It's in the $(ROOT)/doc directory, run make with no
36
%% target there if the PDF file isn't present.)  If not, see
37
%% <http://www.gnu.org/licenses/> for a copy.
38
%%
39
%% License:     GPL, v3, as defined and found on www.gnu.org,
40
%%              http://www.gnu.org/licenses/gpl.html
41
%%
42
%%
43
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
44
\documentclass{gqtekspec}
45
\project{Wishbone Controlled FM Transmitter Hack}
46
\title{Specification}
47
\author{Dan Gisselquist, Ph.D.}
48
\email{dgisselq (at) opencores.org}
49
\revision{Rev.~0.1}
50
\begin{document}
51
\pagestyle{gqtekspecplain}
52
\titlepage
53
\begin{license}
54
Copyright (C) \theyear\today, Gisselquist Technology, LLC
55
 
56
This project is free software (firmware): you can redistribute it and/or
57
modify it under the terms of  the GNU General Public License as published
58
by the Free Software Foundation, either version 3 of the License, or (at
59
your option) any later version.
60
 
61
This program is distributed in the hope that it will be useful, but WITHOUT
62
ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
63
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
64
for more details.
65
 
66
You should have received a copy of the GNU General Public License along
67
with this program.  If not, see \texttt{http://www.gnu.org/licenses/} for a
68
copy.
69
\end{license}
70
\begin{revisionhistory}
71
0.1 & 6/15/2016 & Gisselquist & First Draft \\\hline
72
\end{revisionhistory}
73
% Revision History
74
% Table of Contents, named Contents
75
\tableofcontents
76
% \listoffigures
77
\listoftables
78
\begin{preface}
79
After watching someone demonstrate a Python hack that turned a Raspberry Pi
80
into a poor man's FM transmitter, I decided that I should try to see if I could
81
do the same with an FPGA.  Indeed, it should be easier with an FPGA: the FPGA
82
has complete control of the clock, as well as what the data line does.
83
Therefore, this hack attempts to turn a GPIO line into an FM transmitter line
84
for an antenna.
85
\end{preface}
86
 
87
\chapter{Introduction}
88
\pagenumbering{arabic}
89
\setcounter{page}{1}
90
 
91
This project is a hack.
92
 
93
It is not intended, nor appropriate, for any commercial or otherwise
94
useful product.  Broadcasting on commercial FM channels has legal implications
95
associated with it.  I am not recommending that you turn your FPGA into an
96
illegal FM transmitter.
97
 
98
The purpose of this project is to show that an FPGA's outputs can be used to
99
create a (nearly) analog FM output.
100
 
101
As the preface mentions, this project is also about one-upsmanship.  Just
102
because your Raspberry Pi can do something doesn't mean my FPGA can't.  Here,
103
let me prove to you that an FPGA can create and broadcast on a commercial
104
FM radio channel.
105
 
106
As with any specification, this one is broken into sections or chapters.
107
Chap.~\ref{ch:ops} will start off by explaining how to use this core.
108
Chap.~\ref{ch:regs} will then discuss the registers in detail.  This may seem
109
like rehashing the Chap.~\ref{ch:ops} chapter, but the information is presented
110
in a different order.  Chap.~\ref{ch:wb} then presents the wishbone data sheet
111
necessary for any wishbone compliant core.  Finally, Chap.~\ref{ch:io} walks
112
through the I/O ports of the core.
113
 
114
% \chapter{Architecture}
115
\chapter{Operation}\label{ch:ops}
116
 
117
From a logical standpoint, the operation of this core is quite simple.  Just
118
follow the following steps:
119
\begin{enumerate}
120
\item Select the frequency ``channel'' to transmit on.
121
\item Adjust the sample rate to set how fast output samples will be sent to the
122
        device.
123
\item Send the first sample to the core
124
\item Wait for an interrupt, then send the next sample to the core
125
\item Repeat step 4 until the desired transmission is done.
126
\item Once transmission is complete, set the frequency ``channel'' slash
127
        NCO step size to zero.
128
\item Set the next sample to zero.
129
\item Disable, in your interrupt controller (external to this core) the
130
        interrupt generated by this core.
131
\end{enumerate}
132
 
133
Internally, the core attempts to generate a square wave at a frequency given by
134
the set frequency plus an amount given by the sample value times a constant.
135
To do this, the core maintains a 32~bit counter which will roll over at the
136
carrier
137
frequency times per second.  The top bit of this counter becomes the output
138
bit for the transmitter.   The counter is incremented every clock by an amount
139
used to set the carrier frequency, plus an amount given by the input sample.
140
 
141
For example, let's assume that the FPGA is running with an 80~MHz clock.
142
To toggle the output line at a rate of 20~Mhz, one need only set the counter
143
increment to {\tt 0x40000000}.  The top bit will, over time, trace through
144
{\tt 0, 0, 1, 1 }--creating a square wave at 20~MHz.  As a rather interesting
145
by product of the fact that this is a square wave is that this 20~MHz tone
146
will have artifacts at odd harmonics of 20~MHz: 60~MHz, 100~MHz, 140~MHz, etc.
147
The energy in each of these harmonics will decrease, dependent upon both the
148
FPGA switching speed and the nature of a square wave.  In particular, the
149
100~MHz harmonic will have 13.6~dB less power than the fundamental at 20~MHz.
150
 
151
Now, if we add a value of {\tt 0x7fff} times 32 to this counter increment,
152
creating a new increment of {\tt 0x400fffe0}, the new counter will roll over
153
as many times in $2^{32}$ clocks, creating a frequency of roughly
154
20.019~MHz. It's fifth harmonic, however, will be at 100.097~MHz, nicely at the
155
edge, if not a little beyond, the frequency range of FM broadcast radio.
156
 
157
By changing the offset to the counter increment with each sample, we create a
158
Frequency Modulation.  This is what allows us to generate an FM waveform
159
similar to that in the FM Broadcast band.
160
 
161
If only life were that simple, we'd be done at this point.
162
 
163
The next part of the operation of this hack is the antenna.  For best
164
performance, this output waveform needs to be fed into an antenna with a DC
165
block and ground as the other lead and a DC block.  Ideally, this antenna
166
should be impedence matched to the board as well.
167
 
168
For the purposes of our hack, we will ignore these details and hope to
169
demonstrate success with just the previously discussed logic.
170
 
171
\section{Software Example}
172
 
173
Before leaving our concept of operation, let's walk through some code which
174
was used to demonstrate this board.  The demonstration itself was done using
175
a ZipCPU, together with a modified version of the XuLA2-LX25 SoC, both
176
available from OpenCores.\footnote{That is, the XuLA2-LX25 SoC is available
177
from OpenCores, as is the ZipCPU, but the modified version is not posted.  It
178
just didn't seem worth it to maintain a simple hack there.}
179
 
180
The first step is to set the frequency channel of the board.  Here, we set it
181
to $91.9$~MHz, based upon an 80~MHz internal oscillator clock.
182
\begin{eqnarray}
183
{\mbox{\tt sys->io\_fmtx\_nco}} &=& \mbox{\tt 0x26147ae1;}
184
\end{eqnarray}
185
 
186
The next step is to set the sample rate of the device.  In my case, I set this
187
as a parameter to the module.  However, it can also be set here as a run time
188
configuration parameter:
189
\begin{eqnarray}
190
{\mbox{\tt sys->io\_fmtx\_audio}} &=& \mbox{\tt 1814<<16;}
191
\end{eqnarray}
192
 
193
For our example, we'll poll the interrupt controller to see when the
194
{\tt INT\_FM} interrupt line goes high:
195
\begin{eqnarray}
196
{\mbox{\tt while((sys->io\_pic \& INT\_FM)==0) ;}}
197
\end{eqnarray}
198
 
199
Once it goes high, we can send a sample to the transmitter,
200
\begin{eqnarray}
201
{\mbox{\tt sys->io\_fmtx\_audio}} &=& \mbox{\tt sample \& 0x0ffff};
202
\end{eqnarray}
203
 
204
We now repeat the process of checking the transmitter for readiness to send the next sample, and sending samples, until we are done.
205
 
206
Once complete, we simply turn the module off:
207
\begin{eqnarray}
208
{\mbox{\tt sys->io\_fmtx\_nco}} &=& \mbox{\tt 0;} \\
209
{\mbox{\tt sys->io\_fmtx\_audio}} &=& \mbox{\tt 0;}
210
\end{eqnarray}
211
 
212
 
213
That's it!  It's really quite simple to use.
214
 
215
\chapter{Registers}\label{ch:regs}
216
 
217
This FM Transmitter core supports two registers, as listed in
218
Tbl.~\ref{tbl:reglist}: a next sample register, {\tt SAMPLE}, and a carrier
219
frequency control register called {\tt NCOSTEP}.
220
\begin{table}[htbp]
221
\begin{center}
222
\begin{reglist}
223
SAMPLE  & 0 & 32 & R/W & Controls the sample value out of the transmitter,
224
        as well as the sample rate of the transmitters interrupts requesting
225
        further samples.\\\hline
226
NCOSTEP & 1 & 32 & R(/W) & Controls the step size of the pseudo-oscillator
227
        controlling the RF frequency.  Appropriate writes to this register
228
        will determine what channel the FM transmitter broadcasts on.
229
        \\\hline
230
\end{reglist}\caption{List of Registers}\label{tbl:reglist}
231
\end{center}\end{table}
232
Each register will be discussed in detail in this chapter.
233
 
234
\section{Sample Register}
235
The bits in the control register are defined in Tbl.~\ref{tbl:sample}.
236
\begin{table}[htbp]
237
\begin{center}
238
\begin{bitlist}
239
16--31 & R/W &  This is the number of clocks between interrupts.  Hence, to
240
        transmit from a waveform file sampled at a rate of $R$~samples per
241
        second, from an FPGA with a clock rate of $F$~Hz, set this value
242
        to $F/R$.  For example, to transmit at 44.1~kHz from an FPGA with
243
        an 80~MHz clock, set this value to 1814.
244
 
245
        Writing a value of zero to this register has no effect, allowing
246
        a user to only write the sample value at each write without adjusting
247
        the sample rate.\\\hline
248
0--15 & W & Signed, twos complement, next sample to be broadcast.\\\hline
249
1--15 & R & Signed, twos complement, current sample being broadcast.\\\hline
250
 
251
        actual lowest bit of the data value in the transmitter cannot be read
252
        out.\\\hline
253
\end{bitlist}
254
\caption{Sample Register}\label{tbl:sample}
255
\end{center}\end{table}
256
 
257
Basically, in sum, the top 16~bits determine the sample rate of the audio
258
being sent to the device.  Perhaps more accurately, they set the number of
259
clocks between assertions of the CPU interrupt line.  The core will internally
260
run a timer at an interval given by these bits.  When the timer is up, it will
261
transmit its next sample, assert an interrupt, and restart the timer with this
262
value.  The CPU will then have until the timer expires to provide the next
263
sample.  Writing to this register with these bits set to zero will cause them
264
to be ignored.
265
 
266
It should be possible to run this from a DMA controller, although I have not
267
tried to do so.
268
 
269
The lower 16 bits of this register, when written to, control the next audio
270
sample out of the device.  When read from, they return the current audio sample
271
being produced by the device, and in the low order bit whether or not an
272
interrupt is currently being asserted.
273
 
274
\section{Carrier Frequency Control Register}
275
Based upon Nyquist principles, properly producing a sampled tone requires
276
samples that are at least twice the frequency of the desired tone.  In the
277
case of commercial FM in the US, the highest frequency may be roughly 110~MHz.
278
This means that the FPGA must produce a sampled output using a clock of at
279
least 220~MHz.
280
 
281
My FPGA boards don't clock that high.  Instead, I can clock my Spartan--6 boards
282
at 80~MHz.  While this should be sufficient for transmitting in the Citizen's
283
Band of 26~to 28~MHz, it is entirely insufficient for transmitting at commercial
284
radio.
285
 
286
Instead, to reach these really high speeds, this core exploits what
287
is normally an undesired consequence of sampling: aliasing.  Basically, that
288
means that it is possible to produce a tone at some frequency, such as 10~MHz,
289
as well as your clock rate plus that frequency, or 90~MHz in my case.  The
290
90~MHz output is often considered an undesirable artifact of the square wave
291
outputs produced by the FPGA, but in our case we exploit this.
292
 
293
Now that all that is said, we can discuss setting the Carrier Frequency
294
Control Reigster.  This register is set when you wish to begin transmitting
295
to:
296
\begin{eqnarray}
297
{\tt CFCR} &=& \left\lfloor \frac{2^{32} f_{ch}}{f_{\mbox{\tiny FPGA}}}
298
                +\frac{1}{2}\right\rfloor
299
\end{eqnarray}
300
where $f_{ch}$ is the center frequency you wish to transmit on, and
301
$f_{\mbox{\tiny FPGA}}$ is your FPGA clock frequency.  Note that this value
302
will be greater than $2^{32}$ for my setup, since the frequency of my FPGA
303
is less than that of the channel I wish to transmit on.  In this case, just
304
throw away any bits above the lower thirty--two and continue.
305
 
306
As an example, my FPGA's clock runs at 80~MHz.  In order to transmit at
307
91.9~MHz, I would then set the {\tt CFCR} register to
308
\hbox{0x26147ae1}.
309
 
310
\chapter{Wishbone Datasheet}\label{chap:wishbone}\label{ch:wb}
311
Tbl.~\ref{tbl:wishbone}
312
\begin{table}[htbp]
313
\begin{center}
314
\begin{wishboneds}
315
Revision level of wishbone & WB B4 spec \\\hline
316
Type of interface & Slave, Read/Write, pipeline reads supported \\\hline
317
Port size & 32--bit \\\hline
318
Port granularity & 32--bit \\\hline
319
Maximum Operand Size & 32--bit \\\hline
320
Data transfer ordering & (Irrelevant) \\\hline
321
Clock constraints & None.\\\hline
322
Signal Names & \begin{tabular}{ll}
323
                Signal Name & Wishbone Equivalent \\\hline
324
                {\tt i\_wb\_clk} & {\tt CLK\_I} \\
325
                {\tt i\_wb\_cyc} & {\tt CYC\_I} \\
326
                {\tt i\_wb\_stb} & {\tt STB\_I} \\
327
                {\tt i\_wb\_we} & {\tt WE\_I} \\
328
                {\tt i\_wb\_addr} & {\tt ADR\_I} \\
329
                {\tt i\_wb\_data} & {\tt DAT\_I} \\
330
                {\tt o\_wb\_ack} & {\tt ACK\_O} \\
331
                {\tt o\_wb\_stall} & {\tt STALL\_O} \\
332
                {\tt o\_wb\_data} & {\tt DAT\_O}
333
                \end{tabular}\\\hline
334
\end{wishboneds}
335
\caption{Wishbone Datasheet}\label{tbl:wishbone}
336
\end{center}\end{table}
337
is required by the wishbone specification, and so
338
it is included here.  The big thing to notice is that this core
339
acts as a wishbone slave, and that all accesses to any local
340
registers become 32--bit reads and writes to this interface.
341
 
342
\chapter{IO Ports}\label{ch:io}
343
 
344
The ports are listed in Table.~\ref{tbl:ioports}.
345
\begin{table}[htbp]
346
\begin{center}
347
\begin{portlist}
348
{\tt i\_clk} & 1 & Input & The clock synchronizing the entire core.\\\hline
349
{\tt i\_wb\_cyc} & 1 & Input & Indicates a wishbone bus cycle is active when
350
                high.  \\\hline
351
{\tt i\_wb\_stb} & 1 & Input & Indicates a wishbone bus cycle for this
352
        peripheral when high.  (See the wishbone spec for more details) \\\hline
353
{\tt i\_wb\_we} & 1 & Input & Write enable, allows indicates a write to one of
354
        the two registers when {\tt i\_wb\_stb} is also high.
355
        \\\hline
356
{\tt i\_wb\_addr} & 1 & Input & A single address line, set to zero to access the
357
                configuration and control register, to one to access the data
358
                register.  \\\hline
359
{\tt i\_wb\_data} & 32 & Input & Data used when writing to the core.  Valid
360
                when {\tt i\_wb\_cyc}, {\tt i\_wb\_stb}, and {\tt i\_wb\_we}
361
                are all high, ignored otherwise.  \\\hline
362
{\tt o\_wb\_ack} & 1 & Output & Wishbone acknowledgement.  This line will go
363
                high on the clock after any wishbone access.\\\hline
364
{\tt o\_wb\_stall} & 1 & Output & Required by the wishbone spec, but always
365
                set to zero in this implementation.
366
                \\\hline
367
{\tt o\_wb\_data} & 32 & Output & Value read, whether the next sample register
368
        or the nco step register, headed back to the wishbone bus master.
369
        These bits will be valid during any
370
        read cycle when the {\tt o\_wb\_ack} line is high.
371
        \\\hline
372
{\tt o\_tx} & 1 & Output & A one wire output value to be sent to the ``antenna''
373
        output pin of your FPGA.\\\hline
374
{\tt o\_int} & 1 & Output & True whenever the next sample has transitioned
375
        to the current sample, until a new next sample is written. \\\hline
376
\end{portlist}
377
\caption{List of IO ports}\label{tbl:ioports}
378
\end{center}\end{table}
379
Of these ports, the {\tt i\_wb\_*} and the {\tt o\_wb\_*} ports are all
380
defined by the wishbone specification.  This leaves two ports of interest,
381
{\tt o\_tx} and {\tt o\_int}.
382
 
383
The {\tt o\_tx} output is the FM transmitter output.  This output needs to be
384
wired off of your board to your FM transmit antenna.  Should your board not have
385
such an antenna, one can often be improvised by sending this output to any
386
available output ports from your FPGA.  The more GPIO's that are set with this
387
value, the more power the device will output and likewise the better the output
388
may approximate an FM antenna.
389
 
390
Finally, the {\tt o\_int} line is an interrupt line to be sent to whatever
391
controller is controlling the transmitter.  This interrupt line will be set
392
whenever the transmitter is ready for a new sample.  It is also self clearing,
393
so that sending a sample to the transmitter will turn this off until the next
394
value is needed.
395
 
396
% Appendices
397
% Index
398
\end{document}
399
 
400
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.