<<

A Thesis

entitled

Wi-Fi Transmission Employing Microcontroller and Wi-Fi CompactFlash Card

by

Haoyue Li

Submitted to the Graduate Faculty as partial fulfillment of the requirements for the Master of Science Degree in

______Dr. Vijay K. Devabhaktuni, Committee Chair

______Dr. Mansoor Alam, Committee Member

______Dr. Weiqing Sun, Committee Member

______Dr. Patricia Komuniecki, Dean College of Graduate Studies

The University of Toledo

May 2011

Copyright 2011, Haoyue Li

This document is copyrighted material. Under copyright law, no parts of this document may be reproduced without the expressed permission of the author.

An Abstract of

Implement Wi-Fi Data transmission with microcontroller and Wi-Fi CompactFlash card

by

Haoyue Li

Submitted to the Graduate Faculty as partial fulfillment of the requirements for the Master of Science Degree in Electrical Engineering

The University of Toledo May 201

Wi-Fi (short for " fidelity") is a term used to explain certain types of wireless local area networks (WLANs) that use specifications in the 802.11 family. IEEE 802.11

(Wi-Fi) is the most widely used wireless technology. This thesis presents an idea explaining how to build a Wi-Fi data transmission system based on the

PIC18LF6722 microcontroller and a CompactFlash card with Wi-Fi capability

(XTERASYS CWB1K). The proposed system uses a Wi-Fi data transmission system capable of sending data packets through (UDP) to a with Wi-Fi capability. The experimental results indicate that it is possible to build a data transmission module using inexpensive and simple components. This provides a simple and inexpensive design of data transmission for use in areas like real- time measuring and monitoring when combined with a sensing system.

iii

For my parents, and friends.

iv

Acknowledgements

I would like to thank my advisor Dr. Vijay Devabhaktuni and co-advisor Dr. Mansoor

Alam, for giving me the opportunity conduct my master‟s research under their guidance.

It is a great learning experience working with them. I also want to express my deepest gratitude to them for offering intelligent advice at all times, treating me with patience, and constantly given me new direction.

At last, I would also like to extend special thanks to my family, and friends in Toledo for all the memorable times and constant encouragement for their motivation.

v

Table of Contents

Acknowledgements ...... iii

List of Tables ...... ix

List of Figures ...... x

List of Abbreviations ...... xi

1 Introduction ...... 1

1.1 Background ...... 1

1.2 Research Objectives ...... 3

1.3 Overview ...... 4

1.4 Structure of the Thesis ...... 7

2 Hardware Design and Structure ...... 8

2.1 Microcontroller – PIC18LF6722 ...... 8

2.2 Power Supply and RS-232 Interface ...... 11

2.3 802.11b CompactFlash Network Interface Cards...... 14

3 Communicate with 802.11b CompactFlash Card ...... 18

3.1 Connecting a Microcontroller to a CompactFlash Card ...... 20

vi

3.2 Talking in Tuples ...... 26

3.3 First Steps for programming the Phoenix ...... 30

3.4 The Tuple Chain ...... 32

3.5 CIS Reconnaissance ...... 35

3.6 Some 802.11b Language Basics ...... 37

3.7 The 802.11b CompactFlash NIC I/O Drivers ...... 40

4 Setting up a Wi-Fi and making the board accesses the Wi-Fi ...... 47

4.1 Setting up the SSID ...... 49

4.2 Retrieving the MAC Address ...... 51

4.3 Putting an Phoenix on a Wireless LAN ...... 53

5 Sending data to the terminal laptop computer by UDP ...... 56

5.1 Running a UDP Application on the Phoenix ...... 56

5.2 Setting Phoenix Using Tera Term Pro ...... 59

5.3 Sending and Receiving Data by UDP...... 60

6 Conclusions and Future Work ...... 64

6.1 Conclusions ...... 64

6.2 Future Work ...... 65

vii

References ...... 66

A Definition of local variables C code used in the 802.11b CompactFlash NIC initialization procedure ...... 70

B C code for the CompactFlash Card initialization ...... 72

viii

List of Tables

2-1 Specification of XTERASYS CWB1K wireless NIC ...... 16

3-1 CompactFlash Card Register and Memory Area Decoding ...... 23

3-2 Common Memory Functions ...... 24

3-3 CompactFlash+ Card Configuration Registers Decoding ...... 24

3-4 PCMCIA Mode I/O Functions ...... 25

3-5 Layer 1 Tuples ...... 27

3-6 Typical Tuple Layout ...... 29

3-7 PIC configuration register layouts ...... 31

ix

List of Figures

1-1 Overview of the Phoenix ...... 5

1-2 Debugger and Programmer Mplab ICD3 ...... 5

1-3 Block diagram of the Wi-Fi data sending system...... 7

2-1 Hardware Schematic of Phoenix ...... 10

2-2 XTERASYS CWB1K 802.11b CompactFlash NIC...... 14

3-1 Schematic of the CompactFlash Card ...... 21

3-2 CompactFlash Card connector ...... 22

3-3 The flow chart of CompactFlash Card initialization ...... 41

4-1 Setting page...... 48

4-2 Attached devices before Phoenix access ...... 49

4-3 Attached devices after Phoenix access ...... 54

4-4 Ping commend for Phoenix ...... 55

5-1 Tera Term Pro setting window before CompactFlash card is activated ...... 59

5-2 The whole data sending process flow chart ...... 61

5-3 The MCHPDetect application window...... 62

5-4 Tera Term Pro window after CF card is activated ...... 63

5-5 Data packets received on laptop computer ...... 63

x

List of Abbreviations

GAN …………………………...... Global Area Networks WAN……………………………………Wide Area Networks MAN……………………………………metropolitan area networks LAN…………………………………….local area networks PAN…………………………………….personal area networks DSRC…………………………………..dedicated short-range ITS……………………………………...Transport Systems and Services RFID…………………………………… frequency identifications UDP…………………………………….User Datagram Protocol WDT……………………………………Extended Watchdog Timer ICSP…………………………………….In-Circuit Serial Programming BOR…………………………………….Programmable Brown-out Reset SRAM…………………………………..Static random access memory USART…………………………………Universal asynchronous receiver/ SPI ……………………………………...Serial Interface I2C………………………………………Inter IC TQFP……………………………………Thin Quad Flat Pack DCE……………………………………..Data Communications Equipment DTE…………………………………….. NIC……………………………………...Network Interface Card ISM……………………………………...Industrial Scientific Medical CCK……………………………………..Complimentary Code Keying DQPSK………………………………….Differential Quadrature Phase Shift Keying DBPSK………………………………….Differential Binary Phase Shift Keying CSMA/CA………………………………Carrier Sense Multiple Access/Collision Avoidance PCMCIA………………………………..Personal Card International Association CIS………………………………………Card Structure COR……………………………………..Configuration Option Register MAC……………………………………. PHY…………………………………...... Physical

xi

LLC……………………………………... Control ISM……………………………………...Industrial, Scientific, Medical SSID…………………………………….Service Set Identity WEP……………………………………..Wired Equivalent Privacy AP………………………………………..Access Point BSS………………………………………basic service set DHCP……………………………………Dynamic Host Configuration Protocol TFTP…………………………………….Trivial File Protocol TCP………………………………………Transmission Control Protocol SSH………………………………………Secure Shell

xii

Chapter 1

Introduction

1.1 Background

Wireless is wonderful; it is the information transfer over a distance without using enhanced electrical conductors and wires. Wireless data transmission is traditionally a branch of and electrical engineering. There are a lot of different standards and protocols for wireless , such as: , cellular , satellites, and wireless networks. These wireless communication and mobile networks have been widely used nowadays [1].

It is said that new wireless networking technology has been thought of as one of the five contrivances that is changing our daily life. Due to the importance of wireless communication networks in computing and industrial area, many universities provide courses on wireless related subject in undergraduate and graduate program. Wireless communication contributes to the improvement of engineering technology in many areas, for instance, conventional and renewable electrical power, electronics, control system and instrumentation and so on [2]. The development of wireless communication is noticeable in the second-half of the 20th century till today. In recent years, considerable amount of 1

data traffic is carried in mobile communication networks. Development and the widely use of novel wireless communication systems caused changes in our life styles.

Communication made brilliant effort to develop various digital communication technologies, which aim at approaching the performance close to the theoretic limit. In the 1980s, digital wireless communication technology was used in the satellite communication systems for International Telecommunications Satellite

Organization () to achieve increased system capacity in the situation where demands in satellite communication were increasing rapidly. Then it was used to cell phone systems, and led the significant growth of cellular phone market. Today, wireless communication technology is used in a plenty of systems. Besides global area networks

(GANs), metropolitan area networks (MANs), wide area networks (WANs), and local area networks (LANs), it is also used in personal area networks (PANs), including dedicated short-range communications (DSRC) for intelligent Transport Systems and

Services (ITS), identifications (RFIDs), wireless sensor networks, and wireless cards [3].

The most popular wireless network technology, Wi-Fi, which is used everywhere and every day, is a family of standards for wireless networking defined in the IEEE 802.11 specifications. The interoperability of these standards were tested and endorsed by the

Wi-Fi Alliance. In general terms, Wi-Fi provides a network to a device on wireless using

Radio Frequency as an alternative to being connected via a network cable. Wi-Fi technologies are not confused with other wireless technologies such as G3, and packet radio and so on, which use a different set of IEEE specifications [4]. However,

2

comparing with other wireless communication, Wi-Fi has some outstanding advantage as below:

1. Wi-Fi allows the deployment of local area networks (LANs) without wires for client devices, typically reducing the costs of network deployment and expansion [5].

Spaces where cables cannot be run, such as outdoor areas and historical buildings, can host wireless LANs.

2. Wi-Fi products are extensively available in the market, and the price keeps decreasing, which means it is easy to create a or access point by using a with Wi-Fi capability.

3. Wi-Fi has a set of global standards. Not like the cellular carriers, the same Wi-Fi users can work in different countries around the world at all time [6].

1.2 Research Objectives

This thesis gives a method and explains how to make embedded microcontroller- based 802.11b wireless hardware and firmware work in plain terms. We are going to show that how to implement inexpensive and simple embedded 802.11b wireless hardware and firmware through the code examples, pictures and theoretical explanations contained within this research. In this research, we use the 802.11b radio services of the aforementioned wireless 802.11b CompactFlash cards, which are all built around the

PRISM chipset. The entire 802.11b design is dependent on the 802.11b radio. There are multiple 802.11b radio designs to choose from out there and all of them can be easily

3

obtained commercially via local office supply warehouses or through online vendors. In addition to the CompactFlash 802.11b radio cards that can plug into your laptop computer or PDA, there are various vendors that offer stand-alone solutions. Most of them are very nice. The only drawback to a vendor-controlled device is that their system, their way of doing things and their I/O interfaces are locked. A significant advantage to using 11 Mbps CompactFlash Network Adapters is the form factor of the CompactFlash

Network Adapter package. The 802.11b CompactFlash NIC radio cards are small and lightweight. This makes it easier if one want to port the base hardware and firmware model to a unique portable device of one‟s own design.

1.3 Overview

The standards of 802.11b CompactFlash NICs allow the CompactFlash 802.11b radio cards to take a part in standard LAN environments, which means that although the 802.11b CompactFlash NIC is wireless communication, it can still be accessed from standard wired LAN architectures by connecting to a access point or wireless router.

Meanwhile, TCP/IP is still the same TCP/IP as the old one in this wireless connection [7].

That means nothing but only the way we access the network is changed, however, all of the well-known and Ethernet protocols remain the same.

The most important advantage to use 11 Mbps CompactFlash Network Adapters is that they all support the CompactFlash standard [8]. That means we can look up a number of available CompactFlash material to know about how to interface an 11 Mbps

4

CompactFlash Network Adapter. Because most of the 802.11b CompactFlash NIC manufacturers provide some information about their card on their website.

Figure 1-1 Overview of the Phoenix As can be seen in Figure 1-1, the whole system is based on the microcontroller

Microchip PIC18LF6722. It operates with a +3.3 VDC power supply, the microcontroller is clocked to a safe maximum rate at the +3.3 VDC power level. At this power level the microcontroller can be clocked up to a over 25 MHz. It is also equipped with a regulation RS-232 port built around a +3.3 VDC SP3232 RS-232 converter.

Figure 1-2 Debugger and Programmer Mplab ICD3

5

The microcontroller PIC18LF6722 can be debugged and programmed by using any

Microchip-compatible development hardware. The board includes a standard 6-pin RJ-12 programming/debugging interface. The Microchip MPLAB ICD3 and the software called

MPLAB IDE were used as the programming and debugging platform when using the board. There is no need to buy an expensive in-circuit emulator, because the MPLAB

ICD 3 is enough for programming and debugging, meanwhile, it is also easy to setup and use. The MPLAB ICD 3 becomes either a debugger engine or a PIC programmer when it is used with Microchip‟s MPLAB IDE. The MPLAB IDE contains downloadable

MPLAB ICD 3 drivers that immediately fit the MPLAB ICD 3 to service many different types of the PIC microcontrollers.

The C compiler we used in this research is HI-TECH PICC-18, which is full- functioned and free of bugs [9]. Furthermore, because the HITECH PICC-18 C compiler is not based on PIC-targeted macros, it is easy to port the 802.11b driver source code between the Microchip platforms [10]. HI-TECH PICC-18 C compiler is easily portable so that all of the 802.11b driver code in this thesis is consist of HI-TECH PICC-18 C code. The connection between PIC18LF6722 interfaces and the 802.11b CompactFlash

NICs are standard port I/O interfaces. This allows the simplest of structure could be employed and makes the 802.11b driver code much easier.

Here is a block diagram to show the principle of how the whole system works in

Figure 1-3:

6

Figure 1-3 Block diagram of the Wi-Fi data sending system

1.4 Structure of the Thesis

The remainder of the thesis is organized as follows: Chapter 2 explains the hardware design and structure of this system. Chapter 3 introduces the wireless CompactFlash card and discusses how to control it using the microcontroller. Chapter 4 shows setting up a

Wi-Fi wireless network and making the board accesses the Wi-Fi. Chapter 5 talks about sending data to the terminal laptop computer by UDP, and finally conclusion and some future work are presented in Chapter6.

7

Chapter 2

Hardware Design and Structure

As mentioned before, the wireless data sending modules Phoenix started out as a universal microcontroller platform with 802.11b capability that could be deployed using the 802.11b designer‟s microcontroller of choice. PIC18LF6722 is chosen in this system, which is a very popular Microchip PIC microcontroller.

2.1 Microcontroller – PIC18LF6722

PIC18LF6722, which produced by Microchip is a high-performance 64-Pin, 1-Mbit,

Enhanced Flash Microcontrollers with 10-Bit A/D and nanoWatt Technology microcontroller [11], it is very suitable for embedded system because of its special microcontroller features as below:

 C Compiler Optimized Architecture

 100,000 Erase/Write Cycle Enhanced Flash Program Memory Typical

 1,000,000 Erase/Write Cycle Data EEPROM Memory Typical

 Flash/Data EEPROM Retention: 100 Years Typical

8

 Self-Programmable under Software Control

 Priority Levels for Interrupts

 8 x 8 Single-Cycle Hardware Multiplier

 Extended Watchdog Timer (WDT): - Programmable period from 4 ms to 131s

 Single-Supply 5V In-Circuit Serial Programming™ (ICSP™) via Two Pins

 In-Circuit Debug (ICD) via Two Pins

 Wide Operating Voltage Range: 2.0V to 5.5V

 Programmable Brown-out Reset (BOR) with Software Enable Option

The PIC18LF6722 is a powerful chip which is based on a Microchip Technology‟s family of high-pin-count PIC microcontrollers. With a total of seven pinned-out I/O ports, the PIC18LF6722 has more than enough available I/O pins to fabricate a microcontroller- based 802.11b solution. The standard on-chip memory subsystem of PIC18LF6722 includes 3.9K of SRAM and 128K of high-endurance program Flash. The high- endurance program flash allows reprogramming the PIC18LF6722 up to 100,000 times.

To be precise, the PIC18LF6722 is a microcontroller incorporating 54 I/O lines, a 12-bit analog-to-digital converter, two enhanced Universal Synchronous/Asynchronous

Receiver/ (USART), 5 timers, a Serial Peripheral Interface (SPI) module and an Inter IC bus (I²C) module all native to the PIC18LF6722 silicon. The PIC18LF6722‟s resource arsenal is housed in a compact 64-pin Thin Quad Flat Pack (TQFP) package, which adds up to enough microcontroller resources to support a CompactFlash wireless

9

NIC (Network Interface Card). The remaining I/O pins are used for things such as analog-to-digital conversion and digital control which is helpful for any future developments. That means it can do the normal things which can be done by a microcontroller such as generate waveforms, read switch states, monitor voltages, drive displays, control relays, scan keyboards, digitally communicate with other devices and so on, as well as communicate with other wired or wireless devices by Ethernet LAN.

Figure 2-1 below shows the schematic of its hardware.

Figure 2-1 Hardware Schematic of Phoenix

10

2.2 Power Supply and RS-232 Interface

As shown in Figure 2-1, the power supply of Phoenix is an industry standard power supply circuit which is from the PJ-202A, which supplies the +3.3 VDC power which gives power to the 802.11b CompactFlash NIC, along with the PIC18LF6722 microcontroller and the ST3232 RS-232 converter IC. The +3.3 VDC entails the Phoenix electronics and the 802.11b CompactFlash NIC. A 10µF tantalum capacitor is used to filter the Phoenix‟s +3.3 VDC power supply. LED1 gives a visual to show if the

Phoenix‟s regulated power supply is in a good condition. The 0.1 µF power supply bypass capacitors (C9-C15) are used for supporting the PICLF6722 and the

CompactFlash connector. A standard RS-232 is realized on the Phoenix with the inclusion of a 3.3-volt ST3232 RS-232 converter IC. Capacitors C2-C6 are used in the Phoenix serial port since they enable the ST3232‟s on-chip charge pump.

According to charge pump technology, RS-232 voltage levels which are well beyond the RS-232 high-noise voltage band can be generated by the ST3232 [12]. All active digital component power supply rails is demanded to be suitable bypassed to reduce noise.

Capacitor C6 gives the power supply bypass function for the ST3232. The ST3232 is able to drive two pairs of RS-232 transmit and receive lines [13].

There are many advantages for the module to have a RS-232 serial port. If one need to wirelessly send or receive data between devices that can only communicate with RS-232 and an Ethernet LAN, it is necessary to build a serial port. The serial port is also very useful while the 802.11b firmware is being developed. Combining with some personal computer terminal emulators, the serial port can make writing and debugging code much 11

easier and clearer. In this research, the serial port can be used to send status messages to the personal computer or get 802.11b signal strength information from the 802.11b

CompactFlash NIC.

The PIC18LF6722 is able to operate with a Vdd of +5.5 VDC with a maximum clock frequency of 40 MHz. Whereas the power supply of Phoenix is +3.3 VDC, according to the equation from the datasheet of PIC18LF6722, the PIC18LF6722‟s maximum clock frequency can be reduced to a bit over 25 MHz. Although running the PIC18LF6722 at its maximum clock speed results in higher operating speeds, we resorted to a lower speed because at higher speeds, the system requires a logic level shifting hardware in its design thus adding complexity and cost. Here is an equation shows the relationship between

PIC18LF6722 maximum clock frequency and maximum applied Vdd:

Fmax = (16.36 MHz/V) (Vddappmin – 2.0 V) + 4 MHz (data sheet)

Where:

Fmax = Maximum operating clock frequency

Vddappmin = Minimum Vdd power supply voltage

Fmax = (16.36 MHz/V) (3.3 V – 2.0 V) + 4 MHz = 25.268 MHz [16]

The Phoenix can be easily programmed and debugged by using with the MPLAB

ICD3 and the software Microchip‟s MPLAB IDE [17]. Indeed, most of Microchip- compatible programming/debugging system can be used to program the Phoenix.

An important part of the Phoenix is the 50-pin CompactFlash connector which connects the 802.11b wireless NIC to the microcontroller PIC18LF6722. As known, the 12

PIC18LF6722 is an 8-bit microcontroller, so some pins of the CompactFlash connector cannot be unused and not connected. In order to save the I/O pins of PIC18LF6722, only the CompactFlash connector I/O lines which are necessary for 802.11b operation are connected. For example, the CD1 and CD2 pins are used to judge if a card is connected correctly. Those pins are disconnected because that writing code to sense these pins is a waste in particular application of the CompactFlash card. However, to keep the circuitry and driver code as simple as possible a simple I/O interface is adopted. One of the

Phoenix design points was to leave as many of the PIC18LF6722‟s subsystems open for use and to leave as many open microcontroller I/O lines as possible without resorting to additional special purpose components. In addition, using the I/O interface allowed the use of simple I/O code routines to move data back and forth between the CompactFlash card and the microcontroller.

All of the firmware to drive the 802.11b application and the CompactFlash NIC is contained within the PIC18LF6722‟s program flash. The CompactFlash NIC is responsible for taking data from the microcontroller and it wirelessly to another wireless device or access point. The wireless LAN card of choice for the Phoenix series of 802.11b development systems was manufactured by Xterasys and is shown along with the Phoenix CompactFlash NICs in Chapter 1 (Figure 1-1). The Xterasys

CWB1K is an 11 Mbps wireless CompactFlash network adapter card that can transmit and receive up to 60 meters indoors and up to 250 meters outdoors [18]. However, the most important reason for choosing the Xterasys card is that it has an activity LED that can let people know if the data is being sent or received by the Xterasys CompactFlash

NIC. Also, the Xterasys CWB1K is certified for use anywhere in the world. 13

2.3 802.11b CompactFlash Network Interface Cards

Figure 2-2 XTERASYS CWB1K 802.11b CompactFlash NIC The XTERASYS CWB1K is a CompactFlash Type 1 card which is 1.7 mm thinner than the CompactFlash Type II card. The XTERASYS CWB1K wireless NIC operates in the 2.4 MHz ISM (Industrial Scientific Medical) band. The XTERASYS CWB1K NIC complicated schemes (CCK (Complimentary Code Keying), DQPSK

(Differential Quadrature Phase Shift Keying) and DBPSK (Differential Binary Phase

Shift Keying)) help avoid much of the interference from other devices using the frequencies the XTERASYS CWB1K NIC wants to use [19]. Those modulation techniques increased data rate of 802.11b over the original 802.11 specification. DBPSK delivers 1 Mbps data rates, DQPSK is used for 2 Mbps data rates and CCK can provide

5.5 Mbps and 11 Mbps data rates. Here is some Specification of the XTERASYS

CWB1K CompactFlash NIC below:

• Complies with IEEE 802.11b standard for 2.4GHz Wireless LAN

• Complies with Compact Flash Type-I Standard

14

• Lower power consumption and power save mode

• Plug-and-Play Operation provides easy setup

• Works with all existing network infrastructure

• Compatible with specific wireless products and services

• Capable of up to 128-Bit WEP Encrypt

• Freedom to roam while staying connected

• 11 Mbps High-Speed Transfer Rate

• Rich diagnostic LED indicators with Integrated

• Easy to install and configure

• Modulation Technique Direct Sequence (CCK, DQPSK, DBPSK)

• Spreading 11 chip Barker sequence

Better than 10-5

Access Protocol CSMA/CA (Collision Avoidance) with ACK MODEL:

CWB1K

The 802.11b Wireless CompactFlash Card is the perfect solution for the wireless network applications and based on the IEEE 802.11b standard offering a data rate of

11Mbps in a wireless LAN environment. It is a high-speed wireless network card that 15

connects directly to a PDA, laptop computer or some other devices. One can just plug it in and you are ready to share data, printers, or high speed over your existing wireless network. User-friendly software makes it simple to set up.

Table 2-1 Specification of XTERASYS CWB1K wireless NIC

Antenna (included) Internal Chip Antenna

Data Rate 1/2/5.5/11 Mbps

Dimension 68.77 (L) x 42.8(W) x 6.4 (H) mm

EMC Certifications EN300328 and EN300826 (EN301489-17) in Europe FCC Part 15 in US

Frequency 2.412GHz-2.4835GHz

Humidity Storage: 95% maximum (non-condensing) Operating: 95% maximum (non-condensing)

Interface CompactFlash Type-I

LED LINK: Orange ACT: Green

Other Bit Error Rate: Better than 10 -5 Modulation Technique : Direct Sequence Spread Spectrum

Power Requirement TX consumption : 300mA (Max) RX consumption: 200mA (Max) Sleep Mode: 50mA Operating Voltage: 5V or 3.3V

Security 0/64/128 bit WEP

Standards Standard IEEE 802.11b, Wi-Fi compliant

Supported OS For Notebook: Windows 95 OSR2/98/ME/2000/XP/NT For Handheld/Pocket PC: Windows CE

Weight 15 g

16

Wireless Channel Japan: 14 channels Europe: 13 channels USA, Canada: 11 channels

17

Chapter 3

Communicate with 802.11b CompactFlash Card

A CompactFlash card can be used as a PCMCIA card because their specifications are almost same. Actually, the official CompactFlash specification implies that

CompactFlash cards provide complete PCMCIA functionality and compatibility including PCMCIA True IDE capability. The CompactFlash datasheet shows that

CompactFlash cards can operate with either a +5VDC or +3.3 VDC power supply. As mentioned before, the Phoenix modules use the +3.3 VDC power supply [20].

There are three operating modes in the Compact Flash 3.0 Specification: the Memory mode, the I/O mode and the TRUE IDE mode. PRISM technology and the industry standard published by SanDisc implements Memory mode to initialize the card and access register data; however, I/O mode must be used to accomplish 802.11 communications. The TRUE IDE Mode is used to access data stored in cards that are a combination of both Network Interface Cards (NIC) and Memory Flash Cards. Memory mode is the default when the NIC is settled up, and the first thing that Phoenix driver does is to ensure functionality with the card and then enter to I/O mode. This last step is achieved by setting logically high the lowest significantly bit in the Configuration Option 18

Register (COR). Something important to note is that although the NIC is in I/O Mode the specification allows reading and writing registers in this mode; this is feature is devised by the Phoenix hardware connections and the firmware functions that fulfill the reading and writing of registers.

Besides registers, in the I/O mode there are other types of access structures: Buffer

Access Paths (BAP), Identifiers (FID), and RIDs. When the network interface receives data (from the medium or the driving microprocessor) it must be stored before it can be used, because all of the network events occur asynchronously. The BAPs are used to interact with the internal memory management subsystems of the PRISM chipset.

Without the BAPs the network module would have to know exactly where to retrieve data. Inside the NIC there are two BAPs, and to achieve a faster response the Phoenix driver uses the first available BAP to enable the data transfer. However the continuous dynamic allocation of 128 byte memory buffer chains within the NIC would make data almost impossible to trace if it was not for the FIDs. This access structure provides a unique reference to an associated dynamically allocated buffer chain. To enable data transfers between the microcontroller and the NIC, one must provide the FID to the

SELECTN register, where N represents the number of the BAP, and the corresponding offset within the BAP to the OFFSETN register; data would be available through the

DATAN register after this setup configuration, for both reading and writing. It should be noted that reading and writing uses the lowest driving functions as already specified.

Another thing the BAP would do for the driver is to automatically increment the buffer pointer as data is transferred between the microcontroller and the NIC. The BAPs provide an automated indirect access to the PRISM chipset memory system. RIDs work in a 19

similar way that FID, but they are used to configure the operation of the NIC; in fact, many of the operations that the Phoenix driver uses to initialize the card use RIDs to achieve its goals.

Another important data structure is the Card Information Structure (CIS), which describes the basic functionality of the card and critic data such as voltage nomination and the address of the COR register. Ideally, the correct MAC address would be included within this structure but it has been proven that many cards do not specify it through this system; this is the reason the Phoenix driver obtains its own MAC address using a RID.

The CIS is formed by a linked list of entities that are formed themselves by an identification tuple, a link tuple, the data tuples, and followed by the ending tuple. The identification tuple describes what type of data is contained by the entity, while the number of bytes until the next structure is given by the link tuple. In this chapter, we will talk about how to deal with the BAP, FID, RID and CIS through some code example.

3.1 Connecting a Microcontroller to a CompactFlash Card

Figure 3-1 shows the connection view of the CompactFlash card connector used in the Phoenix. The CompactFlash card is originally a 16-bit device because of the

CompactFlash card data I/O pins D0-D15. However, it is allowed to use the

CompactFlash card with 8-bit devices, like the PIC18LF6722 microcontrollers, and can read and write 16-bit data to and from the CompactFlash card from the lower eight I/O lines of the CompactFlash card data D0-D7 [21].

20

Figure 3-1 Schematic of the CompactFlash Card connector In the CompactFlash card connector schematic (Figure 3-1), as we can see, the

CompactFlash data I/O pins D08-D15 are left disconnected to the microcontroller whereas all of the CompactFlash address input pins (A0-10) are used. This is typical 8-bit

CompactFlash card connector solution, which is allowed to access and makes all of the

CompactFlash card internals in 8-bit mode.

CompactFlash card pin 1 is followed by pin 26; pin 2 is followed by pin 27 and so on.

The first and the last CompactFlash card pins are GND (ground). Except the active low

*CE1 and *OE pins (the * means active low), the function of the odd numbered

CompactFlash card I/O pins are obvious. It makes sure that we can access any address space or memory area inside the CompactFlash card by assignning each CompactFlash card connector address input pin to a microcontroller I/O pin. Figure 3-2 is a picture of the Phoenix modules‟ CompactFlash card connector, which is used to connect the microcontroller and the CompactFlash Card.

21

Figure 3-2 CompactFlash Card connector

Input pin *CE1 and input pin *CE2 are both active low CompactFlash card input . These CompactFlash card input signals are used both to select the CompactFlash card and to tell the CompactFlash card whether it is performing an 8-bit or a 16-bit access operation. CompactFlash card connector pin A0 affects when the Phoenix operates on the

CompactFlash card‟s internals in 8-bit mode. The input pin *REG (CompactFlash card pin 37) also plays key role in the 8-bit mode CompactFlash card memory area access scheme. With the Phoenix design, we takes the complexity out of the *CE1-*CE2-A0-

*REG pin function by giving up the CompactFlash card‟s 16-bit function by the hardware.

As can be seen in Figure 3-1, the *CE1 CompactFlash card input pin 7 is connected to ground while the CompactFlash card input pin *CE2 (pin 32) is tied to +3.3VDC power supply. This solution of the CompactFlash card‟s *CE1 and *CE2 input pins‟ logic levels make the CompactFlash card‟s data I/O lines D8-D15 disable. The CompactFlash card standby mode is also eliminated as *CE1, which is always tied to ground, is not able to be driven to a logical high level. It puts the 802.11b CompactFlash NIC into permanent

8-bit mode by tying *CE1 and *CE2 and we can perform all of the 8-bit 802.11b

22

operations necessary to run a Phoenix without worrying about the logical states of *CE1 and *CE2.

Table 3-1 shows the logic levels on the CompactFlash card‟s A0, *CE1, *CE2, *REG inputs and read/write control input pins which are required to read the CompactFlash card‟s Card Information Structure (CIS) memory area and read and write the

CompactFlash card‟s configuration registers if it is necessary. The CompactFlash card‟s

*REG input pin (pin 44) should be driven low for accessin CompactFlash card Attribute

Memory and CompactFlash card I/O cycles when an active I/O address is on the

CompactFlash card‟s address lines. The *REG input pin should be given high for accessing Common Memory. The Phoenix driver code makes the CompactFlash card‟s

*REG input pin logically low for all 802.11b CompactFlash NIC operations. So, there are no Common Memory accesses against the 802.11b CompactFlash NIC. Tying the

CompactFlash card‟s *REG input pin to a microcontroller I/O pin makes it more flexible of interfacing the Phoenix module‟s support electronics to a CompactFlash card.

Table 3-1 CompactFlash Card Register and Memory Area Decoding [22]

CompactFlash Card Register and Memory Area Decoding

*CE1 *CE2 *REG *OE *WE A10-A1 A0 Selected Memory Area

0 1 0 0 1 X 0 Configuration Registers Read

0 1 0 1 0 X 0 Configuration Registers Write

0 1 0 0 1 X 0 Card Information Structure Read

Active Low signals are preceded by a „*‟ x‟ means: “don‟t care”

23

To stabilize the facts of *OE and *WE usage, here is Table 3-2, which shows the *OE and *WE input requirements to access a CompactFlash Card‟s Common Memory area.

Table 3-2 Common Memory Functions [22]

Common Memory Functions

Function Code *CE1 *CE2 *REG *OE *WE A0 D15-D8 D7-D0

Byte Read (8-) 0 1 1 0 1 0 High Z Even Byte

Byte Read (8-bits) 0 1 1 0 1 1 High Z Odd Byte

Byte Write (8-bits) 0 1 1 1 0 0 X Even Byte

Byte Write (8-bits) 0 1 1 1 0 1 X Odd Byte

Active Low signals are preceded by a „*‟ x‟ means: “don‟t care”

It is really important to be able to read a CompactFlash card‟s Card Information

Structure memory information. And another very important CompactFlash card register in Phoenix driver code is called Configuration Option Register. Table 3-3 shows the logic levels requirements to operate on the CompactFlash card‟s COR.

Table 3-3 CompactFlash+ Card Configuration Registers Decoding [22]

CompactFlash Card Configuration Registers Decoding

*CE1 *CE2 *REG *OE *WE A4 A3 A2 A1 A0 Selected Register

0 X 0 0 1 0 0 0 0 0 Configuration Option Reg Read 0 X 0 1 0 0 0 0 0 0 Configuration Option Reg Write

24

Active Low signals are preceded by a „*‟

Address lines A5-A10 are “don‟t care” x‟ = don‟t care

As can be seen in Table 3-1, the CompactFlash card‟s *OE (Output Enable) input pin

(pin 9) is used to read the CompactFlash card‟s Card Information Structure memory area.

The CompactFlash card connector *WE input pin (pin 36) is given logically low when writing to the CompactFlash card‟s configuration registers. *OE and *WE are also used to read and write data to and from a CompactFlash Card in memory mode. The *OE and

*WE pins are used to read the CompactFlash Card Information Structure memory area and write to the CompactFlash card configuration registers when the CompactFlash card is drive to I/O mode. An example of using the *OE and *WE signals for the operation of registers, espically the CompactFlash card‟s Configuration Option Register, is represented in Table 3-3.

Once the CompactFlash card is put into I/O mode, it works like a PCMCIA card which is plugged into the CompactFlash card connector, which can be seen in Table 3-4

Table 3-4 PCMCIA Mode I/O Functions [22]

PCMCIA Mode I/O Functions

Function Code *CE1 *CE2 *REG *IORD *IOWR A0 D15-D8 D7-D0

Input (8- bits) 0 1 0 0 1 0 High Z Even

Input (8- bits) 0 1 0 0 1 1 High Z Odd

25

Output (8- bits) 0 1 0 1 0 0 X Even

Output (8- bits) 0 1 0 1 0 1 X Odd

Active Low signals are preceded by a „*‟

x‟ = don‟t care

*IORD and *IOWR are used to enable 16-bits data to be clocked into or out of a

CompactFlash card using even and odd 8-bit bytes. The CompactFlash card‟s A0 address line decides which byte is even (when A0=0) and which byte is odd (when A0=1). The

CompactFlash card‟s *IORD and *IOWR control signals can be seen when we start communicate with the Phoenix‟s 802.11b CompactFlash NIC.

The CIS tells all information about a CompactFlash card. It describes the basic functionality of the card and critic data such as voltage nomination and the address of the

COR register. Actually, we can ignore most of the CIS information we get from the

802.11b CompactFlash NIC as the operation of the Phoenix 802.11b drivers only require the 802.11b CompactFlash NIC‟s CIS address from the COR.

3.2 Talking in Tuples

Tuples exist at the beginning of a CompactFlash card‟s Attribute Memory area and can be seen after the CompactFlash card a reset operation executed. The only thing that

802.11b CompactFlash NIC knows is the internal program which is written by the manufacturer. We need to make the 802.11b CompactFlash NIC to show us what is in its read-only Attribute Memory area. The way we learn about the contents of any 26

CompactFlash card is by retrieving and examining the CompactFlash card‟s tuples, which can be found in the CompactFlash card‟s CIS memory area.

A tuple is a “set of x amount of elements”. In this case, a tuple is a group of bytes which describes a physical or electrical element of the CompactFlash card in which the tuple belongs to. A Phoenix 802.11b CompactFlash NIC tuple includes a tuple code byte, a tuple link byte and the tuple data bytes. The tuple code byte shows what kind of tuple we are using. The tuple link byte implies how many bytes are in the tuple structure. It also tells us where the next tuple structure begins in the CompactFlash card address space.

As we have already known, the tuple data bytes contain some of the information about the 802.11b CompactFlash NIC need to use in our Phoenix driver code. Each individual tuple structure ends with a hexadecimal 0xFF, which is a part of that particular tuple‟s byte count. However, some tuples use the linked list concept without the 0xFF tuple ending byte sequence. Layer 1 tuples are shown in Table 3-5.

Table 3-5 Layer 1 Tuples [23]

Layer 1 Tuples

Tuple Code Tuple Name Tuple Description

0x00 NULL

0x01 DEVICE Device Information for Common Memory

0x02-0x05 RESERVED

0x06 LONGLINK_MFC Long-link for Multi-Function Card

0x07-0x0F RESERVED

27

0x10 CHECKSUM Checksum Control

0x11 LONGLINK_A Long-Link Control to Attribute Memory

0x12 LONGLINK_C Long-Link Control to Common Memory

0x13 LINKTARGET Link Target

0x14 NO_LINK End of Current Chain

0x15 VERS_1 Identifies PCMCIA Compliance Level of CIS

0x16 ALTSTR Alternate Language String

0x17 DEVICE_A Device Information to Attribute Memory

0x18 JEDEC_C JEDEC Programming Algorithm for Tuple 0x01

0x19 JEDEC_A JEDEC Programming Algorithm for Tuple 0x17

0x1A CONFIG Configuration Tuple

0x1B CFTABLE_ENTRY Configuration Table Entry

0x1C DEVICE_OC Other Conditions Device Information (Common

Memory)

0x1D DEVICE_OA Other Conditions Device Information (Attribute

Memory)

0x1E DEVICEGEO Device Geometry (Common Memory)

0x1F DEVICEGEO_A Device Geometry (Attribute Memory)

0x20 MANFID PCMCIA Manufacturers Identification

0x21 FUNCID Function Identification

0x22 FUNCE Function Extension

0xFF END Termination Tuple

28

Tuple data is arranged on even byte boundaries. Such alignment makes things done with tuples easily for 8-bit setups like the Phoenix. This means that the first tuple, a code tuple, exist at CIS address 0 (zero). The first link tuple is located at CIS address 0x02 while the first of any data bytes are at CIS address 0x04. The even-byte tuple arrangement for the CWB1K initial tuple entry is shown in Table 3-6.

Table 3-6 Typical Tuple Layout [24]

Typical Tuple Layout

Type Addr Data Description

END 0x08 0xFF End of Tuple

0x07 X

DATA 0x06 0x00

0x05 X

DATA 0x04 0x00

0x03 X

LINK 0x02 0x03 3 Byte Follow

0x01 X

CODE 0x00 0x01 Device Tuple

Now that we know how to read the tuple chain, we put some code behind our new- found tuple knowledge and check the XTERASYS CWB1K‟s CIS memory area.

29

3.3 First Steps for programming the Phoenix

This is the beginning with tuple by taking care of something necessary that relates to the microcontroller‟s USART and I/O pins. The code snippet below is from the main function of the Phoenix 802.11b driver. At this point, we‟re concerned with the calls init_USART1 and init_cf_card.

void main(void) { unsigned int i,temp,evstat_data; char rc; init_USART1(); init_cf_card();

So, we get started and assume that the init_USART1 function is called and begin at the top of the Phoenix‟s init_USART1 function code.

#define BAUD1 57600 //desired baud rate #define FOSC 20000000 //oscillator frequency #define DIVIDER1 ((unsigned int)(FOSC/(16 * BAUD1) -1)) //********************************************************** //* Init USART Function //********************************************************** void init_USART1(void) { SPBRG1 = DIVIDER1; // baud rate divisor TRISC7 = 1; //receive pin TRISC6 = 0; //transmit pin TXSTA1 = 0x04; //high speed baud rate RCSTA1 = 0x80; //enable serial port and serial port pins USART_RxTail = 0x00; //flush receive buffer USART_RxHead = 0x00; USART_TxTail = 0x00; //flush transmit buffer USART_TxHead = 0x00; RC1IP = 1; //receive interrupt = high priority TX1IP = 1; //transmit interrupt = high priority RC1IE = 1; //enable receive interrupt PEIE = 1; //enable all unmasked peripheral interrupts GIE = 1; //enable all unmasked interrupts CREN1 = 1; //enable USART1 receiver TX1IE = 0; //disable USART1 transmit interrupt TXEN1 = 1; //transmitter enabled }

30

The USART1 baud rate divisor is set in the code shown above. It also clears the receive buffer area and the transmit buffer area, prioritizes the transmit interrupt and the receive interrupt and enables the USART1 transmitter and receiver circuit.

There are many PIC USART configuration bits and the PIC USART interrupt handling settings. So, in order to make this clear, Table 3-7 shows the various PIC configuration register layouts that all of the bits in code above.

Table 3-7 PIC configuration register layouts

TXSTA1: TRANSMIT STATUS AND CONTROL REGISTER 1

CSRC TX9 TXEN SYNC SENDB BRGH TMRT TX9D

0 0 1 0 0 1 0 0

RCSTA1: RECEIVE STATUS AND CONTROL REGISTER 1

SPEN RX9 SREN CREN ADDEN FERR OERR RX9D

1 0 0 1 0 0 0 0

IPR1: PERIPHERAL INTERRUPT PRIORITY REGISTER 1

PSPIP ADIP RC1IP TX1IP SSPIP CCP1IP TMR2IP TMR1IP

1 1 1 1 1 1 1 1

PIE1: PERIPHERAL INTERRUPT ENABLE REGISTER 1

PSPIE ADIE RC1IE TX1IE SSPIE CCP1IE TMR2IE TMR1IE

0 0 1 0 0 0 0 0

INTCON REGISTER

GIE/GIEH PEIE/GIEL TMR0IE INT0IE RBIE TMR0IF INT0IF RBIF

1 1 0 0 0 0 0 0

31

The USART interrupt is intended for use with operations, which makes the use of the byte-oriented sendchar and recvchar functions in the Phoenix driver code necessary. USART interrupt-driven character functions is optional and we can use the standard printf function to send character and formatted string data to the Phoenix‟s RS-

232 port.

Once the USART is set up, the next call goes out to the 802.11b CompactFlash NIC.

So, here is a closer look at the bytes contained within the XTERASYS CWB1K 802.11b

CompactFlash NIC‟s Card information Structure.

3.4 The Tuple Chain

The C Code shown in Appendix A defined the local variables which is used in the

802.11b CompactFlash NIC initialization process. It also resets the 802.11b

CompactFlash NIC and initializes the input/output states of the microcontroller‟s I/O ports.

The intention of the C code Appendix A is toggling the 802.11b CompactFlash NIC‟s

RESET pin and giving the reset process enough time to complete by setting up the PIC microcontroller‟s I/O lines during the 802.11b CompactFlash NIC‟s reset time. The cisflag bit and rc variable are used to show the availability of the CIS data. So, we need to ensure that the cisflag and rc variable are set to a known state before we go on with the rest of the code in the init_cf_card function.

32

Following the 802.11b CompactFlash NIC reset, the first code that works on the

PRISM chipset complement inside the 802.11b CompactFlash NIC is a read operation aimed at retrieving the data contained within the first byte of the CIS memory area. In

Code Snippet below, 802.11b CompactFlash NIC is given one second to give the first

CIS tuple entry. Once we see the first CIS tuple code, it means that the rest of the

802.11b CompactFlash NIC‟s CIS tuples are also available. Referencing Table 3-1 and

Table 3-2, the very first CIS byte should be 0x01, which finds the Device tuple. In the

Code Snippet below, we continue to read the CIS memory area at address 0x0000 for one second.

//********************************************************** //* Macros //********************************************************** #define make8(var,offset) ((unsigned int)var >> (offset * 8)) & 0x00FF //********************************************************** //* Flags //********************************************************** #define cisflag 0x04 #define bcisflag flags & cisflag #define setf_cis flags |= cisflag #define clrf_cis flags &= ~cisflag //********************************************************** //* PORT Definitions //********************************************************** #define data_in PORTD #define PCTL LATF #define addr_hi LATG #define addr_lo LATH //********************************************************** //* CF I/O Definitions //********************************************************** #define OE 0x01 #define set_OE PCTL |= OE #define clr_OE PCTL &= ~OE //****************************************************************** //* CIS //****************************************************************** #define rd_code_tuple rd_cf_reg ***************************** void wr_cf_addr(unsigned int addr) { addr_hi = (make8(addr,1)); addr_lo = addr & 0x00FF; } char rd_cf_reg(unsigned int reg_addr) { char data,i; 33

wr_cf_addr(reg_addr); clr_OE; i=1; while(--i); //read access delay data = data_in; set_OE; return(data); } ***************************** x = 500; //wait for cis functionality to come up do{ delay_ms(2); if(--x == 0) { rc = 1; break; } code_tuple = rd_code_tuple(0x0000); if(code_tuple == 1) //1 denotes the Device Tuple setf_cis; }while(!(bcisflag)); if(rc) { printf(“\r\nCIS Entry Failed..”); printf(“\r\nDriver Halted..”); while(1); } *****************************

The wr_cf_addr function is called by the rd_code_tuple function, which places the

CIS memory area address that is expected read on the 802.11b CompactFlash NIC‟s address lines. However, the 802.11b CompactFlash NIC is not in I/O mode yet at this time and we are trying to read Attribute Memory. So, we need to use the *OE and *WE

CompactFlash card read/write control lines to get access to the CIS memory area. After setting up the CompactFlash card address lines and enabling the CompactFlash cards

*OE pin, we make a short read access delay before reading in the CIS data. Once we have the data, the OE pin is given high to end the read process.

If a CIS get results in the variable code_tuple is equal to 0x01, the cisflag bit is set and the reading/timing loop is exited with a result of 0x00. If one second passes and the code_tuple variable is not 0x01, the Phoenix driver suppose that there is not a valid CIS

34

information, and after telling the user via the Phoenix‟s serial port of the bad situation, the Phoenix driver code enters a never-ending do-nothing loop. Because if there is something wrong with CIS or the 802.11b CompactFlash NIC is not even plugged into the CompactFlash card connector, there‟s no reason to continue anyway. In fact, we retrieve 0x01 into the code_tuple variable, we‟re ready to start parsing the CIS tuples.

3.5 CIS Reconnaissance

The purpose here is to get a dump of all of the XTERASYS CWB1K‟s tuples and attempt to navigate through the dump using the tuple codes shown in Table 3-1. Here is some code in the Code Snippet below to do that. Once we find the actual tuples that exist within the XTERASYS CWB1K‟s CIS memory area we can write more specific CIS describing code that adapts the tuple codes we discovered.

#define END_TUPLE 0xFF //********************************************************** //* CIS //********************************************************** #define rd_code_tuple rd_cf_reg #define rd_link_tuple rd_cf_reg //********************************************************** //* PORT Definitions //********************************************************** #define data_in PORTD #define PCTL LATF #define addr_hi LATG #define addr_lo LATH //********************************************************** //* CF I/O Definitions //********************************************************** #define OE 0x01 #define set_OE PCTL |= OE #define clr_OE PCTL &= ~OE //****************************************************************** //* CIS //****************************************************************** #define rd_code_tuple rd_cf_reg ***************************** void wr_cf_addr(unsigned int addr) 35

{ addr_hi = (make8(addr,1)); addr_lo = addr & 0x00FF; } char rd_cf_reg(unsigned int reg_addr) { char data,i; wr_cf_addr(reg_addr); clr_OE; i=1; while(--i); //read access delay data = data_in; set_OE; return(data); } ***************************** //********************************************************** //* CIS Tuple Collection Utility //********************************************************** unsigned int index; unsigned int cis_addr; // attribute memory index (EVEN ADDRS ONLY) char code_tuple; // tuple type char link_tuple; // number of bytes in tuple structure char tuple_link_cnt; // tuple byte count char tuple_data[1024]; //tuple dump buffer cis_addr = 0; // CIS starts at location 0 of Attribute memory index = 0; //pointer into tuple dump buffer do{ code_tuple = rd_code_tuple(cis_addr); //read code tuple tuple_data[index++] = code_tuple; //store code tuple in buffer cis_addr+=2; //increment addr to link tuple link_tuple = rd_link_tuple(cis_addr); //read link tuple tuple_data[index++] = link_tuple; //store link tuple in buffer cis_addr+=2; //increment addr to data tuple for(tuple_link_cnt=0;tuple_link_cnt

The code shown in Code Snippet above reads every tuple byte and then stores them in a tuple_data buffer. The CIS Tuple Collection Utility code only works against even bytes in the CIS memory area. The code tuple is read first and stored in the buffer. The tuple buffer pointer (index) is then incremented to point to the next byte in the tuple buffer.

The cis_addr which addresses tuples in the CIS memory area is increased by two to point to the tuple element, which always exists on an even-byte boundary. After reading and storing the link tuple, the data tuple area is accessed, read then stored in the tuple buffer

36

on the basis of the byte value contained within the link tuple. This process of addressing, reading and storing the tuples will not stop until the end tuple is encountered.

3.6 Some 802.11b Language Basics

802.11b can be described as a MAC (Medium Access Control), PHY (Physical) and

LLC (Link Layer Control) combination which operate in the 2.4GHz ISM band at a maximum speed of 11Mbps using standards set defined by the IEEE [25]. 802.11b devices operate in the ISM S-Band, which is from 2.4GHz to 2.5GHz. Operation in this band puts the typical 802.11b device in competition with radio emissions sent by other devices in that like wireless telephones and . In order to reduce the interference factor and increase data delivery reliability, 802.11b devices don‟t use collision detection schemes (CSMA/CD or Carrier Sense Multiple Access/Collision

Detection) as in wired 802.3 networks. Instead, it uses a collision avoidance method

(CSMA/CA or Carrier Sense Multiple Access/Collision Avoidance) [26]. It means that the 802.11b device pays attention to the communications ether before trying to transmit unlike 802.3 devices that collide and then back off for a period of time before trying to get access to the communications channel again. In order to make the 802.11b

CSMA/CA scheme work, a set of timing rules need to be implemented that allow an

802.11b station to enter the communications channel, send and receive its message and release the ether to the next 802.11b station that needs to transmit a message. This timing is automatic and it should be taken care of by the PRISM chipset firmware. If an 802.11b station finds traffic, it does not try a transmission and gives an exponentially-timed back off procedure. For increasing data delivery reliability, every transmitted message must be 37

known by the receiver. If communications conditions degrade, the PRISM chipset automatically decreases the transmission speed from 11 Mbps to 5.5 Mbps to 2 Mbps.

When the condition gets better, the NIC‟s transmission speed is automatically return to a maximum level.

The 802.2 LLC layer is common to all of the wired 802.3 MAC and 802.3 PHY OSI layers and the wireless 802.11 MAC and 802.11b PHY OSI layers. This relationship in the upper OSI layers allows the 802.11b LAN to work play easily with an 802.3 LAN at the LLC layer and above [27].

In addition to managing some of the network traffic, access points enhance the mobility of stations in a wireless network. Usually, an access point acts as a bridge between a wireless station and a wired system. When multiple access points are used in a network, each access point must be able to pass the mobile station‟s data to and from another mobile station, another access point or a wired network station. This passing and routing of messages is performed using what is called a distribution system. A distribution system in this sense is a logical component of 802.11 that simply routes messages to their destinations no matter which access point in the network the mobile

802.11b station is using.

An SSID (Service Set Identity) and a channel number are used to distinguish access points. The SSID is usually a human-readable description that can be up to 32 characters in length. An 802.11b station will scan the communications ether channel by channel to detect an access point to join [28]. In the United States, there are 11 valid channels which can be used for 802.11b. Most European countries can use 13 of the 14 available 802.11b

38

channels. If a particular SSID is specified, the 802.11b station will only join the access point with that specific SSID. Otherwise, the 802.11b station can be configured to join the strongest signaled access point it can find.

Once all of the available access points are identified by an 802.11b station, the

802.11b station can then introduce itself and join a BBS via the selected access point [29].

Before the 802.11b station can participate in the BSS, it must be authenticated by the access point. There are several ways to authenticate an 802.11b station. One method is called open-system and is really not authentication at all. Using open- system authentication the access point simply allows the requesting 802.11b station to come on in. If your 802.11b station is WEP-enabled (Wired Equivalent Privacy), the access point could invoke shared-key authentication. You can also instruct the access point to only authenticate certain station MAC addresses. This authentication process is called address filtering.

No matter how the 802.11b station gets authenticated, once the authentication process is complete the station can then associate with the access point. Association allows the

802.11b station to use the access point to gain access to the distribution system and thus gain access to the network.

The 802.11b CompactFlash NIC does so many things automatically for us, but to use those automatic features we must be able to listen to what the NIC is telling us and issue commands to the NIC to realize any transfer of data between wireless LAN stations.

39

3.7 The 802.11b CompactFlash NIC I/O Drivers

In the case of the Phoenix, I/O functions are used to steer the 802.11b CompactFlash

NIC. Code Snippet in Appendix B represents the final C statements in the init_cf_card call. Figure 3-3 shows the whole CompactFlash card initialization progress.

Start

Get The First Device Tuple

Scan the CIS Memory

Read the COR bit Mask

Add I/O enable bit

Set default SSID

End

Figure 3-3 The flow chart of CompactFlash Card initialization

40

The send_command function‟s purpose is obvious. In this case, we send a command to initialize the 802.11b CompactFlash NIC. There are other commands that may be issued with the send_command function and they are listed in Code Snippet above.

For now, we can concentrate on the initialization of the 802.11b CompactFlash NIC.

By way of a do-while loop, checks for the busy bit inside the Command_Register using the CmdBusy_Bit_Mask. The heart of the do-while loop is the rd_cf_io16 function retrieving a 16-bit value (cmd_data) from a designated address (Command_Register). wr_cf_addr function this case is writing an address of 0x0000 to the 802.11b

CompactFlash NIC address lines. To perform a CompactFlash card I/O read operation we must take IORD low for 2.2 μS, read the CompactFlash card data bus and return IORD to a logical high state. Earlier we found that the 802.11b CompactFlash NIC SRAM is rated at 55 nS and one would conclude that 2.2 μS is way too long a time to take to read 55 nS

SRAM. Remember that we‟re not talking directly to the SRAM. We‟re talking to the

PRISM chipset‟s firmware, which controls and accesses the 55 nS SRAM.

Two CompactFlash cards I/O read operations are required. One read is performed to get the low byte of the 16-bit value and another to retrieve the high byte of the 16-bit value. Note that the base address is incremented by one to access the high byte value. The

NOPs that follow the set_IORD macros are there to ensure any hold time requirements are met. The extra time afforded by the NOPs also gives the microcontroller I/O ports some time to settle. Once the high and low bytes are gathered, they are merged to form the 16-bit data value cmd_data.

When the busy bit is clear the busy bit do-while loop is exited and the command sequence can be written to the 802.11b CompactFlash NIC. If present, the command

41

parameter is written first followed by the actual command bit sequence as shown in code

Snippet below:

********************************************************** wr_cf_io16(parm0, Param0_Register); wr_cf_io16(cmd, Command_Register); **********************************************************

The wr_cf_io16 function is used to write a 16-bit value to the 802.11b CompactFlash

NIC. With the CompactFlash card I/O read operation, the desired address is sent to the

802.11b CompactFlash NIC‟s address lines before the actual data is put on the 802.11b

CompactFlash NIC‟s data bus. The LOW_BYTE and HIGH_BYTE macros are very similar to the make8 macro. However, the LOW_BYTE and HIGH_BYTE macros are more efficient as far as code size and execution time is concerned.

A 16-bit CompactFlash card I/O write operation is performed by executing the

TO_NIC macro, which puts the microcontroller data bus I/O in output mode. To write the low byte of the 16-bit value, the IOWR microcontroller I/O pin is taken to a logic low level for 800 nS before it is returned to a logical high state. Recall that we used values gleaned from the CIS to calculate a maximum write access time of 500 nS. Again 800 nS is half again as much time needed to perform the 500 nS write operation. If we had used

NOPs (200 nS each) the closest we could come to the ideal 500 nS write pulse is 600 nS.

As always, the first rule of embedded programming applies.

To avoid any I/O contention and satisfy any hold time requirements, a NOP is executed following the return of the IOWR I/O pin to a logical high state, which is then followed by the writing of all ones to the microcontroller‟s data I/O port. The base address is then incremented by one and the high byte of the 16-bit value is placed on the

802.11b CompactFlash NIC‟s data bus. An IOWR write pulse is generated in the same 42

fashion as it was in the low byte write sequence and the data bus is allowed to settle.

Before leaving the wr_cf_io16 function in code Snippet below, the microcontroller‟s data bus I/O port is put into input mode with the execution of the FROM_NIC macro.

********************************************************** void wr_cf_io16(unsigned int data16,unsigned int addr) { char i; wr_cf_addr(addr); data_out = LOW_BYTE(data16); TO_NIC; clr_IOWR; i=1; while(--i); set_IOWR; NOP(); data_out = 0xFF; wr_cf_addr(addr+1); data_out = HIGH_BYTE(data16); clr_IOWR; i=1; while(--i); set_IOWR; NOP(); data_out = 0xFF; FROM_NIC; } **********************************************************

The 802.11b CompactFlash NIC will go into a busy state while executing the command. We must wait for the busy bit to clear before proceeding. This is done by once again polling the Command_Register and checking the most significant bit (the busy bit) of the Command_Register for a value of 1 (1 = busy). The polling of the busy bit is done with the code you see in code Snippet below.

********************************************************** do{ cmd_data = rd_cf_io16(Command_Register); }while(cmd_data & CmdBusy_Bit_Mask); **********************************************************

43

When the busy bit finally clears, a command complete event will be generated. The command complete event is signaled by the setting of a bit in the Event Status Register.

As can be seen in code Snippet below, we look for the command complete bit by reading the EvStat_Register and applying a bit mask that represents the command complete bit, which happens to be the EvStat_Cmd_Bit_Mask (0x0010).

********************************************************** do{ evstat_data = rd_cf_io16(EvStat_Register); }while(!(evstat_data & EvStat_Cmd_Bit_Mask)); **********************************************************

Once the command complete bit materializes the 802.11b CompactFlash NIC will post a command status word in the Status Register. What we want to see is a return code of zero (rc = 0) after applying the Status_Result_Mask to the cmd_status word as we‟ve done in code Snippet below.

********************************************************** cmd_status = rd_cf_io16( Status_Register); rc = cmd_status & Status_Result_Mask; wr_cf_io16( EvStat_Cmd_Bit_Mask, EvAck_Register); **********************************************************

All events must be acknowledged by the Phoenix driver firmware. In this case, we must acknowledge the command complete event. Since the EvStat_Cmd_Bit_Mask value represents the command complete bit‟s location in the Event Acknowledge Register, all we have to do is write the EvStat_Cmd_Bit_Mask value to the Event Acknowledge

Register to acknowledge the pending command complete event.

In code Snippet below, the return code (rc) is parsed and returned to the calling function, which in this case is send_command. 44

********************************************************** switch(rc) { case 0x00: rc = 0; //command completed OK break; case 0x01: rc = 1; //Card failure break; case 0x05: rc = 2; //no buffer space break; case 0x7F: rc = 3; //command error break; } return(rc); **********************************************************

Another switch structure then translates the returned return code value into a human- readable message. What we want to see coming out of the Phoenix RS-232 port is

“Phoenix Initialized”. When we get that message, the 802.11b CompactFlash NIC is ready to receive commands and punch holes in electromagnetic space. Other undesirable messages are shown in Code Snippet below.

********************************************************** rc = send_command( Initialize_Cmd, 0); switch(rc) { case 0: printf(“\r\nPhoenix Initialized”); break; case 1: printf(“\r\nPhoenix Initialization Failure”); break; case 2: printf(“\r\nNo buffer space”); break; case 3: printf(“\r\nCommand error”); break; default: printf(“\r\nResult Code = %x”,rc); break; } **********************************************************

45

At this point, if all went well, the 802.11b CompactFlash NIC is initialized and ready to be told what we want to do next. The 802.11b CompactFlash NIC is in unsure situation and has not sent a word of RF yet. The 802.11b CompactFlash NICs exhibit a flashing

LED condition at this point.

46

Chapter 4

Setting up a Wi-Fi wireless network and making the board accesses the Wi-Fi

In the previous chapters we‟ve built some simple 802.11b hardware and we‟ve taken an extraordinarily in depth look at the electronics inside a typical 802.11b CompactFlash

NIC. We‟ve even taken some swipes at coding the Phoenix 802.11b driver.

In this chapter, we‟ll set up a BSS on Channel 1. Our BSS will consist of a standard desktop personal computer, a laptop equipped with built-in 802.11b capability and a

Phoenix. We use a Netgear wireless router as the AP for our BSS. Once we get all of the wireless LAN hardware up, we‟ll use a wireless LAN network to follow the 802.11b action.

I started by resetting the Netgear AP to its default settings and logging on to the

Netgear AP‟s management interface using the laptop personal computer with a wireless

Ethernet connection as the Figure 4-1 shows.

47

Figure 4-1 Wireless Access Point Setting page I set my wireless access point SSID to PHOENIX_NETWORK. Wireless LAN stations with hard-coded SSIDs will always look for and associate with an AP with a matching SSID.

For now, we‟ll leave everything else in the Netgear AP just as it is. The laptop and desktop personal can be given IP addresses via the AP‟s DHCP (Dynamic

Host Configuration Protocol) engine. The Phoenix 802.11b hardware does not participate in the DHCP exchanges and is hard-coded with an IP address of 192.168.1.150. This puts the Phoenix module out of range of the default AP DHCP IP address lease range, which is 192.168.1.2 to 192.168.1.51 on the Netgear AP.

48

I applied the SSID and Channel changes to the Netgear AP. Shortly thereafter, we checked the Netgear AP‟s status and saw two IP address leases had been distributed. As you can see in Figure 4-2, IP addresses 192.168.1.4 was assigned to the desktop named

EECS-NE2042-09A; the 802.11b laptop VICTOR-PC, received 192.168.1.2. The

Netgear AP uses the first IP address of 192.168.1.1.

Figure 4-2 Attached devices before Phoenix access

4.1 Setting up the SSID

So far we are ready for the Phoenix microcontroller‟s USART, initialized the

Phoenix‟s CompactFlash NIC and configured the 802.11b CompactFlash NIC for BSS operation. Our basic PHOENIX_NETWORK network hardware is working as designed.

The source code we have in the main function timeline code is thePhoenix_cfg call to

49

establish a desired SSID. All of the code that is touched by the Phoenix_cfg(SSID) call is listed in the Code Snippet below.

***************************** const char ssid[] = “PHOENIX_NETWORK”; //* RID CONFIGURATION RECORDS #define RID_cfgDesiredSSID 0xFC02 //the SSID of the BSS we want to join #define RID_DesiredSSID_Length 18 //word count of the DesiredSSID RID //********************************************************** //* PHOENIX CONFIGURATION FUNCTION //********************************************************** char Phoenix_cfg(unsigned int cmd) { case SSID: fidrid_buffer[0] = RID_DesiredSSID_Length; fidrid_buffer[1] = RID_cfgDesiredSSID; fidrid_buffer[2] = strlen(ssid); j = strlen(ssid); i=0; k=3; while(j > 1) { fidrid_buffer[k] = (ssid[i+1] << 8) | ssid[i]; i+=2; ++k; j-=2; } while(j > 0) { fidrid_buffer[k] = ssid[i]; --j; } rc = rid_write(RID_cfgDesiredSSID,fidrid_buffer,RID_DesiredSSID_Length); *****************************

In Sub Snippet below the fid_read buffer in employed just as it is with all of the RID operations we have experienced thus far. The actual length of our SSID string,

“PHOENIX_NETWORK”, is stored at position 2 of the fidrid_buffer. If we put a zero length string into the fidrid_buffer[2] slot, the Phoenix‟s 802.11b CompactFlash NIC will attempt to join the first BSS that it can find that will accept it.

********************************************************** case SSID: fidrid_buffer[0] = RID_DesiredSSID_Length; fidrid_buffer[1] = RID_cfgDesiredSSID; fidrid_buffer[2] = strlen(ssid); **********************************************************

50

The code to prepare the SSID string for presentation to the 802.11b CompactFlash

NIC is not complicated at all. All we‟re doing here is assembling the characters in the ssid array into little-endian words. The code between the while (j>0) braces in Sub

Snippet below takes care of the odd byte, which we have one of in our 15-byte ssid array.

********************************************************** j = strlen(ssid); i=0; k=3; while(j > 1) { fidrid_buffer[k] = (ssid[i+1] << 8) | ssid[i]; i+=2; ++k; j-=2; } while(j > 0) { fidrid_buffer[k] = ssid[i]; --j; } **********************************************************

4.2 Retrieving the MAC Address

This is just as good a time as any to pluck the 802.11b CompactFlash NIC‟s MAC address from the RID_cfgOwnMACAddress RID. All it takes is a simple rid_read call like the one in Code Snippet below.

***************************** //* RID CONFIGURATION RECORDS #define RID_cfgOwnMACAddress 0xFC01 //our MAC address char ipaddrc[4] = { 192,168,1,150}; #define make16(varhigh,varlow) (((unsigned int)varhigh & 0xFF)* 0x100) + ((unsigned int)varlow & 0x00FF) #define fidrid_buffer_size 256 unsigned int fidrid_buffer[fidrid_buffer_size]; unsigned int macaddri[3],ipaddri[2]; temp = rid_read(RID_cfgOwnMACAddress); for(i=0;i<6;i++) { if(i%2) macaddrc[i] = fidrid_buffer[2+i/2]>>8; 51

else macaddrc[i] = fidrid_buffer[2+i/2]& 0xFF; } for(i=0;i<3;++i) macaddri[i] = fidrid_buffer[i+2]; ipaddri[0] = make16(ipaddrc[1],ipaddrc[0]); ipaddri[1] = make16(ipaddrc[3],ipaddrc[2]); *****************************

The 802.11b CompactFlash NIC MAC address held in the fidrid_buffer is first converted to character format and stored in the macaddrc array by the code in Sub

Snippet below.

********************************************************** for(i=0;i<6;i++) { if(i%2) macaddrc[i] = fidrid_buffer[2+i/2]>>8; else macaddrc[i] = fidrid_buffer[2+i/2]& 0xFF; } **********************************************************

Then the same fidrid_buffer MAC address contents are formed into an integer format in the array macaddri with the for loop in Sub Snippet below.

********************************************************** for(i=0;i<3;++i) macaddri[i] = fidrid_buffer[i+2]; **********************************************************

The reason behind translating the 802.11b CompactFlash NIC MAC address into characters and integers hinges on how each Phoenix 802.11b function that has to have access to the MAC address uses the MAC address. For instance, the ARP function wants to see the MAC address as an array of integers, while the Phoenix 802.11b driver create_comframestructure function uses the MAC address in character form.

52

The IP address is not something that the 802.11b CompactFlash NIC cares about. As a result, the IP address is not part of the PRISM chipset or a physical and permanent part of the 802.11b CompactFlash NIC. Basically, we make up an IP address to suit our network needs. We choose an IP address of 192.168.1.150 you see in code Snippet below for the Phoenix modules.

********************************************************** ipaddri[0] = make16(ipaddrc[1],ipaddrc[0]); ipaddri[1] = make16(ipaddrc[3],ipaddrc[2]); **********************************************************

The Phoenix module’s IP address is only used in integer format in the Phoenix

802.11b driver.

4.3 Putting an Phoenix on a Wireless LAN

Here‟s a list of what we have accomplished thus far:

1. Power up and initialize the Phoenix USART.

2. Initialize the CompactFlash NIC.

3. Configure the CompactFlash NIC for BSS operation.

4. Configure the CompactFlash NIC‟s desired SSID.

5. Configure the CompactFlash NIC‟s maximum frame body data length.

6. Configure the CompactFlash NIC‟s transmission rates.

7. Retrieve and format the CompactFlash NIC‟s MAC address.

8. Format the Phoenix IP address.

53

So far, we can see if the Phoenix is connected to the wireless AP which we set up in the lab, when we open the router management interface, and check the attached device of the wireless router, as can be seen in Figure 4-3.

Figure 4-3 Attached devices after Phoenix access

As can be seen in Figure 4-3, that device with an IP address 192.168.1.150 is our

Phoenix, which means it is already connected to the wireless router and access the

WLAN. We can also use the Ping commend to check it again, here is Figure 4-4 for the

“ping” result.

54

Figure 4-4 Ping commend for Phoenix

As Figure 4-4 shows, Phoenix received all the data packets which sent by the laptop computer in the WLAN, which means we successfully make the Phoenix access the wireless access point, and it can send and receive data packet with other members in this

Local Area Network.

55

Chapter 5

Sending data to the terminal laptop computer by UDP

5.1 Running a UDP Application on the Phoenix

UDP is the closest thing to standard techniques to get in an . Like RS-232, UDP can be considered as an “I don‟t care” protocol.

Each protocol will send and receive data but neither of them cares if it really gets where it‟s going or not [30]. UDP and RS-232 leave the data integrity tasks up to the application.

You can send just about anything with UDP at any time you wish with very little effort.

A very useful , TFTP (Trivial File Transfer Protocol) is built on top of UDP [31]. Of all of the Internet protocols, UDP is the easiest to understand and implement. Just like all of the other internet protocols, UDP datagrams are handled the same whether they emanate from an RF source like the Phoenix 802.11b CompactFlash

NIC or are transported over ether in a wire.

UDP is short for User Datagram Protocol. Like IP, UDP has absolutely no means of insuring that a data packet will arrive in one piece or even arrive at all. However, we‟ll find that it is reliable enough for most tasks it‟s used for [32].

56

As mentioned earlier, UDP is a very simple and easy to understand protocol. UDP modifies an application-generated message by tagging on a checksum, a source port number and a destination port number of its own before passing the UDP segment to IP for encapsulation [33]. IP does its best to deliver the UDP segment since there is nothing within IP or the UDP segment it is carrying to guarantee that the UDP segment will arrive intact.

Logically, a UDP host transmits a UDP datagram through a source port to a UDP recipient‟s destination port. The destination port number and destination IP address are used to route the UDP segment to the correct application once the segment arrives at its destination. By using port numbers, various applications can be using the services of

UDP simultaneously. This is called . The combination of the IP address and the port number is called a socket.

Like RS-232, a UDP transmission can occur at any time without the need to establish a communications session with the remote host [34]. Since there is no handshaking or predetermined contact between UDP hosts, UDP is defined as a connectionless protocol.

Again, this is similar to the way RS-232 stations operate.

Despite the shortcomings that UDP appears to emanate, UDP does have advantages over its cousin TCP. For instance, UDP does not have to establish a formal connection and as a result is a faster and more efficient way to send a message. TCP uses a three-way handshake to establish a communications session before transmitting any data and TCP does an awful lot of housekeeping compared to none for UDP.

UDP is able to send messages as fast as the microcontroller and application it is involved with can run. The only thing that slows UDP down is the limitations of the

57

hardware it is running on and the bandwidth of the LAN it is riding on. Unlike UDP, TCP has built in rev limiters that throttle the data rate to relieve congestion on the LAN segment. UDP segments with any kind of problems are simply discarded by the devices on the LAN segment [35].

The layout of the UDP in Code Snippet below shows us that the UDP segment rides in the IP data area. Thus the UDP datagram is encapsulated within the IP datagram.

The UDP source and destination ports are 16-bits in length, which allows port numbers to range from 0 to 65535 [36]. The UDP header is only 8 bytes long compared to the 20 bytes that make up the IP header. The UDP datagram length or size is simply the total number of bytes in the UDP header plus the number of bytes in the UDP payload (data area).

//********************************************************** //* IP Header Layout //********************************************************** #define ip_vers_len 0x0C //IP version and header length #define ip_pktlen 0x0D //packet length #define ip_id 0x0E //datagram id #define ip_frag_offset 0x0F //fragment offset #define ip_ttlproto 0x10 //time to live define ip_hdr_cksum 0x11 //header checksum #define ip_srcaddr 0x12 //IP address of source #define ip_destaddr 0x14 //IP addess of destination #define ip_data 0x16 //IP data area //********************************************************** //* UDP Header Layout //********************************************************** #define UDP_srcport ip_data #define UDP_destport UDP_srcport+1 #define UDP_len UDP_destport+1 #define UDP_cksum UDP_len+1 #define UDP_data UDP_cksum+1 *****************************

58

5.2 Setting Phoenix Using Tera Term Pro

Tera Term is an open-source, free, software implemented, terminal emulator

(communications) program. It supports , SSH 1 & 2 and serial port connections. It also has a built in Macro scripting language and a few other useful plugins [37].

In this case, we use Tera Term Pro to do some setting job for the Phoenix, at first, start up the Tera Term Pro terminal emulator on the computer and set the baud rate for

57600bps as we wrote in the C code. Connect its RS-232 port to the Phoenix‟s serial port and apply power to the Phoenix. If everything goes well, we can see the figure below:

Figure 5-1 Tera Term Pro setting window before CompactFlash card is activated

At this time, it is available to set Cycle Time, Phoenix IP address, Remote (the laptop computer) IP address, Phoenix UDP port and Remote UDP port by pressing different numbers on the keyboard of the computer.

59

Set the CYCLE TIME for the number of seconds between UDP packet transmissions.

Set the PHOENIX IP ADDRESS to your desired IP address. The default PHOENIX IP

ADDRESS is 192.168.1.150. If you change the WLAN Phoenix default IP address in the

WLAN Phoenix UDP Utility, you must also change the WLAN Phoenix IP address in the

WLAN Phoenix driver code. Set the REMOTE IP ADDRESS to your laptop computer‟s

IP address. For now, leave the UDP PORT settings at their defaults. You can change the

UDP PORT addresses. Just make sure the UDP PORT addresses you specify match the

WLAN Phoenix and personal computer UDP Port addresses you have coded in your applications. The PHOENIX UDP PORT address of 8088 is the default UDP address that is coded into the WLAN Phoenix Driver code. Again, if you wish to change the default

UDP address, you must make the same change in the WLAN Phoenix Driver code. The

REMOTE UDP PORT address of 30303 is used with the Microchip MCHPDetect utility, which can be get from the bowels of the free Microchip TCP/IP Stack.

5.3 Sending and Receiving Data by UDP

This is the last step of the experiment, so let us take a review of the previous work about the whole procedure of the Phoenix . As mentioned before, the first thing after the microcontroller settles is check if the device tuple is available through a read request. If it is not available it may indicate a faulty connection between the controller and the

Compact Flash card. After enough information is obtained from the CIS to make the

Phoenix work properly (the device tuple and the COR address), the module enters I/O mode. With the proper functions, the module configures itself to enter the managed mode of the IEEE 802.11 specification, enters to the default Service Set Identifier (SSID), and 60

specifies its own maximum packet size and the transmission rate. If any of these initialization procedures fail the module does a software reset and tries again. With the primary configuration done, is safe to request the MAC address through a RID, as well to allocate the transmission buffers. The sending data process is shown in Figure 5-2.

Start

Send Data Initialize PIC

Initialize CF Card No Assemble UDP

Get Data from PIC Yes If CF card is connected

Set IP Address Yes No

Yes Save MAC If SSID If Data from Address matched PIC

No

Figure 5-2 The whole data sending process flow chart 61

As shown in Figure 5-1, once we are done with the Phoenix and remote settings, the

Phoenix is ready to send data via Wi-Fi. Before we start up the CompactFlash 802.11 radio card, we need to start the MCHPDetect application. We want to be sure to capture any UDP packets that may be thrown by the Phoenix, with the MCHPDetect application running in a Windows command prompt window, what can be seen is as Figure 5-2

Figure 5-3 The MCHPDetect application window

At this point the CompactFlash 802.11 radio card is inactive until we hit the ESC button on the keyboard, so now, we activate the CompactFlash 802.11 radio card by pressing the ESC button, at first, the terminal emulator Tera Term Pro window refreshed to reveal the hardware (MAC) address of the CompactFlash radio card plugged into the

Phoenix, as well as the MAC address of my laptop computer‟s Ethernet adapter, which is receiving UDP packets from the Phoenix. Figure 5-3 shows the situation right now.

62

Figure 5-4 Tera Term Pro window after CF card is activated

If the remote IP address and MAC address match the two addresses of the laptop computer, it is ready to receive the UDP packets hard-coded in the Phoenix, which can be seen in the MCHPDetect application as Figure 5-4 shows.

Figure 5-5 Data packets received on laptop computer

63

Chapter 6

Conclusions and Future Work

6.1 Conclusions

This thesis has presented the idea of implementing wireless data transmission by means of microcontroller and Wi-Fi CompactFlash card. This is a small, convenient, and inexpensive wireless communication module. If it is combined with a sensing system, it can be used in many areas such as real-time measuring, industrial monitoring, and machine health monitoring. In this research, we have used the high-performance

Enhanced Flash Microcontrollers PIC18LF6722 to control the 802.11 Wireless

CompactFlash Card to search the Wi-Fi access point with the matched SSID, and then we make it to throw 8-byte data packets which can be received by a Wi-Fi capability device with the desired IP address. All of these functions are implemented through initializing the CompactFlash Card, reading and writing the CompactFlash Card. In order to do this, we write the C-code for the Microcontroller PIC18LF6722, and make it access the

CompactFlash Card to tell it to do access the Wi-Fi access point and send data packets.

Compared with the wireless module before, the Phoenix is an inexpensive, simple and easy-to-build PIC-based device, and it is also easy to understand

64

because it transfer data via Wi-Fi, which is a normally is used universally, the most popular wireless network technology, is a family of standards for wireless networking defined in the IEEE 802.11 specifications.

6.2 Future Work

Since the Phoenix is an experimental product, it still has some imperfections, and the various results obtained indicate the following possible upgrades to the platform.

1. Use a battery power instead of the wired power supply for the data transmission module to make it totally wireless

2. Considering the data security, it can be made to access a Wi-Fi network with various such as WEP or WPA, so that the data cannot be captured by other people if the data is secret or privacy.

3. Add a new function to send the data to the Internet. This enables that data to be available anywhere in the world.

65

References

[1] Upkar Varshney, "Recent Advances in Wireless Networking," Communications,

pp. 100-103, June 2000

[2] Jin Zhu, "Development of an Application-Oriented Wireless Communication

Networks Course for Engineering Technology Program," the Technology

Interface Journal/Spring 2010, Volume 10 No. 3

[3] Makoto Miyake, "A Survey on Progress and Standardization Trends in Wireless

Communications," JOURNAL OF COMMUNICATIONS, VOL. 4, NO. 7,

AUGUST 2009

[4] David J. Nagel, Wireless Sensor Systems and Networks: Technologies,

Applications, Implications and Impacts .

[5] Paramjit S. Kahai, Simran K. Kahai, "Deployment Issues And Security

Concerns With Wireless Local Area Networks: The Deployment Experience

At A University" Journal of Applied Business Research, pp. 11-24, Volume 20,

Number 4

[6] Vinoth Gunasekaran, Fotios C. Harmantzis, "Emerging wireless technologies

for developing countries," Technology in Society, pp. 23-42, 2007

[7] Kuang-Yeh Wang, and Satish K. Tripathi, "Mobile-End Transport Protocol: An

Alternative to TCP/IP OverWireless Links,"

66

[8] http://www.ar.cc.mn.us/blommel/CNET-2205/0-619-21579-8_02_op.pdf

[9] Microchip Technology Inc, "HI-TECH C Compiler for PIC10/12/18 MCUs

Version 9.80 Release Notes"

[10] Microchip Technology Inc, "Software Solutions for the 16-bit and 32-bit

Designer," January 2010

[11] “PIC18F8722 Family Data Sheet,” Microchip

[12] "Genesys Board Refference Manual" Revision: August 27, 2010

[13] "COMMUNICATION WITH A PC USING RS232 "

http://www.st.com/stonline/books/pdf/docs/10340.pdf

[14] Dogan Ibrahim, "Microcontroller DEBUGGING and TESTING tools,"

Electronics World, August 2009, pp. 20-23

[15] "Configuring Serial Terminal Emulation Programs,"

http://www.actel.com/documents/Configuring_Serial_Terminal_Emulation_Programs.pdf

[16] “PIC18F8722 Family Data Sheet,” Microchip

[17] "MPLAB ICD 3 In-Circuit Debugger User‟s Guide, " Microchip

[18] "802.11b Wireless CompactFlash Card data sheet"

http://www.xterasys.com/files/cwb1k_data.pdf

[19] http://www.xterasys.com/product/cwb1k.htm

[20] "CF+ and CompactFlash Specification Revision 3.0," CompactFlash

Association, Dec 2004

[21] Mark Samuels, " PIC a CompactFlash Card," CIRCUIT CELLAR, pp. 1-571,

67

Feb 2001.

[22] "DataSafe CompactFlash Engineering Spcification"

http://www.delkin.com/oem/pdf/cf_datasafe_sheet.pdf

[23] Francisco Javier Díaz Delgadillo, Adalberto Bustamante López, Arturo Nikolai

Sevilla Covarubias, "XRunner Project," SONY Robotika, 2007.

[24] "CF test 222 Technical Reference Manual " Sycard Technology, January 2002

[25] "IEEE 802.11b Wireless LANs "

http://www.3com.com/other/pdfs/infra/corpinfo/en_US/50307201.pdf

[26] "The 802.11 Protocol Stack and ,"

http://www.scribd.com/doc/13628928/80211-Protocol-Stack-and-Physical-

Layer

[27] Larry M. Sanders, "A Configuration Protocol for Embedded Devices on Secure

Wireless Networks," B.S.Co.E., University of Kansas, Lawrence, Kansas, 2000.

[28] Oct 2005 wikipedia, http://en.wikipedia.org/wiki/Service_set_(802.11_network)

[29] Arindam Ghosh, Aboubaker Lasebae, Enver Ever, " Performance Evaluation of

Wireless IEEE 802.11(b) used for Ad-Hoc Networks in an ELearning

Classroom Network," Middlesex University

[30] Jan Axelson, " Embedded Ethernet and Internet Complete - Designing and

Programming Small Devices for Networking," 2003

[31] "TCP/IP Tutorial and Technical Overview," International Technical Support

Organization, December 2006

68

[32] Norman Matloff, " Tutorial on Network Programming with Python ," University

of California, May, 2009

[33] Manmeeet. Singh, “Designing Masking Ruleset for Hiding Operaing System

Identity ” M. Eng. Thesis, Thapra University, Patialay, May,2007.

[34] Ahsan Habib, Nicolas Christi,John Chuang, " Taking Advantage of

Multihoming with Striping," pp. 1-6, INFOCOM 2006. 25th

IEEE International Conference on Computer Communications. Proceedings,

Apr, 2006

[35] Fred Eady, "Networking and with Microcontrollers," 2004

[36] http://www.cs.usfca.edu/~parrt/doc/java/Sockets-notes.pdf

[37] Sep 2010, wikipedia, http://en.wikipedia.org/wiki/Tera_Term

69

Appendix A

Definition of local variables C code used in the 802.11b CompactFlash NIC initialization procedure

//********************************************************** //* PORT Definitions //********************************************************** #define AOUT LATA #define BOPEN PORTB #define COPEN PORTC #define data_in PORTD #define data_out LATD #define EOPEN PORTE #define PCTL LATF #define addr_hi LATG #define addr_lo LATH #define PCOMM LATJ //********************************************************** //* CF I/O Definitions //********************************************************** #define RSET 0x10 #define set_RSET PCTL |= RSET #define clr_RSET PCTL &= ~RSET //********************************************************** //* Flags //********************************************************** #define cisflag 0x04 #define bcisflag flags & cisflag #define setf_cis flags |= cisflag #define clrf_cis flags &= ~cisflag //********************************************************** //* PORT TRIS Definitions //********************************************************** #define TO_NIC TRISD = 0x00 #define FROM_NIC TRISD = 0xFF #define SETUP_A TRISA = 0x00; \ LATA = 0xFF; #define SETUP_C TRISC = 0x80; #define SETUP_F TRISF = 0x20; \ LATF = 0xFB; #define SETUP_G TRISG = 0x00; \ 70

LATG = 0xF0; //CE1 = 0; //CE2 = 1; #define SETUP_H TRISH = 0x00; \ LATH = 0x00; #define SETUP_J TRISJ = 0xEF; \ LATJ = 0xFF; void init_cf_card(void) { char cor_addr_lo,cor_addr_hi,cor_data; char cis_device; unsigned int x; unsigned int cis_addr; // attribute memory index (EVEN ADDRS ONLY) char code_tuple; // tuple type char link_tuple; // number of bytes in tuple structure char tuple_link_cnt; // tuple byte count char tuple_data; // current tuple contents char funce_cnt; char mac_cnt; char rc; set_RSET; //reset CF card SETUP_A; //configure I/O ports SETUP_C; SETUP_F; SETUP_G; SETUP_H; SETUP_J; FROM_NIC; //set to receive from NIC clr_RSET; //take CF card out of reset clrf_cis; //clear cis flag rc = 0; //clear result code

71

Appendix B

C code for the CompactFlash Card initialization

***************************** //* COMMAND/STATUS #define Command_Register 0x0000 #define Param0_Register 0x0002 //* EVENT #define EvStat_Register 0x0030 #define EvAck_Register 0x0034 //* COMMANDS #define Initialize_Cmd 0x0000 //* BIT MASKS #define CmdCode_Mask 0x003F #define CmdBusy_Bit_Mask 0x8000 #define EvStat_Tick_Bit_Mask 0x8000 #define EvStat_WTErr_Bit_Mask 0x4000 #define EvStat_InfDrop_Bit_Mask 0x2000 #define EvStat_Info_Bit_Mask 0x0080 #define EvStat_DTIM_Bit_Mask 0x0020 #define EvStat_Cmd_Bit_Mask 0x0010 #define EvStat_Alloc_Bit_Mask 0x0008 #define EvStat_TxExc_Bit_Mask 0x0004 #define EvStat_Tx_Bit_Mask 0x0002 #define EvStat_Rx_Bit_Mask 0x0001 #define Status_Result_Mask 0x7F00 #define nop NOP() //********************************************************** //* Macros //********************************************************** #define make8(var,offset) ((unsigned int)var >> (offset * 8)) & 0x00FF #define make16(varhigh,varlow) (((unsigned int)varhigh & 0xFF)* 0x100) + ((unsigned int)varlow & 0x00FF) /* Macros to access bytes within words */ #define LOW_BYTE(x) ((unsigned char)(x)&0xFF) #define HIGH_BYTE(x) ((unsigned char)(x>>8)&0xFF) //********************************************************** //* PORT Definitions //********************************************************** #define data_in PORTD #define data_out LATD #define addr_hi LATG

72

#define addr_lo LATH //********************************************************** //* PORT TRIS Definitions //********************************************************** #define TO_NICTRISD = 0x00 #define FROM_NIC TRISD = 0xFF //********************************************************** //* CF I/O Definitions //********************************************************** #define OE 0x01 #define IORD 0x02 #define WE 0x40 #define IOWR 0x80 #define set_OE PCTL |= OE #define clr_OE PCTL &= ~OE #define set_IORD PCTL |= IORD #define clr_IORD PCTL &= ~IORD #define set_IOWR PCTL |= IOWR #define clr_IOWR PCTL &= ~IOWR void wr_cf_addr(unsigned int addr) { addr_hi = (make8(addr,1)); addr_lo = addr & 0x00FF; } unsigned int rd_cf_io16(unsigned int addr) { char data_lo,data_hi,i; unsigned int data16; wr_cf_addr(addr); clr_IORD; i=3; while(--i); data_lo=data_in; set_IORD; NOP(); wr_cf_addr(addr+1); clr_IORD; i=3; while(--i); data_hi=data_in; set_IORD; NOP(); data16 = make16(data_hi,data_lo); return(data16); } void wr_cf_io16(unsigned int data16,unsigned int addr) { char i; wr_cf_addr(addr); data_out = LOW_BYTE(data16); TO_NIC; clr_IOWR; i=1; while(--i); set_IOWR; NOP(); data_out = 0xFF; wr_cf_addr(addr+1); 73

data_out = HIGH_BYTE(data16); clr_IOWR; i=1; while(--i); set_IOWR; NOP(); data_out = 0xFF; FROM_NIC; } char send_command(unsigned int cmd, unsigned int parm0) { char cmd_code,rc; unsigned int cmd_status,evstat_data; do{ cmd_data = rd_cf_io16(Command_Register); }while(cmd_data & CmdBusy_Bit_Mask); wr_cf_io16(parm0, Param0_Register); wr_cf_io16(cmd, Command_Register); do{ cmd_data = rd_cf_io16(Command_Register); }while(cmd_data & CmdBusy_Bit_Mask); do{ evstat_data = rd_cf_io16(EvStat_Register); }while(!(evstat_data & EvStat_Cmd_Bit_Mask)); cmd_status = rd_cf_io16( Status_Register); rc = cmd_status & Status_Result_Mask; wr_cf_io16( EvStat_Cmd_Bit_Mask, EvAck_Register); switch(rc) { case 0x00: rc = 0; //command completed OK break; case 0x01: rc = 1; //Card failure break;

case 0x05: rc = 2; //no buffer space break; case 0x7F: rc = 3; //command error break; } return(rc); } ***************************** void init_cf_card(void) { char rc;

rc = send_command( Initialize_Cmd, 0); switch(rc) { case 0: printf(“\r\nPhoenix Initialized”); break; case 1: printf(“\r\nPhoenix Initialization Failure”); break; case 2: printf(“\r\nNo buffer space”); break; 74

case 3: printf(“\r\nCommand error”); break; default: printf(“\r\nResult Code = %x”,rc); break; } }

75