Sei sulla pagina 1di 37

The Design of a LED Blinker

David Baird
Hector Malagon
Miguel Sanchez
December 17, 2004

1
Contents
1 Introduction 4

2 The Original Plan: Digital Oscilloscope 5


2.1 Theory of Operation . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3 The Modified Plan: LED Blinker 6


3.1 Theory of Operation . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.2 Connecting the LED to the Internet . . . . . . . . . . . . . . . . 6
3.3 Online GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.4 Testing Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . 8

4 Future Improvements 9
4.1 Project Management . . . . . . . . . . . . . . . . . . . . . . . . . 9
4.2 Design Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

A Altera MAX7064 Code 11


A.1 Final.gdf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
A.2 DataBus.vhd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
A.3 Decoder.vhd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
A.4 Encoder.vhd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
A.5 Register8.vhd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

B Printed Circuit Board 16


B.1 Front Silk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
B.2 Front Copper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
B.3 Back Copper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
B.4 Back Silk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
B.5 ISA Bus to MAX7064 Wiring . . . . . . . . . . . . . . . . . . . . 18

C Linux 2.4 Drivers 22


C.1 Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
C.2 blinker.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
C.3 test.sh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

D Online User Interface 26


D.1 form.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
D.2 data.txt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
D.3 form.txt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
D.4 header.txt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
D.5 main.css . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

2
List of Tables
1 Specifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2 Deliverables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3 Old Specifications . . . . . . . . . . . . . . . . . . . . . . . . . . 4
4 Voltage Levels of Interfaces . . . . . . . . . . . . . . . . . . . . . 5

List of Figures

3
Acknowledgment
Dr. William Rison Project mentor
Dr. Robert Bond Advice concerning project management and advice con-
cerning design for testability
John Battles Advice concerning design of programmable logic programs for
easier in-circuit testing

4
1. LED blinker must connect to a PC/XT or
PC/AT ISA bus
2. Drivers must be provided for Linux 2.4 or for
RTLinux
3. A convenient user interface must be wrapped
around the drivers
4. Costs should remain under $200

Table 1: Specifications

1. A report discussing the implementation of a


complete blinking LED system
2. Printed circuit board drawings for the system
3. All source code for drivers, user interface, and
programmable logic devices

Table 2: Deliverables

1 Introduction
The original goal of this project was to create a multi-channel digital oscillo-
scope, as described in §2. Due to many constraints, the project was trimmed
down to an LED blinker described in §3. The specifications for the LED blinker
are presented in Table 1. The deliverables for this project are presented in
Table 2. The specifications for the digital oscilloscope are presented in Table 3.

1. Oscilloscope will provide 16 input channels.


Two channels will be reserved for self calibra-
tion purposes.
2. Oscilloscope will sample up to 10 MSPS.
3. Oscilloscope inputs can vary across ±10 V.
4. Linux drivers must be provided.

Table 3: Old Specifications

5
Component min VIH min VOH
ISA Bus 2.0 V 2.4 V
MAX7000SLC 2.0 V 2.4 V
ACEX 1K 1.7 V 2.4 V
74ACT541 2.0 V 3.8 V
AD9240 3.5 V 2.4 V (@500 µA)
A/D converter 4.5 V (@50 µA)
AD408 Mux 2.4 V n/a

Table 4: Voltage Levels of Interfaces

2 The Original Plan: Digital Oscilloscope


2.1 Theory of Operation
The digital oscilloscope provides 16 analog inputs. Each input has protection
circuitry to prevent problems with input voltages that go outside the specs
mention in Table 3. The signals are then fed to analog muxes. The output
of the muxes are fed to a differential amplifier. The output of the differential
amplifier is fed to a 10 MSPS A/D converter.
An ACEX 1K FPGA from Altera is used to coordinate all the digital elec-
tronics. Some of the functions performed by the FPGA are selecting of mux
channels, sending a clock to the A/D converter, reading data from the A/D
converter into RAM, accepting programmed I/O commands from the ISA bus,
and dumping on-board RAM via DMA.
The ACEX 1K is RAM based, and thus needs to be programmed every time
it is powered on. A small PLD, an Altera MAX7032, is used to allow the ISA bus
to control the JTAG pins on the ACEX. The MAX7032 is based on non-volatile
memory, so it only needs to be programmed once.
The memory blocks of the ACEX 1k is used as on-board RAM used to
stored samples from the A/D converter. This memory is very limited however,
and so it cannot store a complete waveform. To solve this problem, a program
was written that takes pieces of a complete waveform and figures out how to
connect the pieces to reconstruct the complete waveform. This technique only
works when the signal being sampled is periodic.
A lot of care was put into the printed circuit layout. The PCB features a
fairly solid ground plane. Any breaks in the ground plane are kept fairly short,
especially when those breaks cut underneath signal wires on the top layer. This
is important because it minimizes the size of inductive loops formed by signal
paths and the signal return paths. The signal return paths are free to flow in the
ground plane directly beneath the signal path, except when the ground plane is
broken underneath a signal path.
Numerous test points are located on the PCB to allow convenient testing
and rewiring. Every integrated circuit was surrounded by vias that could fit

6
.100” headers. If necessary, it is possible to cut traces on the PCB and then
place populate the holes with headers and do wirewrapping to rewire the cut
traces.
The printed circuit is organized into functional blocks. There are blocks
for the power supply, input muxes, differential amplifier, A/D converter, and
programmable logic chips. It is easy to comprehend, by visual inspection, the
general flow of signals through the circuit board.
The is one shortcoming with the printed circuit board drawing: there were
too few labels. Additional labels could indicate the pin numberings on chips.
Because these labels were missing, it is necessary to count pins by hand when
debugging the board.
The PCB does not have a card edge connector to plug directly into the ISA
bus. A separate prototype perf board with a card edge connector is used. These
two boards are connected using ribbon cable and a 64 pin IDC receptacle.

2.2 Conclusions
The original plan was zealous. The plan was not fulfilled in part due to poor
project management, described in §4.1, and also in part due to inexperience of
the team members involved. This was not a failure though: we all tested our
limits and gained more experience and knowledge.

3 The Modified Plan: LED Blinker


3.1 Theory of Operation
The LED blinkers is an ISA card that provides an addressable register. The
output of this register is connected to a single LED. By writing a value, using
Intel x86 inb and outb instructions, the LED can be switched on or off. The
code for Altera chip is provided in Appendix A. The wiring information and
PCB layout was borrowed from the oscilloscope project and can be viewed in
Appendix B.
The Linux driver (see Appendix C) makes this I/O port appear as a character
device file. User space programs can open this device file and write ‘1’ or ‘0’
characters into it to turn the LED on and off. A Makefile file is provided in
the Appendix. To build the drivers, type ‘make’. To load the device driver, type
‘make reload’. To create the device file, type ‘make mknod’. The device file
will be /dev/blinker. To run a simple test, run ‘make runtest’, which will
execute test.sh.
User interface possibilities are explored by putting this device on the internet,
as described in the next section.

3.2 Connecting the LED to the Internet


TCP port 5555 is setup in listen mode. Any data written to this port is piped
data directly to /dev/blinker. A web CGI application accepts user input

7
through an HTML form. When the user submits a form, the CGI script connects
to port 5555 to control the LED. Since the computer running the LED blinker is
different from the computer running the web server, OpenSSH is used for port
tunneling.
To setup the TCP port, a prepackaged system called pipes is used. This
package can be obtained from http://bisqwit.iki.fi/source/pipes.html.
To create the TCP port, type ‘plis 5555 -i ’cat > /dev/blinker’’. The
TCP port can be quickly tested using a telnet client:

telnet localhost 5555


Trying 127.0.0.1...
Connected to localhost.
Escape character is ’^]’.
0
1
0
1

OpenSSH can be used to tunnel data by typing a command such as ‘ssh -R


5555:localhost:5555 infohost.nmt.edu’. This will forward all data from
port 5555 on infohost.nmt.edu to port 5555 on the local machine.

3.3 Online GUI


The purpose of the Online Graphical User Interface proposal is to allow for easily
configurable GUI using the well-documented, established web-standard format,
xhtml. The user interface is an xhtml web form generated using a single python
script. The page can be broken into three distinct sections: the header, the form,
and the response. User interface is divided into two components: user-interface
communication (the web form) and the interface-device communication system.
The code for all of this can be found in Appendix D.
The OGUI is a dynamically created web page, which takes advantage of
the CGI capabilities of Python. The Python script used to write the different
sections of web page are predefined in separate plain-text files. The different
files each contain portions of w3c-compliant xhtml. However, because the files
are not truly xhtml files, in-and-of themselves, they have been appended with
the .txt file-type designator. The three different sections of xhtml code are
described below.
The file header.txt is a generic heading file for the webpage. It contains
no real special information. It requires no special encoding. The data for
the header is contained in the plain-text file, ”header.txt”. The header is a
section of generic, preformatted xhtml, with simple arguments added for ease
of customizability.
The file form.txt is the most important part of the user interface. Like
the header, it is a predefined selection of xhtml with %s arguments added to

8
allow customizability. In the case of the form, the default values of the form are
returned from the cgi script to reflect the previous selection.
The intent of data.txt is to expose the current status of the device. How-
ever, the ISA device was not designed to allow reading of its current state.
Therefore, the information is simulated, using the previous input data. If com-
munication with the actual device is correct, the board response should be
identical to the last submitted values.
Aside from writing the xhtml code, the purpose of form.py is to act as the
communication link between the user and the device. Both the web form and the
communication system are designed for simplicity and general understandability.
Two methods were attempted for communication with the device. The first
plan, telnet communication, failed because of the nature of the telnet program.
The second attempt was to communicate directly with the device, using Sockets.
The telnet communication system (the SendDataTelnet function in form.py)
is quite self-explanatory. Telnet is opened and pointed to port 5555 (the arbitrar-
ily chosen TCP port of the ssh tunnel between the webserver and the computer
with the actual device). Depending on the user-requested duty cycle, either a
‘0’ or a ‘1’ is written to the telnet terminal. Unfortunately, telnet, which is
designed for interactive use, does not handle communication through pipes (i.e.
popen). Thus, the telnet method of communication had to be abandoned in
favor of a more script-friendly communication method.
The sockets communication system (the SendDataSocket function in form.py)
was very straight forward. Python includes ‘socket’ as a standard library mod-
ule. This reduced communication to opening a socket and sending a message
(either a ‘1’ or a ‘0’) to the device. The result is a rather robust communication
system that is as simple as it is effective.
The Online Graphic User Interface, although quite simplistic and lacking in
functionality, is a very nice example of creating a multi-level interface. Each
component may be readily modified without much affecting the rest of the in-
terface. Also, given the use of Python and xhtml, the interface can be easily
expanded if needed. This system will definitely be used as the basis for the
Oscilloscope UI, when that project is resumed.

3.4 Testing Procedures


1. Plug ISA card into ISA bus, without jumper to our main board. Does
computer boot? If not, then there is a defect in the ISA card.
2. Before populating main board, attach it to ISA card plugged in to ISA
bus? If not, then there is a defect in the PCB design or the manufacturer
did not meet spec.
3. Load program into Altera 7064 chip. Have testing station apply input
stimulus. Does Altera chip pass test? If not, then the chip is either fried
or the firmware loaded into the chip does not provide a reset function. A
reset function is imperative for testing and it must put every state element
into a known state.

9
4. Insert Altera 7064 chip. Does computer boot?
5. Read/write I/O ports on the Altera chip. Does the system respond as
expected?
Write multiple Altera programs to assist with testing:
1. Set all I/O to high impedance.
2. Turn an LED on when reset is applied.
3. Turn an LED off when reset is applied.
4. Allow read/write of a register mapped to some I/O address.

4 Future Improvements
Some of the guidelines were written when we discovered problems as we were
putting the system together. Good project management should be very helpful
in future projects.

4.1 Project Management


If it isn’t written down, it didn’t happen. When managing projects in the future,
this guidelines should be followed: team members need to sign statements of
work. The statement of work signed by individual team members should consist
of the following:
1. Statement of what work will be done
2. Date by which the work will be completed
3. Any risks that the signer is concerned about that may cause the work to
be unfulfilled
4. A signature from the person doing the work
Anyone assuming leadership among the team cannot tell team members
what to do and how long it will take. The team members must tell the leader
how much time they need in order to complete certain tasks. For example, if
someone is going to draw a printed circuit board, then they must give specify
a time when they will be finished. A written statement of work must then be
drawn up for the printed circuit board drawing, as described above.
Time management can also be improved. Here are some guidelines for plan-
ning time:
1. Be prepared for more than one iteration of a design. Plan for at least two
printed circuit boards revisions. This provides time to become acquainted
with the PCB vendor’s manufacturing capabilities. It also provides a
chance to iron out many mistakes in the design, such as wrong footprints
or incorrect hole sizes.

10
4.2 Design Practices
For the Altera code, the following requirements must be met:

1. Provide a reset. All state elements must enter a known state when reset
is applied. This is necessary for testing. It is very hard to test a pro-
grammable logic device if you cannot force it into a known state and then
apply stimulus to progress through other states.
2. Make it possible to route all state machine bits to pins on the chip. This
is more beneficial to complex designs than it is to simple designs.

Circuit design practices:

1. Connect VCC through a resistor. Thus shorts in the circuit can be de-
tected by measuring the voltage drop across this resistor.
2. Connect control signals such as tristate enables or reset signals through
resistors. This permits these signals to be manually controlled for purposes
of test.

PCB design practices:

1. Double check all footprints with datasheets directly from the manufac-
turer.
2. Ensure all hole diameters will allow easy and secure fitting of through hole
components.
3. Use DRC to ensure you meet manufacturing specifications.
4. Use netlists to help ensure correct wiring of the board.
5. When routing, simplify routing by taking advantage of the generic-ness of
programmable logic I/O pins and any other generic circuit blocks. Reas-
sign pins as necessary to mitigate tracks crossing each.
6. Wire all integrated circuits (and other high pin density parts, such as
connectors) to vias that can hold dual row .100” headers. This permits
easier testing and rewiring of the board.
7. Provide a solid ground plane. Keep breaks short, especially when the
breaks run perpendicularly beneath other signals. This minimizes induc-
tive loops. Inductive loops increase interference and susceptibility to in-
terference as well as increase the rise times of signals.
8. Put tick marks and/or labels next to pins and pads. This makes it easier
to count them and easier to debug.
9. Place bypass capacitors near chips that require transient current supplies.
Connections to bypass capacitors should be provided through short wiring.

11
A Altera MAX7064 Code
A.1 Final.gdf

A.2 DataBus.vhd
1 LIBRARY ieee;
2 USE ieee.std_logic_1164.all;
3
4 ENTITY DataBus IS
5
6 PORT (
7 databus :INOUT std_logic_vector(7 DOWNTO 0);
8
9 dataIn :IN std_logic_vector(7 DOWNTO 0);
10 ie :IN std_logic;
11
12 dataOut :OUT std_logic_vector(7 DOWNTO 0));
13 END DataBus;
14
15 ARCHITECTURE dataBus OF DataBus IS
16
17 BEGIN
18 iep: PROCESS ( databus, dataIn, ie )
19 BEGIN
20 IF ie = ’0’ THEN
21 databus <= (OTHERS => ’Z’);
22 dataOut <= databus;
23 ELSE
24 databus <= dataIn;
25 dataOut <= (OTHERS => ’Z’);
26 END IF;
27 END PROCESS iep;
28 END databus;

12
A.3 Decoder.vhd
1 LIBRARY ieee;
2 USE ieee.std_logic_1164.all;
3
4 ENTITY Decoder IS
5
6 PORT (
7 address :IN std_logic_vector(9 DOWNTO 0);
8 aen, iow, ior :IN std_logic;
9
10 clk_counter, w, r :OUT std_logic;
11 data :OUT std_logic_vector(7 DOWNTO 0));
12
13
14 END Decoder;
15
16 ARCHITECTURE decoder OF Decoder IS
17
18 BEGIN
19 PROCESS ( aen, address )
20 BEGIN
21 w <= NOT iow;
22 r <= NOT ior;
23 data <= (OTHERS => ’Z’);
24
25 IF aen = ’1’ THEN
26 IF address = b"1001000000" THEN
27 clk_counter <= ’1’;
28 ELSE
29 clk_counter <= ’0’;
30 END IF;
31 END IF;
32 END PROCESS;
33 END decoder;

A.4 Encoder.vhd
1 LIBRARY ieee;
2 USE ieee.std_logic_1164.all;
3
4 ENTITY Encoder IS
5
6 PORT (
7 input :IN std_logic_vector(7 DOWNTO 0);
8

13
9 output :OUT std_logic);
10
11 END Encoder;
12
13 ARCHITECTURE encoder OF Encoder IS
14
15 BEGIN
16 PROCESS ( input )
17 BEGIN
18 IF input >= x"00" AND input < x"F0" THEN
19 output <= ’0’;
20 ELSIF input >= x"F0" THEN
21 output <= ’1’;
22 END IF;
23 END PROCESS;
24 END encoder;

A.5 Register8.vhd
1 LIBRARY ieee;
2 USE ieee.std_logic_1164.all;
3
4 ENTITY Register8 IS
5
6 PORT (
7 d :IN std_logic_vector(7 DOWNTO 0);
8 clk, en :IN std_logic;
9 reset :IN std_logic;
10
11 r :OUT std_logic);
12 END Register8;
13
14 ARCHITECTURE register8 OF Register8 IS
15
16 BEGIN
17 PROCESS ( clk, en, d, reset )
18 BEGIN
19 IF reset = ’1’ THEN
20 r <= ’1’;
21
22 ELSIF clk ’EVENT AND clk = ’0’ THEN
23 IF en = ’1’ THEN
24 IF d >= x"00" AND d < x"C3" THEN
25 r <= ’0’;
26 ELSE
27 r <= ’1’;

14
28 END IF;
29 END IF;
30 END IF;
31 END PROCESS;
32 END register8;

15
16
B Printed Circuit Board
B.1 Front Silk

17
B.2 Front Copper

18
B.3 Back Copper

B.4 Back Silk

B.5 ISA Bus to MAX7064 Wiring


1 JISA v. U320
2 ============
3
4 JISA 2 A2 U320 25
5 JISA 3 A3 U320 26
6 JISA 4 A4 U320 27

19
7 JISA 5 A5 U320 28
8 JISA 6 A6 U320 29
9 JISA 7 A7 U320 31
10 JISA 8 A8 U320 33
11 JISA 9 A9 U320 34
12 JISA 11 A11 U320 36
13 JISA 22 A22 U320 8
14 JISA 23 A23 U320 9
15 JISA 24 A24 U320 11
16 JISA 25 A25 U320 12
17 JISA 26 A26 U320 14
18 JISA 27 A27 U320 16
19 JISA 28 A28 U320 17
20 JISA 29 A29 U320 18
21 JISA 30 A30 U320 19
22 JISA 31 A31 U320 20
23 JISA 32 B1 U320 1
24 JISA 32 B1 U320 2
25 JISA 32 B1 U320 10
26 JISA 32 B1 U320 22
27 JISA 32 B1 U320 30
28 JISA 32 B1 U320 42
29 JISA 32 B1 U320 43
30 JISA 32 B1 U320 44
31 JISA 34 B3 U320 3
32 JISA 34 B3 U320 15
33 JISA 34 B3 U320 23
34 JISA 34 B3 U320 35
35 JISA 41 B10 U320 1
36 JISA 41 B10 U320 2
37 JISA 41 B10 U320 10
38 JISA 41 B10 U320 22
39 JISA 41 B10 U320 30
40 JISA 41 B10 U320 42
41 JISA 41 B10 U320 43
42 JISA 41 B10 U320 44
43 JISA 44 B13 U320 21
44 JISA 45 B14 U320 24
45 JISA 60 B29 U320 3
46 JISA 60 B29 U320 15
47 JISA 60 B29 U320 23
48 JISA 60 B29 U320 35
49 JISA 62 B31 U320 1
50 JISA 62 B31 U320 2
51 JISA 62 B31 U320 10
52 JISA 62 B31 U320 22

20
53 JISA 62 B31 U320 30
54 JISA 62 B31 U320 42
55 JISA 62 B31 U320 43
56 JISA 62 B31 U320 44
57
58 U320 1 JISA 32 B1
59 U320 1 JISA 41 B10
60 U320 1 JISA 62 B31
61 U320 2 JISA 32 B1
62 U320 2 JISA 41 B10
63 U320 2 JISA 62 B31
64 U320 3 JISA 34 B3
65 U320 3 JISA 60 B29
66 U320 8 JISA 22 A22
67 U320 9 JISA 23 A23
68 U320 10 JISA 32 B1
69 U320 10 JISA 41 B10
70 U320 10 JISA 62 B31
71 U320 11 JISA 24 A24
72 U320 12 JISA 25 A25
73 U320 14 JISA 26 A26
74 U320 15 JISA 34 B3
75 U320 15 JISA 60 B29
76 U320 16 JISA 27 A27
77 U320 17 JISA 28 A28
78 U320 18 JISA 29 A29
79 U320 19 JISA 30 A30
80 U320 20 JISA 31 A31
81 U320 21 JISA 44 B13
82 U320 22 JISA 32 B1
83 U320 22 JISA 41 B10
84 U320 22 JISA 62 B31
85 U320 23 JISA 34 B3
86 U320 23 JISA 60 B29
87 U320 24 JISA 45 B14
88 U320 25 JISA 2 A2
89 U320 26 JISA 3 A3
90 U320 27 JISA 4 A4
91 U320 28 JISA 5 A5
92 U320 29 JISA 6 A6
93 U320 30 JISA 32 B1
94 U320 30 JISA 41 B10
95 U320 30 JISA 62 B31
96 U320 31 JISA 7 A7
97 U320 33 JISA 8 A8
98 U320 34 JISA 9 A9

21
99 U320 35 JISA 34 B3
100 U320 35 JISA 60 B29
101 U320 36 JISA 11 A11
102 U320 42 JISA 32 B1
103 U320 42 JISA 41 B10
104 U320 42 JISA 62 B31
105 U320 43 JISA 32 B1
106 U320 43 JISA 41 B10
107 U320 43 JISA 62 B31
108 U320 44 JISA 32 B1
109 U320 44 JISA 41 B10
110 U320 44 JISA 62 B31

22
C Linux 2.4 Drivers
C.1 Makefile
1 KERNELDIR = /usr/src/linux-2.4.22
2 include $(KERNELDIR)/.config
3 CFLAGS = -D__KERNEL__ -DMODULE -I$(KERNELDIR)/include -O -Wall
4
5 .PHONY: mknod reload testdev
6
7 all: blinker.o
8 reload: blinker.o
9 -rmmod blinker
10 insmod blinker.o
11 mknod:
12 -rm /dev/blinker
13 mknod /dev/blinker c $(shell grep blinker /proc/devices | cut -f1 -d\ ) 0
14 runtest: reload mknod
15 -./test.sh
16
17 test: test.c
18 gcc -O2 $< -o $@
19

C.2 blinker.c
1 #ifndef __KERNEL__
2 # define __KERNEL__
3 #endif
4 #ifndef MODULE
5 # define MODULE
6 #endif
7
8 #include <linux/config.h>
9 #include <linux/module.h>
10
11 #include <linux/sched.h>
12 #include <linux/kernel.h>
13 #include <linux/fs.h>
14 #include <linux/errno.h>
15 #include <linux/delay.h>
16 #include <linux/slab.h>
17 #include <linux/mm.h>
18 #include <linux/ioport.h>
19 #include <linux/interrupt.h>
20

23
21 #include <asm/io.h>
22 #include <linux/poll.h>
23 #include <linux/interrupt.h>
24 #include <linux/slab.h>
25
26 static int major = 0; /* dynamic */
27
28 static unsigned long base = 0x240;
29 MODULE_PARM(base, "l");
30
31 MODULE_AUTHOR("Some Loser");
32
33 #define MY_MODULE_NAME "blinker"
34
35 ssize_t blinker_read(struct file *filp, char *buf,
36 size_t count, loff_t *f_pos);
37 ssize_t blinker_write(struct file *filp, const char *buf,
38 size_t count, loff_t *f_pos);
39 ssize_t blinker_open(struct inode *inode, struct file *filp);
40 ssize_t blinker_release(struct inode *inode, struct file *filp);
41 int blinker_init();
42 void blinker_cleanup();
43
44 struct file_operations blinker_fops = {
45 read: blinker_read,
46 write: blinker_write,
47 open: blinker_open,
48 release: blinker_release
49 };
50
51 ssize_t blinker_read(struct file *filp, char *buf,
52 size_t count, loff_t *f_pos)
53 {
54 char my_buf[1];
55 my_buf[0] = ’0’;
56 if(count > 0) {
57 count = 1;
58 inb(base);
59 copy_to_user(buf, my_buf, count);
60 }
61 return count;
62 }
63
64 ssize_t blinker_write(struct file *filp, const char *buf,
65 size_t count, loff_t *f_pos)
66 {

24
67 char my_buf[1];
68 if(count > 0) {
69 count = 1;
70 copy_from_user(my_buf, buf, count);
71 if(*my_buf == ’1’) {
72 outb(0xff, base);
73 }
74 else if(*my_buf == ’0’) {
75 outb(0x00, base);
76 }
77 }
78 return count;
79 }
80
81 ssize_t blinker_open(struct inode *inode, struct file *filp)
82 {
83 MOD_INC_USE_COUNT;
84 return 0;
85 }
86
87 ssize_t blinker_release(struct inode *inode, struct file *filp)
88 {
89 MOD_DEC_USE_COUNT;
90 return 0;
91 }
92
93 int blinker_init()
94 {
95 int result;
96 result = check_region(base, 1);
97 if (result) {
98 printk(KERN_INFO MY_MODULE_NAME
99 "_init: can’t get I/O port address 0x%lx\n",
100 base);
101 return result;
102 }
103 request_region(base, 1, MY_MODULE_NAME);
104 result = register_chrdev(major, MY_MODULE_NAME, &blinker_fops);
105 if (result < 0) {
106 printk(KERN_INFO MY_MODULE_NAME "_init: can’t get major number\n");
107 release_region(base, 1);
108 return result;
109 }
110 if (major == 0) major = result;
111 printk(KERN_INFO MY_MODULE_NAME "_init: major number is %d\n", major);
112 return 0;

25
113 }
114
115 void blinker_cleanup()
116 {
117 unregister_chrdev(major, MY_MODULE_NAME);
118 release_region(base, 1);
119 }
120
121 module_init(blinker_init);
122 module_exit(blinker_cleanup);
123

C.3 test.sh
1 #!/bin/bash
2 while true; do
3 date
4 echo 1 > /dev/blinker
5 sleep .5
6 echo 0 > /dev/blinker
7 sleep .5
8 done;

26
D Online User Interface
D.1 form.py
1 #!/usr/local/bin/python
2
3 import cgi
4 import cgitb; cgitb.enable()
5 import socket
6 import os
7
8 from time import gmtime, strftime
9
10 #Header
11 def PrintHead():
12 head = "Microcomputer Interfacing - Oscilloscope"
13 desc = "Welcome to the Graphical User Interface for EE352: " + \
14 "micro_intf, version 1.00.00&gamma;"
15 date = strftime("%d %b %Y",gmtime())
16 file = open("./header.txt", ’r’)
17 HEAD = file.read()
18 print HEAD%{’title’:head, ’description’:desc, ’date’:date}
19 file.close()
20
21 #Form
22 def PrintForm(freq, dty):
23 file = open("./form.txt", ’r’)
24 FORM = file.read()
25 if int(dty) == 100:
26 ch000 = ’’
27 ch100 = ’checked="checked"’
28 else:
29 ch000 = ’checked="checked"’
30 ch100 = ’’
31 print FORM%(freq, ch000, ch100)
32 file.close()
33
34 #Data
35 def PrintData(freq, dty):
36 file = open("./data.txt", ’r’)
37 DATA = file.read()
38 print DATA%(freq, dty)
39 file.close()
40
41 #Send Data using Sockets (should work)
42 def SendDataSocket(dty):

27
43 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
44 if dty == ’100’:
45 msg = ’1\n’
46 else:
47 msg = ’0\n’
48 s.connect(("localhost", 5555))
49 s.send(msg)
50
51 #Send Data using Telnet (does not work)
52 def SendDataTelnet(dty):
53 p = os.popen(’telnet localhost 5555 > ./telnet.log’, ’w’)
54 if dty == ’100’:
55 print >>p, ’1’
56 else:
57 print >>p, ’0’
58 p.flush()
59 p.close()
60
61 #Main
62 def main():
63 form = cgi.FieldStorage(keep_blank_values=1)
64 keys = form.keys()
65 if ’freq’ in keys:
66 freq = form[’freq’].value
67 dty = form[’dty’].value
68 else:
69 freq = ’0’
70 dty = ’0’
71
72 SendDataSocket(dty)
73 PrintHead()
74 PrintForm(freq, dty)
75 PrintData(freq, dty)
76
77 if __name__ == "__main__":
78 print "Content-type: text/html" # Print the required header for HTML
79 print # Blank line to signify end of headers
80 main()

D.2 data.txt
1 <!-- column Break -->
2 </td><td class="main" colspan="1">
3
4 <h4>Posted Form Data</h4>
5 <ul>

28
6 <li>Frequency = %s Hz</li>
7 <li>Duty Cycle = %s %%</li>
8 <ul>

D.3 form.txt
1 <form method="get" action="form.py">
2 <h4>LED Cotroller</h4>
3 <h6>PWM Frequency</h6>
4 <input type="text" maxLength="3" size="3" value="%s" name="freq" />
5 <label for="freq">Hz</label>
6 <h6>Duty Cylce</h6>
7 <input id="PWM0" type="radio" value="0" name="dty" %s />
8 <label for="PWM0">0 %%</label><br />
9 <input id="PWM1" type="radio" value="25" name="dty" disabled="disabled" />
10 <label for="PWM1">25 %%</label><br />
11 <input id="PWM2" type="radio" value="50" name="dty" disabled="disabled" />
12 <label for="PWM2">50 %%</label><br />
13 <input id="PWM3" type="radio" value="75" name="dty" disabled="disabled" />
14 <label for="PWM3">75 %%</label><br />
15 <input id="PWM4" type="radio" value="100" name="dty" %s />
16 <label for="PWM4">100 %%</label><br />
17 <input type="submit" value="Submit Changes" />
18 </form>

D.4 header.txt
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
4 <meta http-equiv="Content-Style-Type" content="text/css" />
5 <link type="text/css" rel="stylesheet" href="main.css" />
6 <meta http-equiv="Content-Language" content="en-us" />
7 <title>%(title)s</title>
8 </head>
9 <body>
10 <table class="invisible"><tr>
11 <td class="side" colspan="3">
12 <h1>%(title)s</h1>
13 <p>%(description)s</p>
14 </td><td class="side" rowspan="2"></td></tr>
15 <tr><td class="side"><table class="side">
16 <tr><td class="side0"><h2 class="side">%(date)s</h2></td></tr>
17 <tr><td class="side1"><h1 class="side">CONTENTS</h1>
18 <ul>
19 <li><a class="side" href="README">README</a></li>

29
20 <li><a class="side" href="http://www.nmt.edu/~dbaird/micro_intf/">
21 micro_intf SVN Server</a></li>
22 </ul></td></tr>
23 <tr><td class="side2"><h1 class="side">REFERENCE</h1>
24 <ul>
25 <li><a class="side" href="http://www.python.org/">Python.org</a></li>
26 <li><a class="side" href="http://www.python.org/doc/2.3.4/lib/lib.html">
27 Python 2.3 Doc</a>
28 </li>
29 <li><a class="side" href="http://www.w3schools.com/">W3Schools</a></li>
30 <li><a class="side" href="http://www.algonet.se/~ug/">
31 Ug’s Other Homepage</a>
32 </li>
33 <li><a class="side" href="http://gnosis.cx/publish/tech_index.html">
34 Gnosis Project</a>
35 </li>
36 </ul></td></tr>
37 <tr><td class="side1"><h1 class="side">LINKS</h1>
38 <ul>
39 <li><a class="side" href="http://www.nmt.edu/">NMT Homepage</a></li>
40 <li><a class="side" href="http://www.ee.nmt.edu/">EE Homepage</a></li>
41 <li><a class="side" href="http://www.ee.nmt.edu/~rison/">
42 Dr. Rison’s Homepage</a>
43 </li>
44 <li><a class="side"
45 href="http://www.ee.nmt.edu/~rison/ee352_fall04/homepage.html">
46 EE352 Homepage</a>
47 </li>
48 <li><a class="side" href="http://www.nmt.edu/~dbaird/">
49 David Baird’s Homepage</a>
50 </li>
51 </ul></td></tr></table></td>
52 <td class="main" colspan="1">
53 <!-- End of Header -->

D.5 main.css
1 a:link {
2 margin: 0px;
3 padding: 0px;
4 text-decoration: none;
5 color: #5a5a50;
6 }
7 a:visited {
8 text-decoration: none;
9 color: #5a5a50;

30
10 }
11 a:hover {
12 background-color: #f0f0f0;
13 color: #333333;
14 text-decoration: underline;
15 }
16 a:active {
17 text-decoration: overline;
18 color: #012050;
19 }
20 a:link.side {
21 font-family: arial, sans-serif;
22 font-size: 0.75em;
23 font-weight: bold;
24 text-decoration: none;
25 color: #666666;
26 clear: both;
27 letter-spacing: 0.033em
28 }
29 a:visited.side {
30 font-family: arial, sans-serif;
31 font-size: 0.75em;
32 font-weight: bold;
33 text-decoration: none;
34 color: #666666;
35 clear: both;
36 letter-spacing: 0.033em
37 }
38 a:hover.side {
39 background-color: #d9c060;
40 clear: both;
41 color: #333333;
42 font-family: arial, sans-serif;
43 font-size: 0.75em;
44 font-weight: bolder;
45 text-decoration: none;
46 letter-spacing: 0.037em
47 }
48 a:active.side {
49 background-color: #aaaaaa;
50 color: #333333;
51 font-size: 0.75em;
52 }
53 address {
54 color: #c9b040;
55 font-family: sans-serif;

31
56 font-size: 0.75em;
57 margin: 0px;
58 padding: 5px;
59 text-align: right;
60 }
61 b {
62 font-family: sans-serif;
63 font-size: 0.85em;
64 font-weight: bold;
65 color: #0a0a0a;
66 background-color: #fefeff;
67 }
68 big {
69 font-family: serif;
70 font-size: 1.1em;
71 color: #060045;
72 }
73 body {
74 margin: 0px;
75 padding: 2px;
76 color: #0e0706;
77 background-color: #848484;
78 font-family: sans-serif;
79 }
80 em {
81 background-color: #fff5f5;
82 color: #250505;
83 font-family: sans-serif;
84 font-size: 0.825em;
85 font-style: oblique;
86 text-decoration: underline;
87 }
88 h1 {
89 margin: 0.075em 0.0em 0.075em 0.20em;
90 padding: 0.10em 0.05em;
91 font-weight: bold;
92 font-size: 3.25em;
93 font-style: oblique;
94 text-align: left;
95 color: #001100;
96 }
97 h1.side {
98 background-color: #959595;
99 color: #d9c060;
100 font-size: 0.95em;
101 font-style: normal;

32
102 font-weight: bold;
103 margin: 0px;
104 padding: 0px 0.05em 0px 0.25em;
105 }
106 h2 {
107 margin: 0.2em;
108 padding: 0.3em 0.125em 0px 0.125em;
109 font-size: 2.5em;
110 font-family: sans-serif;
111 text-align: left;
112 color: #d9c060;
113 }
114 h2.side {
115 color: #f9f060;
116 font-family: "Courier New", serif;
117 font-size: 1.5em;
118 font-style: normal;
119 font-weight: boldest;
120 margin: 0px;
121 padding: 0px;
122 text-align: center;
123 }
124 h3 {
125 margin: 0px 0.75em;
126 padding: 0.3em;
127 font-weight: bold;
128 font-size: 1.2em;
129 text-align: left;
130 color: #686664;
131 }
132 h4 {
133 margin: 0.5em;
134 padding: 0.15em 2px;
135 font-family: arial, sans-serif
136 font-weight: bold;
137 font-size: 1.0em;
138 text-align: left;
139 color: #484644;
140 background-color: #f6f6f6;
141 border: thin double #a0a0a0;
142 }
143 h5 {
144 margin: 0.75em;
145 padding: 0.15em 10px;
146 font-family: arial, sans-serif
147 font-weight: bold;

33
148 font-size: 0.8em;
149 text-align: left;
150 color: #484644;
151 background-color: #f8f8f8;
152 border: thin solid #b5b5b5;
153 }
154 h6 {
155 margin: 1.0em;
156 padding: 0.15em 20px;
157 font-family: arial, sans-serif
158 font-weight: bold;
159 font-size: 0.6em;
160 text-align: left;
161 color: #484644;
162 background-color: #fafafa;
163 border: thin solid #eeeeee;
164 }
165 hr {
166 margin: 0px 18% 1.0em;
167 padding: 2px;
168 width: 66%;
169 color: #0d0d0d;
170 background-color: #e6e6e5;
171 }
172 i {
173 color: #101010;
174 background-color: #f9f9f9;
175 }
176 img {
177 border: 0px solid #000000;
178 vertical-align: middle;
179 }
180 input {
181 color: #5a5a50;
182 font-family: serif;
183 font-size: 0.75em;
184 font-weight: normal;
185 }
186 label {
187 color: #5a5a50;
188 font-family: serif;
189 font-size: 1.0em;
190 font-weight: normal;
191 }
192 li {
193 color: #070a15;

34
194 font-family: serif;
195 font-size: 1.0em;
196 font-weight: normal;
197 margin: 0px 2px;
198 padding: 0px;
199 }
200 ol {
201 margin: 0px 10px;
202 padding: 0px 25px 10px 40px;
203 color: #39597c;
204 }
205 p {
206 color: #070a15;
207 font-family: serif;
208 font-size: 1.0em;
209 font-weight: normal;
210 margin: 0px 0.2em 0px 0.5em;
211 padding: 0.2em 0.2em;
212 }
213 table {
214 margin: 5px 5%;
215 padding: 2px;
216 width: 90%;
217 border: 0.2em double #a1a1a1;
218 background-color: #a1a1a1;
219 }
220 table.invisible {
221 background-color: #ffffff;
222 border: 0px solid #000000;
223 margin: 0px;
224 padding: 0px;
225 width: 100%;
226 }
227 table.side {
228 background-color: #eeeeee;
229 border: 2px double #505050;
230 margin: 0px;
231 padding: 0px;
232 width: 95%;
233 }
234 td {
235 margin: 0px;
236 padding: 2px;
237 vertical-align: middle;
238 text-align: center;
239 color: #050509;

35
240 background-color: #f0f0f0;
241 clear: both;
242 }
243 td.main {
244 background-color: #fefefe;
245 border-color: #f9f9f9;
246 border-style: none solid;
247 border-width: medium;
248 color: #001509;
249 margin: 0px;
250 padding: 5px;
251 text-align: left;
252 vertical-align: top;
253 width: 35%;
254 }
255 td.side {
256 background-color: #ffffff;
257 border: 0px none #000000;
258 color: #000000;
259 margin: 0px;
260 padding: 0px;
261 vertical-align: top;
262 text-align: left;
263 width: 10%;
264 }
265 td.side0 {
266 background-color: #ababab;
267 border: 0px none #000000;
268 color: #000000;
269 margin: 0px;
270 padding: 0px;
271 text-align: left;
272 vertical-align: middle;
273 }
274 td.side1 {
275 background-color: #a5a5a5;
276 border: 0px none #000000;
277 margin: 0px;
278 padding: 0px;
279 text-align: left;
280 vertical-align: middle;
281 }
282 td.side2 {
283 background-color: #b0b0b0;
284 border: 0px none #000000;
285 margin: 0px;

36
286 padding: 0px;
287 text-align: left;
288 vertical-align: middle;
289 }
290 tr {
291 height: 4.0em;
292 }
293 ul {
294 font-family: sans-serif;
295 font-size: 1.0em;
296 list-style: none outside;
297 margin: 0px 0px 0px 3px;
298 padding: 1px;
299 }
300 ul.level0 {
301 font-family: sans-serif;
302 font-size: 1.0em;
303 list-style: disc inside;
304 margin: 1px 5px;
305 padding: 2px 0px;
306 }
307 ul.level1 {
308 font-family: sans-serif;
309 font-size: 1.0em;
310 list-style: circle inside;
311 margin: 1px 10px;
312 padding: 2px 5px;
313 }
314 ul.level2 {
315 font-family: sans-serif;
316 font-size: 1.0em;
317 list-style: disc inside;
318 margin: 1px 15px;
319 padding: 2px 10px;
320 }

37

Potrebbero piacerti anche