File: dsensor.h

package info (click to toggle)
brickos 0.9.0-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 1,700 kB
  • ctags: 1,727
  • sloc: ansic: 9,139; cpp: 860; makefile: 717; asm: 693; sh: 123; perl: 61
file content (277 lines) | stat: -rw-r--r-- 7,633 bytes parent folder | download | duplicates (7)
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
/*! \file   include/dsensor.h
    \brief  Interface: direct reading of sensors
    \author Markus L. Noga <markus@noga.de>
 */

/*
 *  The contents of this file are subject to the Mozilla Public License
 *  Version 1.0 (the "License"); you may not use this file except in
 *  compliance with the License. You may obtain a copy of the License
 *  at http://www.mozilla.org/MPL/
 *
 *  Software distributed under the License is distributed on an "AS IS"
 *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 *  the License for the specific language governing rights and
 *  limitations under the License.
 *
 *  The Original Code is legOS code, released October 17, 1999.
 *
 *  The Initial Developer of the Original Code is Markus L. Noga.
 *  Portions created by Markus L. Noga are Copyright (C) 1999
 *  Markus L. Noga. All Rights Reserved.
 *
 *  Contributor(s): Markus L. Noga <markus@noga.de>
 */

/*
 *   2000.04.30 - Paolo Masetti <paolo.masetti@itlug.org>
 *
 *	- Some typecast & ()s in macros to avoid strange effects
 *        using them...
 *
 *  2000.09.06 - Jochen Hoenicke <jochen@gnu.org>
 *
 *	- Added velocity calculation for rotation sensor.
 */


#ifndef	__dsensor_h__
#define __dsensor_h__

#ifdef  __cplusplus
extern "C" {
#endif

#include <config.h>

#ifdef CONF_DSENSOR

#include <sys/h8.h>
#include <sys/bitops.h>

///////////////////////////////////////////////////////////////////////
//
// Definitions
//
///////////////////////////////////////////////////////////////////////

//
//!< the raw sensors
//
#define SENSOR_1	AD_C	//!< Sensor on input pad 1
#define SENSOR_2	AD_B	//!< Sensor on input pad 2
#define SENSOR_3	AD_A	//!< Sensor on input pad 3
#define BATTERY		AD_D	//!< Battery sensor

//
//!< active light sensor: estimated raw values
//
#define LIGHT_RAW_BLACK 0xffc0	//!< active light sensor raw black value
#define LIGHT_RAW_WHITE 0x5080	//!< active light sensor raw white value


//
// convert raw values to 0 (dark) .. LIGHT_MAX (bright)
// roughly 0-100.
//
#define LIGHT(a)    (147 - ds_scale(a)/7)	//!< map light sensor to 0..LIGHT_MAX
#define LIGHT_MAX   LIGHT(LIGHT_RAW_WHITE)	//!< maximum decoded value

//
// processed active light sensor
//
#define LIGHT_1     LIGHT(SENSOR_1)		//!< light sensor on input 1
#define LIGHT_2     LIGHT(SENSOR_2)		//!< light sensor on input 2
#define LIGHT_3     LIGHT(SENSOR_3)		//!< light sensor on input 3

#ifdef CONF_DSENSOR_ROTATION
//
// processed rotation sensor
//
#define ROTATION_1  (ds_rotations[2])	//!< rotation sensor on input 1	
#define ROTATION_2  (ds_rotations[1])	//!< rotation sensor on input 2	
#define ROTATION_3  (ds_rotations[0])	//!< rotation sensor on input 3	
#endif

#ifdef CONF_DSENSOR_VELOCITY
//
// processed velocity sensor
//
#define VELOCITY_1  (ds_velocities[2])
#define VELOCITY_2  (ds_velocities[1])
#define VELOCITY_3  (ds_velocities[0])
#endif

#ifdef CONF_DSENSOR_MUX
#define SENSOR_1A (ds_muxs[2][0])
#define SENSOR_1B (ds_muxs[2][1])
#define SENSOR_1C (ds_muxs[2][2])
#define SENSOR_2A (ds_muxs[1][0])
#define SENSOR_2B (ds_muxs[1][1])
#define SENSOR_2C (ds_muxs[1][2])
#define SENSOR_3A (ds_muxs[0][0])
#define SENSOR_3B (ds_muxs[0][1])
#define SENSOR_3C (ds_muxs[0][2])
#endif //CONF_DSENSOR_MUX

//! Convert raw data to touch sensor (0: off, else pressed)
#define TOUCH(a)    ((unsigned int)(a) < 0x8000)

//  Processed touch sensors
//
#define TOUCH_1     TOUCH(SENSOR_1)		//!< touch sensor on input 1
#define TOUCH_2     TOUCH(SENSOR_2)		//!< touch sensor on input 2
#define TOUCH_3     TOUCH(SENSOR_3)		//!< touch sensor on input 3


#define ds_scale(x)   ((unsigned int)(x)>>6)	//!< mask off bottom 6 bits
#define ds_unscale(x) ((unsigned int)(x)<<6)	//!< leave room for bottom 6 bits

///////////////////////////////////////////////////////////////////////
//
// Variables
//
///////////////////////////////////////////////////////////////////////

//
// don't manipulate directly unless you know what you're doing!
//

extern unsigned char ds_activation;	//!< activation bitmask

#ifdef CONF_DSENSOR_ROTATION
extern unsigned char ds_rotation;	//!< rotation   bitmask

extern volatile int ds_rotations[3];	//!< rotational position

#endif
#ifdef CONF_DSENSOR_VELOCITY
extern volatile int ds_velocities[3];	//!< rotational velocity
#endif

#ifdef CONF_DSENSOR_MUX
extern unsigned char ds_mux;	//!< mux   bitmask

extern volatile int ds_muxs[3][3];	//!< mux ch values
#endif //CONF_DSENSOR_MUX

///////////////////////////////////////////////////////////////////////
//
// Functions
//
///////////////////////////////////////////////////////////////////////

//! set sensor mode to active (light sensor emits light, rotation works)
/*! \param  sensor: &SENSOR_1,&SENSOR_2,&SENSOR_3
*/
extern inline void ds_active(volatile unsigned *sensor)
{
  if (sensor == &SENSOR_3)
    bit_set(&ds_activation, 0);
  else if (sensor == &SENSOR_2)
    bit_set(&ds_activation, 1);
  else if (sensor == &SENSOR_1)
    bit_set(&ds_activation, 2);
}

//! set sensor mode to passive (light sensor detects ambient light)
/*! \param  sensor: &SENSOR_1,&SENSOR_2,&SENSOR_3
*/
extern inline void ds_passive(volatile unsigned *sensor)
{
  if (sensor == &SENSOR_3) {
    bit_clear(&ds_activation, 0);
    bit_clear(&PORT6, 0);
  } else if (sensor == &SENSOR_2) {
    bit_clear(&ds_activation, 1);
    bit_clear(&PORT6, 1);
  }  else if (sensor == &SENSOR_1) {
    bit_clear(&ds_activation, 2);
    bit_clear(&PORT6, 2);
  }
}

#ifdef CONF_DSENSOR_ROTATION
//! set rotation to an absolute value
/*! \param sensor one of &SENSOR_1, &SENSOR_2, or &SENSOR_3
    \param  pos the current rotational postion (typically use 0 here)
	\return Nothing

    The axis should be inert during the function call.
*/
extern void ds_rotation_set(volatile unsigned *sensor, int pos);

//! start tracking rotation sensor
/*! \param  sensor: &SENSOR_1,&SENSOR_2,&SENSOR_3
*/
extern inline void ds_rotation_on(volatile unsigned *sensor)
{
  if (sensor == &SENSOR_3)
    bit_set(&ds_rotation, 0);
  else if (sensor == &SENSOR_2)
    bit_set(&ds_rotation, 1);
  else if (sensor == &SENSOR_1)
    bit_set(&ds_rotation, 2);
}

//! stop tracking rotation sensor
/*! \param  sensor: &SENSOR_1,&SENSOR_2,&SENSOR_3
*/
extern inline void ds_rotation_off(volatile unsigned *sensor)
{
  if (sensor == &SENSOR_3)
    bit_clear(&ds_rotation, 0);
  else if (sensor == &SENSOR_2)
    bit_clear(&ds_rotation, 1);
  else if (sensor == &SENSOR_1)
    bit_clear(&ds_rotation, 2);
}
#endif // CONF_DSENSOR_ROTATION


#ifdef CONF_DSENSOR_MUX

#define DS_MUX_POST_SWITCH 150
//! start multiplexing
/*! \param  sensor: &SENSOR_1,&SENSOR_2,&SENSOR_3
    \param  ch1: indicates if ch1 is to be scanned
    \param  ch2: indicates if ch2 is to be scanned
    \param  ch3: indicates if ch3 is to be scanned
    ch1-ch3 also indicates how long to wait after switching
    to a channel before reading from it.
    DS_MUX_POST_SWITCH defines a good default, but some sensors
    require more time, others may work with less.
    specifying 0 will keep the port from being switched to
    or read
*/
extern void ds_mux_on(volatile unsigned *sensor,
		      unsigned int ch1,
		      unsigned int ch2,
		      unsigned int ch3);


//! stop multiplexing
/*! \param  sensor: &SENSOR_1,&SENSOR_2,&SENSOR_3
*/
extern inline void ds_mux_off(volatile unsigned *sensor)
{
  if (sensor == &SENSOR_3)
    bit_clear(&ds_mux, 0);
  else if (sensor == &SENSOR_2)
    bit_clear(&ds_mux, 1);
  else if (sensor == &SENSOR_1)
    bit_clear(&ds_mux, 2);
}//endof ds_mux_off
#endif // CONF_DSENSOR_MUX





#endif // CONF_DSENSOR

#ifdef  __cplusplus
}
#endif

#endif // __dsensor_h__