summaryrefslogtreecommitdiffstats
path: root/hardware_specifications.txt
blob: cd805b97bf8f9e6d32bac3f152cd0ffce6c6c745 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
==============================================================
==      Hardware specifications for the Wi-Fi Detector      ==
==    http://www.getdigital.de/products/Wifi_Finder_LCD     ==
==                                                          ==
==          (c) 2007 Michael Buesch <mb@bu3sch.de>          ==
==                                                          ==
==  This hardware specification file is licensed under the  ==
==     Creative Commons Attribution Share Alike license     ==
==      http://creativecommons.org/licenses/by-sa/3.0/      ==
==============================================================


====================================
=== General hardware information ===
====================================

The microcontroller is an Atmel Mega168 with an external 12Mhz clock.
The device has a standard Atmel ISP (In System Programmer) connector
on the PCB (printed circuitry board). (The 6 solder pads on the lower
right). The pin layout is the standard Atmel layout, but I'll draw it
here for reference:

                                              ^
                                              .
  AVR controller PCB                          .
  lower right edge                            |
                            -------------     |
                           | MISO | VTG  |    |
			   |-------------|    |
                           | SCK  | MOSI |    |
                           |-------------|    |
                           | RST  | GND  |    |
			    -------------     |
<...------------------------------------------



=============
=== PORTS ===
=============

Data directions:

DDRB: 0b00000000  (all input)
DDRC: 0b11111111  (all output)
DDRD: 0b11011100

Port bit usages:

PortB:
---------------------------------
bit # | DDR | Init | Description
---------------------------------
bit 0 | in  | 1    | Key (next)
bit 1 | in  | 1    | Key (back)
bit 2 | in  | 1    | Key (scan/lock)
bit 3 | in  | 0    | ?
bit 4 | in  | 0    | ?
bit 5 | in  | 0    | ZD1211 LED0 (array pin 4)
bit 6 | in  | 0    | ?
bit 7 | in  | 0    | ?

PortC:
---------------------------------
bit # | DDR | Init | Description
---------------------------------
bit 0 | out | 1    | LCD clock signal
bit 1 | out | 1    | LCD data signal
bit 2 | out | 1    | LCD register select; 0->command, 1->data
bit 3 | out | 1    | LCD chip select; 0->selected, 1->inactive
bit 4 | out | 1    | LCD reset; 0->reset, 1->operation
bit 5 | out | 0    | N/C?
bit 6 | out | 1    | N/C, AVR Reset pin
bit 7 | out | 1    | N/C

PortD:
---------------------------------
bit # | DDR | Init | Description
---------------------------------
bit 0 | in  | 1    | USART RXD (array pin 8)
bit 1 | in  | 0    | USART TXD (array pin 5)
bit 2 | out | 0    | ZD1211 power control
bit 3 | out | 0    | Battery measure enable
bit 4 | out | 1    | LCD backlight 1->on, 0->off
bit 5 | in  | 1    | ZD1211 LED1 (array pin 3)
bit 6 | out | 0    | ?
bit 7 | out | 1    | ?

N/C -> not connected
For Input pins "Init" means 1->pullup_enable, 0->pullup_disable



===========
=== LCD ===
===========

The LCD has 96 pixel-columns with 8 pixels each and 4 lines.
The LCD is addressed as row and column, where each 8 pixel column
is represented by one data byte (8 bit).

         Column
         0 1 2 3 4 5 6 7 8 9 ... 95
       ----------------------------
       | * * * * * * * * * * ...... |
       | * * * * * * * * * * ...... |
       | * * * * * * * * * * ...... |
row 0  | * * * * * * * * * * ...... |
       | * * * * * * * * * * ...... |
       | * * * * * * * * * * ...... |
       | * * * * * * * * * * ...... |
       | * * * * * * * * * * ...... |
-------|                            |
       | * * * * * * * * * * ...... |
row 1  | * * * * * * * * * * ...... |
    .  | . . . . . . . . . . ...... |
    .  | . . . . . . . . . . ...... |
row 3  | . . . . . . . . . . ...... |
       ----------------------

The * are the pixels.
Dots (.) are continuations.


Commands:
  0x04			=> ? Used when writing data
  0x12			=> ? Used when writing data
  0xAF			=> Enable the LCD?
  0xB0 + line # (0-3)	=> move cursor to line


Sending a command byte:
  * Drive LCD Register Select low
  * Do the "Generic byte send algorithm"

Sending data byte:
  * Drive LCD Register Select high
  * Do the "Generic byte send algorithm"

Generic byte send algorithm:
  * Init Clock and Data signals to high
  * Drive LCD chipselect low
  * For each bit to send do (from MSB to LSB)
    * If the bit is set
      * Drive the LCD Data line high
    * else
      * Drive the LCD Data line low
    * Drive the LCD Clock line low
    * Drive the LCD Clock line high
    * Wait 1 uSec
    * Drive the LCD Clock line low
  * Drive LCD chipselect high

Sending character data to the LCD:
  * For each line (0-3)
    * Move the cursor to the desired line (command 0xB0)
    * Send command 0x12
    * Send command 0x04
    * For each data byte of the line
      * Do the "Sending data byte" algorithm.
        A byte is one pixel column in the selected line.
        The LCD will automatically jump to the next column

Initialization:
  * Drive "LCD reset" low for 100ms.
  * Drive reset high and wait another 50ms for the device to init itself.
  * Drive chipselect high and init the other lines.
  * Send command 0xE2
  * Send command 0xAB
  * Send command 0xC8
  * Send command 0x40
  * Move the cursor to line 0
  * Send command 0x10
  * Send command 0x00
  * Send command 0xA1
  * Send command 0xA6
  * Send command 0xA2
  * Send command 0x2F
  * Send command 0x24
  * Send command 0x81
  * Send command 0x00
  * Clear the display (write all-zero data)
  * Send command 0xAF



========================================
=== Check if we are connected to USB ===
========================================

A check if we are connected with the ZD1211 board's USB connector to a computer
can be done though the USART TX pin.
First make sure that the USART is disabled, so we can use the USART TX pin as
a normal input pin (PinD bit 1).
If the pin (PinD bit 1) is driven HIGH, we are connected to USB.

Checking whether USB is connected can also be done through ADC7.
See the ADC7 description below.



=======================
=== ADC measurement ===
=======================

  * Write the ADC configuration values to the ADC control registers.
    This includes selecting the reference and MUX settings.
  * Trigger 4 ADC measurements by doing this 4 times:
    * Start an ADC conversion, wait for it to finish
      and read the ADC value.
  * Get the average of the 4 measurements.
    That is the measurement result.



=====================================
=== Measuring the battery voltage ===
=====================================

Measuring the battery voltage is done through ADC7.

ADC7 settings:
  * Reference: 1.1V internal
  * ADC Prescaler: 16
  * No autotrigger
  * Left Adjust Result bit is not set

Measuring the voltage:
  * Drive "Battery measure enable" of PortD high.
    This enables the external measuring circuitry.
  * Wait 10 uSec for the circuitry to stabilize.
  * Do an "ADC measurement" (see above) on ADC7
  * Drive "Battery measure enable" of PortD low.
    This disables the external measuring circuitry.
    Disabling is important to avoid drawing unnecessary current.
  * Interpret the result of the measurement by looking
    up the battery voltage table.

Battery measurement key figures:
(A more exact ADC-value to battery-voltage lookup table
 can be generated by the battery_tab_gen.py script)

------------------------------------------------------------
ADC7 value | Description
------------------------------------------------------------
   0x0FC   | Absolute minimum battery voltage 1*)
>= 0x124   | Battery voltage is low
>= 0x130   | Battery voltage is medium
>= 0x13C   | Battery is fully charged
-----------+-------------------------------------------------
>= 0x171   | We are not running on battery.
           | Power is supplied through the USB port.

1*) --- WARNING ---
    When minimum battery voltage is reached turn off everything
    including all IRQs and put the microcontroller into sleep.
    We must avoid draining battery voltage below 3.0V, as that
    physically destroys the battery.

Note that the lower the battery voltage is, the less wireless networks
the device is able to find.



==============================
=== Recharging the battery ===
==============================

The battery will automatically get recharged while we are connected to USB
and have the power switch turned ON.
The device will automatically stop charging when the battery is fully charged.

Checking the charge status is done by measuring ADC6 while
being connected to USB. Note that the "Battery measure enable" must NOT
be pulled high while measuring ADC6.

---------------------------------------------------------------------------
ADC6 value             | Description
---------------------------------------------------------------------------
0x0   <= ADC6 <= 0xC0  | Not charging battery (Switch not in ON state)
0xC1  <= ADC6 <= 0x160 | Charging battery (Switch is in ON state)
0x161 <= ADC6          | Battery is fully charged (Switch is in ON state)



=================================
=== Accessing the ZD1211 chip ===
=================================

The zd1211 chip is accessed through the USART interface.

USART settings:
  * Asynchronous
  * 115200 baud
    (UBRR = 0x000C, at 12Mhz crystal with U2X speed doubler)
  * 8 data bits
  * 1 stop bit
  * No parity

Scanning for wireless networks:
  * To apply power to the ZD MAC and RF chips, pull PortD bit 2 high.
    It will immediately start scanning after power is applied.
    The device will draw about 200mA at 3.7V when enabled.
  * The original firmware writes 0xEE through the UART now, though
    that seems bogus. Not sure why they do that.
  * Wait for ZD1211 to finish the scan: Poll the UART in a loop
    until a 0xAA byte is read. Consider using a timeout.
  * Loop
    * Read 127 bytes from the UART and handle them (see "Received data" below).
    * Try to read the next byte from the UART.
    * If the UART was empty and no byte was read, break the loop.
    * If the byte is not 0xAA an error occurred.
  * Disable power on the ZD1211 by pulling PortD bit 2 low.

Received data:

Each received data chunk is 127 bytes long. It consists of a small header
and a stripped down IEEE 802.11 beacon or probe response. 

The header is 3 bytes long:
-----------------------------------------------------------------
| byte 0 | Unknown, seems it can only be 0x00 or 0x01.          |
|---------------------------------------------------------------|
| byte 1 | The channel number this beacon was received on       |
|---------------------------------------------------------------|
| byte 2 | The RX Signal Strength Indicator                     |
-----------------------------------------------------------------
| 124 bytes of beacon data follow. The IEEE 802.11 header       |
| of the beacon is half-stripped. So this data block starts     |
| with the last byte of the SA mac address. (So the second      |
| byte of this block is the first byte of the BSSID).           |
-----------------------------------------------------------------

Note that the only reason for including the last byte of the SA
in front of the BSSID is alignment. It will align the beacon packet
to a 4byte boundary. Though, that doesn't matter for us
on the 8bit controller, of course.
See the IEEE 802.11 specifications for more info on the
IEEE 802.11 wireless header data (which is partially included
in the data) and the IEEE 802.11 beacon and probe response packets.

bues.ch cgit interface