Browse code

Make accelerometer work, interrup driven tilt change mode

Nils Faerber authored on 05/05/2013 21:22:33
Showing 11 changed files
... ...
@@ -1,12 +1,87 @@
1 1
 #include <msp430.h>
2 2
 #include <msp430xgeneric.h>
3 3
 #include <stdint.h>
4
+#include <stdio.h>
4 5
 
5 6
 #include "mw_main.h"
7
+#include "mw_uart.h"
6 8
 
7 9
 #include "mw_acc.h"
8 10
 
9
-void mw_init_acc_i2c(void)
11
+#include "oswald_main.h"
12
+
13
+#define ACCEL_STATE_DISABLED		0x00
14
+#define ACCEL_STATE_ENABLED		0x01
15
+
16
+static uint8_t AccelState;
17
+static uint8_t AccelerometerBusy;
18
+static uint8_t LengthCount;
19
+static uint8_t Index;
20
+static uint8_t *pAccelerometerData;
21
+
22
+/*
23
+ * Accelerometer is a Kionix KXTF9-4100 connected to I2C
24
+ * I2C is pretty slow so reading and writing should be done non blocking
25
+ * using interrupts.
26
+ */
27
+
28
+#define ACCELEROMETER_NO_INTERRUPTS	0x00
29
+#define ACCELEROMETER_ALIFG		0x02
30
+#define ACCELEROMETER_NACKIFG		0x04
31
+#define ACCELEROMETER_STTIFG		0x06
32
+#define ACCELEROMETER_STPIFG		0x08
33
+#define ACCELEROMETER_RXIFG		0x0a
34
+#define ACCELEROMETER_TXIFG		0x0c
35
+
36
+#pragma vector=USCI_B1_VECTOR
37
+__interrupt void ACCERLEROMETER_I2C_ISR(void)
38
+{
39
+	// debug_uart_tx("ACC i2c irq\n");
40
+	switch (USCI_ACCELEROMETER_IV) {
41
+		case ACCELEROMETER_NO_INTERRUPTS: 
42
+			break;
43
+		case ACCELEROMETER_ALIFG: 
44
+			break;
45
+		case ACCELEROMETER_NACKIFG:
46
+			nop();
47
+			break; 
48
+		case ACCELEROMETER_STTIFG:
49
+			nop();
50
+			break; 
51
+		case ACCELEROMETER_STPIFG: 
52
+			break;
53
+		case ACCELEROMETER_RXIFG:
54
+			if (LengthCount > 0) {
55
+				pAccelerometerData[Index++] = ACCELEROMETER_RXBUF;
56
+				LengthCount--;
57
+				if ( LengthCount == 1 ) {
58
+					/* All but one byte received. Send stop */
59
+					ACCELEROMETER_CTL1 |= UCTXSTP;
60
+				} else if ( LengthCount == 0 ) {
61
+					/* Last byte received; disable rx interrupt */
62
+					ACCELEROMETER_IE &= ~UCRXIE;
63
+					AccelerometerBusy = 0;
64
+				}
65
+			}
66
+			break;
67
+		case ACCELEROMETER_TXIFG:
68
+			if ( LengthCount > 0 ) {
69
+				ACCELEROMETER_TXBUF = pAccelerometerData[Index++];
70
+				LengthCount--;
71
+			} else {
72
+				/* disable transmit interrupt and send stop */
73
+				ACCELEROMETER_IE &= ~UCTXIE;
74
+				ACCELEROMETER_CTL1 |= UCTXSTP;
75
+				AccelerometerBusy = 0;
76
+			}
77
+			break;
78
+		default:
79
+			break;
80
+	}
81
+
82
+}
83
+
84
+void mw_acc_init_i2c(void)
10 85
 {
11 86
 	/* enable reset before configuration */
12 87
 	ACCELEROMETER_CTL1 |= UCSWRST;
... ...
@@ -23,49 +98,307 @@ void mw_init_acc_i2c(void)
23 98
 	ACCELEROMETER_CTL1 &= ~UCSWRST;
24 99
 }
25 100
 
26
-/*
27
- * DMA2 = SPI for LCD
28
- */
29
-static void mw_acc_i2c_write_byte(uint8_t byte)
101
+void mw_acc_disable_i2c(void)
30 102
 {
31
-	ACCELEROMETER_TXBUF = byte;
32
-	while ((ACCELEROMETER_CTL1 & ACCELEROMETER_IFG) == 0)
33
-		nop();
103
+	/* enable reset to hold it */
104
+	ACCELEROMETER_CTL1 |= UCSWRST;
34 105
 }
35 106
 
36
-/* OK this is polling write, but data is small and 400kHz I2C, it should "just work" :) */
37
-void mw_acc_i2c_write(const uint8_t addr, const void *data, const uint8_t len)
107
+void mw_acc_i2c_write(uint8_t RegisterAddress, uint8_t *pData, uint8_t Length)
38 108
 {
39
-	int i;
40
-
41
-	if (len == 0) {
109
+	if (Length == 0 || pData == 0)
42 110
 		return;  
43
-	}
44 111
   
45 112
 	while (UCB1STAT & UCBBUSY)
46 113
 		nop();
47 114
   
115
+	AccelerometerBusy = 1;
116
+	LengthCount = Length;
117
+	Index = 0;
118
+	pAccelerometerData = pData;
119
+  
48 120
 	/* 
121
+	 * enable transmit interrupt and 
49 122
 	 * setup for write and send the start condition
50 123
 	 */
51 124
 	ACCELEROMETER_IFG = 0;
52 125
 	ACCELEROMETER_CTL1 |= UCTR + UCTXSTT;
53
-	while (!(ACCELEROMETER_IFG & UCTXIFG))
126
+	while(!(ACCELEROMETER_IFG & UCTXIFG))
54 127
 		nop();
55 128
   
56 129
 	/* 
57
-	 * clear transmit interrupt flag,
130
+	 * clear transmit interrupt flag, enable interrupt, 
58 131
 	 * send the register address
59 132
 	 */
60 133
 	ACCELEROMETER_IFG = 0;
134
+	ACCELEROMETER_IE |= UCTXIE;
135
+	ACCELEROMETER_TXBUF = RegisterAddress;
61 136
 
62
-	mw_acc_i2c_write_byte(addr);
137
+	while (AccelerometerBusy)
138
+		nop();
139
+
140
+	while (ACCELEROMETER_CTL1 & UCTXSTP)
141
+		nop();
63 142
 
64
-	for (i=0; i<len; i++)
65
-		mw_acc_i2c_write_byte(*(uint8_t *)(data+i));
143
+	/* the rest of TX will be handled by the ISR */
144
+}
66 145
 
146
+void mw_acc_i2c_read_single(const uint8_t RegisterAddress, const uint8_t *pData)
147
+{
148
+	if ( pData == 0 )
149
+		return;
150
+  
151
+	/* wait for bus to be free */
152
+	while (UCB1STAT & UCBBUSY)
153
+		nop();
154
+  
155
+	AccelerometerBusy = 1;
156
+	LengthCount = 1;
157
+	Index = 0;
158
+	pAccelerometerData = (uint8_t *)pData;
159
+
160
+	/* transmit address */
161
+	ACCELEROMETER_IFG = 0;
162
+	ACCELEROMETER_CTL1 |= UCTR + UCTXSTT;
163
+	while (!(ACCELEROMETER_IFG & UCTXIFG))
164
+		nop();
165
+  
166
+	/* write register address */
167
+	ACCELEROMETER_IFG = 0;
168
+	ACCELEROMETER_TXBUF = RegisterAddress;
169
+	while (!(ACCELEROMETER_IFG & UCTXIFG))
170
+		nop();
171
+
172
+	/* send a repeated start (same slave address now it is a read command) 
173
+	 * read possible extra character from rxbuffer
174
+	 */
175
+	ACCELEROMETER_RXBUF;
176
+	ACCELEROMETER_IFG = 0;
177
+	ACCELEROMETER_IE |= UCRXIE;
178
+	ACCELEROMETER_CTL1 &= ~UCTR;
179
+	/* for a read of a single byte the stop must be sent while the byte is being 
180
+	 * received. If this is interrupted an extra byte may be read.
181
+	 * however, it will be discarded during the next read
182
+	 */
183
+	if ( LengthCount == 1 ) {
184
+		/* errata usci30: prevent interruption of sending stop 
185
+		 * so that only one byte is read
186
+		 * this requires 62 us @ 320 kHz, 51 @ 400 kHz
187
+		 */
188
+		ACCELEROMETER_CTL1 |= UCTXSTT;
189
+  
190
+		while(ACCELEROMETER_CTL1 & UCTXSTT)
191
+			nop();
192
+
193
+		ACCELEROMETER_CTL1 |= UCTXSTP;
194
+	} else {
195
+		ACCELEROMETER_CTL1 |= UCTXSTT;
196
+	}
197
+  
198
+	/* wait until all data has been received and the stop bit has been sent */
199
+	while (AccelerometerBusy)
200
+		nop();
67 201
 	while (ACCELEROMETER_CTL1 & UCTXSTP)
68 202
 		nop();
203
+	Index = 0;
204
+	pAccelerometerData = 0;
69 205
 }
70 206
 
207
+/* errata usci30: only perform single reads 
208
+ * second solution: use DMA
209
+ */
210
+void mw_acc_i2c_read(const uint8_t RegisterAddress, uint8_t *pData, const uint8_t Length)
211
+{
212
+	int i;
213
+
214
+	for ( i = 0; i < Length; i++ ) {
215
+		mw_acc_i2c_read_single(RegisterAddress + i, (pData + i));
216
+	}
217
+}
218
+
219
+
220
+void mw_acc_init(void)
221
+{
222
+	uint8_t WriteRegisterData;
223
+	uint8_t pReadRegisterData[4];
224
+#if defined MW_DEVBOARD_V2
225
+	char tstr[16];
226
+#endif
227
+
228
+	ENABLE_ACCELEROMETER_POWER();
229
+
230
+	mw_acc_init_i2c();
231
+
232
+	/*
233
+	 * make sure part is in standby mode because some registers can only
234
+	 * be changed when the part is not active.
235
+	 */
236
+	WriteRegisterData = PC1_STANDBY_MODE;
237
+	mw_acc_i2c_write(KIONIX_CTRL_REG1, &WriteRegisterData, 1);
238
+
239
+	/* enable face-up and face-down detection */
240
+	WriteRegisterData = TILT_FDM | TILT_FUM;
241
+	mw_acc_i2c_write(KIONIX_CTRL_REG2, &WriteRegisterData, 1);
242
+    
243
+	/* 
244
+	 * the interrupt from the accelerometer can be used to get periodic data
245
+	 * the real time clock can also be used
246
+	 */
247
+  
248
+	/* change to output data rate to 25 Hz */
249
+	WriteRegisterData = WUF_ODR_25HZ | TAP_ODR_400HZ;
250
+	mw_acc_i2c_write(KIONIX_CTRL_REG3, &WriteRegisterData, 1);
251
+  
252
+	/* enable interrupt and make it active high */
253
+	WriteRegisterData = IEN | IEA;
254
+	mw_acc_i2c_write(KIONIX_INT_CTRL_REG1, &WriteRegisterData, 1);
255
+  
256
+	/* enable motion detection interrupt for all three axis */
257
+	WriteRegisterData = XBW | YBW | ZBW;
258
+	mw_acc_i2c_write(KIONIX_INT_CTRL_REG2, &WriteRegisterData, 1);
259
+
260
+	/* enable tap interrupt for Z-axis */
261
+	WriteRegisterData = TFDM;
262
+	mw_acc_i2c_write(KIONIX_INT_CTRL_REG3, &WriteRegisterData, 1);
263
+  
264
+	/* set TDT_TIMER to 0.2 secs*/
265
+	WriteRegisterData = 0x50;
266
+	mw_acc_i2c_write(KIONIX_TDT_TIMER, &WriteRegisterData, 1);
267
+  
268
+	/* set tap low and high thresholds (default: 26 and 182) */
269
+	WriteRegisterData = 40; //78;
270
+	mw_acc_i2c_write(KIONIX_TDT_L_THRESH, &WriteRegisterData, 1);
271
+	WriteRegisterData = 128;
272
+	mw_acc_i2c_write(KIONIX_TDT_H_THRESH, &WriteRegisterData, 1);
273
+    
274
+	/* set WUF_TIMER counter */
275
+	WriteRegisterData = 10;
276
+	mw_acc_i2c_write(KIONIX_WUF_TIMER, &WriteRegisterData, 1);
277
+    
278
+	/* this causes data to always be sent */
279
+	// WriteRegisterData = 0x00;
280
+	WriteRegisterData = 0x02 /*0x08*/;
281
+	mw_acc_i2c_write(KIONIX_WUF_THRESH, &WriteRegisterData, 1);
282
+     
283
+	/* single byte read test */
284
+	mw_acc_i2c_read(KIONIX_DCST_RESP, pReadRegisterData, 1);
285
+#if defined MW_DEVBOARD_V2
286
+	snprintf(tstr, 16, "acc DCST 0x%02x\n", pReadRegisterData[0]);
287
+	debug_uart_tx(tstr);
288
+#endif
289
+  
290
+	/* multiple byte read test */
291
+	mw_acc_i2c_read(KIONIX_WHO_AM_I, pReadRegisterData, 2);
292
+#if defined MW_DEVBOARD_V2
293
+	snprintf(tstr, 16, "acc is 0x%02x 0x%02x\n", pReadRegisterData[0], pReadRegisterData[1]);
294
+	debug_uart_tx(tstr);
295
+#endif
296
+
297
+	/* 
298
+	 * KIONIX_CTRL_REG3 and DATA_CTRL_REG can remain at their default values 
299
+	 *
300
+	 * 50 Hz
301
+	 */
302
+#if 0  
303
+	/* KTXF9 300 uA; KTXI9 165 uA */
304
+	WriteRegisterData = PC1_OPERATING_MODE | TAP_ENABLE_TDTE;
305
+  
306
+	/* 180 uA; KTXI9 115 uA */
307
+	WriteRegisterData = PC1_OPERATING_MODE | RESOLUTION_8BIT | WUF_ENABLE;
308
+
309
+	/* 180 uA; KTXI9 8.7 uA */
310
+	WriteRegisterData = PC1_OPERATING_MODE | TILT_ENABLE_TPE;
311
+
312
+	/* 720 uA; KTXI9 330 uA */  
313
+	WriteRegisterData = PC1_OPERATING_MODE | RESOLUTION_12BIT | WUF_ENABLE;
314
+#endif
315
+  
316
+	/* setup the default for the AccelerometerEnable command */
317
+#if 0
318
+	OperatingModeRegister = PC1_OPERATING_MODE | RESOLUTION_12BIT | TAP_ENABLE_TDTE | TILT_ENABLE_TPE; // | WUF_ENABLE;
319
+	InterruptControl = INTERRUPT_CONTROL_DISABLE_INTERRUPT;
320
+	SidControl = SID_CONTROL_SEND_DATA;
321
+	SidAddr = KIONIX_XOUT_L;
322
+	SidLength = XYZ_DATA_LENGTH;  
323
+
324
+	AccelState = ACCEL_STATE_INIT;
325
+#endif
326
+}
327
+
328
+void mw_acc_enable(void)
329
+{
330
+	uint8_t sdata;
331
+
332
+	mw_acc_init();
333
+
334
+	sdata = PC1_OPERATING_MODE | RESOLUTION_12BIT | TAP_ENABLE_TDTE | TILT_ENABLE_TPE | WUF_ENABLE;
335
+	//sdata = PC1_OPERATING_MODE | RESOLUTION_8BIT | TAP_ENABLE_TDTE | TILT_ENABLE_TPE; // | WUF_ENABLE;
336
+	mw_acc_i2c_write(KIONIX_CTRL_REG1, &sdata, 1);
337
+  
338
+	ACCELEROMETER_INT_ENABLE();
339
+	mw_acc_i2c_read(KIONIX_INT_REL, &sdata, 1);
340
+	AccelState = ACCEL_STATE_ENABLED;
341
+}
342
+
343
+void mw_acc_disable(void)
344
+{
345
+	uint8_t sdata;
346
+
347
+	if (AccelState == ACCEL_STATE_ENABLED) {
348
+		sdata = PC1_STANDBY_MODE;
349
+		mw_acc_i2c_write(KIONIX_CTRL_REG1, &sdata, 1);
350
+
351
+		ACCELEROMETER_INT_DISABLE();
352
+		mw_acc_disable_i2c();
353
+		DISABLE_ACCELEROMETER_POWER();
354
+		AccelState = ACCEL_STATE_DISABLED;
355
+	}
356
+}
357
+
358
+void mw_acc_read(int16_t *x, int16_t *y, int16_t *z)
359
+{
360
+	uint8_t rdata[6];
361
+
362
+	if (AccelState == ACCEL_STATE_ENABLED) {
363
+		mw_acc_i2c_read(KIONIX_XOUT_L, rdata, 6);
364
+
365
+		*x = rdata[0] | (rdata[1] << 8);
366
+		*y = rdata[2] | (rdata[3] << 8);
367
+		*z = rdata[4] | (rdata[5] << 8);
368
+	} else {
369
+		*x = 0;
370
+		*y = 0;
371
+		*z = 0;
372
+	}
373
+}
374
+
375
+void mw_acc_handle_irq(void)
376
+{
377
+	uint8_t sdata, srcreg1, srcreg2;
378
+#if defined MW_DEVBOARD_V2
379
+	char tstr[16];
380
+#endif
381
+
382
+	mw_acc_i2c_read(KIONIX_INT_SRC_REG1, &srcreg1, 1);
383
+#if defined MW_DEVBOARD_V2
384
+	snprintf(tstr, 16, "accsrc1: 0x%02x\n", srcreg1);
385
+	debug_uart_tx(tstr);
386
+#endif
387
+	mw_acc_i2c_read(KIONIX_INT_SRC_REG2, &srcreg2, 1);
388
+#if defined MW_DEVBOARD_V2
389
+	snprintf(tstr, 16, "accsrc2: 0x%02x\n", srcreg2);
390
+	debug_uart_tx(tstr);
391
+#endif
392
+	if (srcreg1 & INT_TAP_SINGLE) {
393
+	};
394
+	if (srcreg1 & INT_TAP_DOUBLE) {
395
+	};
396
+	if (srcreg2 & INT_WUFS) {
397
+		int16_t x, y, z;
398
+		mw_acc_read(&x, &y, &z);
399
+		oswald_handle_accel_event((int8_t)(x / (32768 / 255)), (int8_t)(y / (32768 / 255)), (int8_t)(z / (32768 / 255)));
400
+	}
401
+
402
+	mw_acc_i2c_read(KIONIX_INT_REL, &sdata, 1);
403
+}
71 404
 
... ...
@@ -99,11 +99,22 @@
99 99
 #define TFUM (1 << 0)
100 100
 
101 101
 /* INT_SRC_REG2 */
102
-#define INT_TAP_SINGLE (0x04)
103
-#define INT_TAP_DOUBLE (0x08)
102
+#define INT_TPS		0x01
103
+#define INT_WUFS	0x02
104
+#define INT_TAP_SINGLE	0x04
105
+#define INT_TAP_DOUBLE	0x08
106
+#define INT_DRDY	0x10
104 107
 
105
-/* for readability */
106
-#define ONE_BYTE ( 1 )
107 108
 
108
-#endif
109
+void mw_acc_init_i2c(void);
110
+void mw_acc_disable_i2c(void);
111
+void mw_acc_i2c_read(const uint8_t RegisterAddress, uint8_t *pData, const uint8_t Length);
112
+void mw_acc_i2c_write(uint8_t RegisterAddress, uint8_t *pData, uint8_t Length);
113
+
114
+void mw_acc_init(void);
115
+void mw_acc_enable(void);
116
+void mw_acc_disable(void);
117
+void mw_acc_read(int16_t *x, int16_t *y, int16_t *z);
118
+void mw_acc_handle_irq(void);
109 119
 
120
+#endif
... ...
@@ -188,17 +188,6 @@ void mw_enable_bt(void)
188 188
 	mw_bt_enabled = 1;
189 189
 }
190 190
 
191
-#pragma vector=PORT1_VECTOR
192
-__interrupt void BT_CTS_ISR (void)
193
-{
194
-	P1IFG &= ~BT_IO_CTS;
195
-
196
-	debug_uart_tx("BTS CTS triggered\n");
197
-	bt_hci_ehcill_wake();
198
-
199
-	LPM3_EXIT;
200
-}
201
-
202 191
 void mw_disable_bt(void)
203 192
 {
204 193
 	mw_bt_enabled = 0;
... ...
@@ -10,6 +10,7 @@
10 10
 #include "mw_bt.h"
11 11
 #include "mw_adc.h"
12 12
 #include "mw_bt.h"
13
+#include "mw_acc.h"
13 14
 #include "bt_hci.h"
14 15
 #include "bt_l2cap.h"
15 16
 
... ...
@@ -18,7 +19,7 @@
18 19
 
19 20
 #include "bluetooth_init_cc256x.h"
20 21
 
21
-unsigned int _event_src = 0;
22
+uint16_t _event_src = 0;
22 23
 
23 24
 
24 25
 static void set16mhz(void)
... ...
@@ -111,7 +112,7 @@ static void setup_pins(void)
111 112
 	DISABLE_LCD_LED();		// frontlight
112 113
 	CONFIG_DEBUG_PINS();
113 114
 	CONFIG_ACCELEROMETER_PINS();
114
-	// DISABLE_ACCELEROMETER_POWER(); // there is no accel. power switching!
115
+	DISABLE_ACCELEROMETER_POWER(); // starts from config 5 and later
115 116
 
116 117
 	HARDWARE_CFG_SENSE_INIT();
117 118
 
... ...
@@ -324,7 +325,19 @@ static void handle_uart_rx_event(void)
324 325
 
325 326
 	if (debug_uart_rx_char(&c)) {
326 327
 		debug_uart_tx_char(c);
327
-		if (c == 'b') {
328
+		if (c == 'a') {
329
+			debug_uart_tx("\nenabling ACC\n");
330
+			mw_acc_enable();
331
+		} else if (c == 'A') {
332
+			debug_uart_tx("\ndisabling ACC\n");
333
+			mw_acc_disable();
334
+		} else if (c == 'r') {
335
+			int16_t x,y,z;
336
+			debug_uart_tx("\nread ACC: ");
337
+			mw_acc_read(&x, &y, &z);
338
+			snprintf(tstr, 64, "x:%d y:%d z:%d\n", x,y,z);
339
+			debug_uart_tx(tstr);
340
+		} else if (c == 'b') {
328 341
 			debug_uart_tx("\nenabling BT\n");
329 342
 			mw_enable_bt();
330 343
 		} else if (c == 'B') {
... ...
@@ -484,6 +497,9 @@ uint8_t handle_event(void)
484 497
 		} else if (_event_src & TIMER_100MS_EVENT) {
485 498
 			_event_src &= ~TIMER_100MS_EVENT;
486 499
 			oswald_centisecond_tick();
500
+		} else if (_event_src & ACCEL_EVENT) {
501
+			_event_src &= ~ACCEL_EVENT;
502
+			mw_acc_handle_irq();
487 503
 		} else {
488 504
 #if defined MW_DEVBOARD_V2
489 505
 			snprintf(tstr, 64, "unhandled event in 0x%04x\n", _event_src);
... ...
@@ -504,6 +520,26 @@ __interrupt void BUTTON_ISR (void)
504 520
 	LPM3_EXIT;
505 521
 }
506 522
 
523
+#pragma vector=PORT1_VECTOR
524
+__interrupt void PORT1_GPIO_ISR (void)
525
+{
526
+	if (P1IFG & BT_IO_CTS) {
527
+		P1IFG &= ~BT_IO_CTS;
528
+
529
+		debug_uart_tx("BT CTS irq\n");
530
+		bt_hci_ehcill_wake();
531
+
532
+		LPM3_EXIT;
533
+	};
534
+	if (P1IFG & ACCELEROMETER_INT_PIN) {
535
+		P1IFG &= ~ACCELEROMETER_INT_PIN;
536
+		// debug_uart_tx("ACC irq\n");
537
+		_event_src |= ACCEL_EVENT;
538
+		LPM3_EXIT;
539
+	}
540
+}
541
+
542
+
507 543
 #if 0
508 544
 #pragma vector=NOVECTOR
509 545
 __interrupt void UNEXP_ISR (void)
... ...
@@ -21,6 +21,7 @@
21 21
 #define TIMER_100MS_EVENT	1 << 5
22 22
 #define POWER_SRC_EVENT		1 << 6
23 23
 #define BT_UART_RCV_EVENT	1 << 7
24
+#define ACCEL_EVENT		1 << 8
24 25
 
25 26
 extern unsigned int _event_src;
26 27
 
... ...
@@ -14,6 +14,7 @@
14 14
 #include "bt_hci.h"
15 15
 #include "bt_l2cap.h"
16 16
 #include "bluetooth_init_cc256x.h"
17
+#include "mw_acc.h"
17 18
 
18 19
 #include "oswald.h"
19 20
 #include "oswald_hal.h"
... ...
@@ -249,3 +250,17 @@ void hal_bluetooth_send_data(const void *mdat, uint16_t mlen)
249 250
 	bt_l2cap_send_channel(0x40, mdat, mlen);
250 251
 }
251 252
 
253
+/*
254
+ * Control the accelerometer
255
+ */
256
+void hal_accelerometer_enable(void)
257
+{
258
+	mw_acc_enable();
259
+}
260
+
261
+void hal_accelerometer_disable(void)
262
+{
263
+	mw_acc_disable();
264
+}
265
+
266
+
... ...
@@ -4,9 +4,10 @@
4 4
 
5 5
 unsigned char is_leap(const unsigned int year)
6 6
 {
7
-  // Die Regel lautet: Alles, was durch 4 teilbar ist, ist ein Schaltjahr.
8
-  // Es sei denn, das Jahr ist durch 100 teilbar, dann ist es keins.
9
-  // Aber wenn es durch 400 teilbar ist, ist es doch wieder eins.
7
+	/* the rule is, everything that can be devided by 4 is leap.
8
+	 * Exception: the year can be devided by 100, then it is not,
9
+	 * except it canbe devided by 400, then it is again.
10
+	 */
10 11
 
11 12
 	if ((year % 400) == 0)
12 13
 		return 1;
... ...
@@ -20,11 +21,11 @@ unsigned char is_leap(const unsigned int year)
20 21
 
21 22
 unsigned short days_of_month(const unsigned int uMonat, const unsigned int uJahr)
22 23
 {
23
-	//                     ungült,Jan,Feb,Mrz,Apr,Mai,Jun,Jul,Aug,Sep,Okt,Nov,Dez
24
+	// invalid,January,Febuary,March,April,May,June,July,August,September,October,November,December
24 25
 	int arrTageImMonat[13] = {  0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
25 26
 
26 27
 	if (uMonat == 2) {
27
-		// Februar: Schaltjahr unterscheiden
28
+		// Febuary: distinguish leap
28 29
 		if (is_leap(uJahr))
29 30
 			return 29;
30 31
 		else
... ...
@@ -109,6 +109,22 @@ const char *hal_get_radio_version_string(void)
109 109
 	return "BlueZ";
110 110
 }
111 111
 
112
+void hal_accelerometer_enable(void)
113
+{
114
+	g_printerr("accel enable\n");
115
+	gtk_widget_set_sensitive(ui_g->x_sc, TRUE);
116
+	gtk_widget_set_sensitive(ui_g->y_sc, TRUE);
117
+	gtk_widget_set_sensitive(ui_g->z_sc, TRUE);
118
+}
119
+
120
+void hal_accelerometer_disable(void)
121
+{
122
+	g_printerr("accel enable\n");
123
+	gtk_widget_set_sensitive(ui_g->x_sc, FALSE);
124
+	gtk_widget_set_sensitive(ui_g->y_sc, FALSE);
125
+	gtk_widget_set_sensitive(ui_g->z_sc, FALSE);
126
+}
127
+
112 128
 
113 129
 static gint
114 130
 configure_event (GtkWidget *widget, GdkEventConfigure *event, gpointer user_data)
... ...
@@ -330,18 +346,24 @@ static void create_mainwin(oswald_ui *ui)
330 346
 	sc = gtk_hscale_new_with_range (-128, 127, 1);
331 347
 	gtk_box_pack_start (GTK_BOX(hb), sc, TRUE, TRUE, 5);
332 348
 	g_signal_connect(G_OBJECT(sc), "value-changed", G_CALLBACK(accelX_value_changed), ui);
349
+	ui->x_sc = sc;
350
+	gtk_widget_set_sensitive(ui->x_sc, FALSE);
333 351
 
334 352
 	l = gtk_label_new("Y:");
335 353
 	gtk_box_pack_start (GTK_BOX(hb), l, FALSE, FALSE, 5);
336 354
 	sc = gtk_hscale_new_with_range (-128, 127, 1);
337 355
 	gtk_box_pack_start (GTK_BOX(hb), sc, TRUE, TRUE, 5);
338 356
 	g_signal_connect(G_OBJECT(sc), "value-changed", G_CALLBACK(accelY_value_changed), ui);
357
+	ui->y_sc = sc;
358
+	gtk_widget_set_sensitive(ui->y_sc, FALSE);
339 359
 
340 360
 	l = gtk_label_new("Z:");
341 361
 	gtk_box_pack_start (GTK_BOX(hb), l, FALSE, FALSE, 5);
342 362
 	sc = gtk_hscale_new_with_range (-128, 127, 1);
343 363
 	gtk_box_pack_start (GTK_BOX(hb), sc, TRUE, TRUE, 5);
344 364
 	g_signal_connect(G_OBJECT(sc), "value-changed", G_CALLBACK(accelZ_value_changed), ui);
365
+	ui->z_sc = sc;
366
+	gtk_widget_set_sensitive(ui->z_sc, FALSE);
345 367
 
346 368
 	gtk_widget_show_all(ui->mainwin);
347 369
 }
... ...
@@ -9,6 +9,9 @@ typedef struct {
9 9
 	GtkWidget *mainwin;
10 10
 	GtkWidget *darea;
11 11
 	GdkPixmap *pixmap;
12
+	GtkWidget *x_sc;
13
+	GtkWidget *y_sc;
14
+	GtkWidget *z_sc;
12 15
 	uint8_t accel_x;
13 16
 	uint8_t accel_y;
14 17
 	uint8_t accel_z;
... ...
@@ -36,5 +36,9 @@ uint8_t *hal_bluetooth_get_local_bdaddr(void);
36 36
 void hal_bluetooth_set_visible(boolean visible);
37 37
 boolean hal_bluetooth_get_visible(void);
38 38
 void hal_bluetooth_send_data(const void *mdat, uint16_t mlen);
39
+
40
+void hal_accelerometer_enable(void);
41
+void hal_accelerometer_disable(void);
42
+
39 43
 #endif
40 44
 
... ...
@@ -143,6 +143,8 @@ static accelscreen_data_t accel_screen = {
143 143
 
144 144
 void draw_accel_screen(accel_data_t *accel_data)
145 145
 {
146
+	uint8_t x,y;
147
+
146 148
 	hal_lcd_clear_display();
147 149
 
148 150
 	oswald_draw_bitmap(36, 0, acc_icon_width, acc_icon_height, acc_icon_bits);
... ...
@@ -162,7 +164,13 @@ void draw_accel_screen(accel_data_t *accel_data)
162 164
 	oswald_draw_line(40, 82, 92, 82);
163 165
 	oswald_draw_line(40, 82, 40, 30);
164 166
 
165
-	oswald_draw_pixel(41+25+((accel_data->x * 50) / (254)), 31+25+((accel_data->y * 50) / (254)));
167
+	x = 41+25+((accel_data->x * 50) / (254));
168
+	y = 31+25+((accel_data->y * 50) / (254));
169
+	oswald_draw_pixel(x, y);
170
+	oswald_draw_pixel(x+1, y);
171
+	oswald_draw_pixel(x-1, y);
172
+	oswald_draw_pixel(x, y+1);
173
+	oswald_draw_pixel(x, y-1);
166 174
 
167 175
 	hal_lcd_update_display();
168 176
 }
... ...
@@ -172,6 +180,11 @@ event_ret_t accel_handle_events(uint16_t event, void *data)
172 180
 	switch (event) {
173 181
 		case EVENT_SCREEN_VISIBLE:
174 182
 			draw_accel_screen(&accel_screen.accdata);
183
+			hal_accelerometer_enable();
184
+			return EVENT_RET_HANDLED;
185
+			break;
186
+		case EVENT_SCREEN_DESTROY:
187
+			hal_accelerometer_disable();
175 188
 			return EVENT_RET_HANDLED;
176 189
 			break;
177 190
 		case EVENT_ACCEL_UPDATE: {