Browse code

Use strutils instead of snprintf (to save some bytes), set default year to 2014, partial revamp of the stopwatch

Dario Rodriguez authored on 14/01/2014 22:59:59
Showing 1 changed files
... ...
@@ -299,15 +299,22 @@ void mw_acc_init(void)
299 299
 	/* single byte read test */
300 300
 	mw_acc_i2c_read(KIONIX_DCST_RESP, pReadRegisterData, 1);
301 301
 #if defined MW_DEVBOARD_V2
302
-	snprintf(tstr, 16, "acc DCST 0x%02x\n", pReadRegisterData[0]);
302
+	debug_uart_tx("acc DCST 0x");
303
+	hexnum2str(pReadRegisterData[0],tstr,2);
303 304
 	debug_uart_tx(tstr);
305
+	debug_uart_tx("\n");
304 306
 #endif
305 307
   
306 308
 	/* multiple byte read test */
307 309
 	mw_acc_i2c_read(KIONIX_WHO_AM_I, pReadRegisterData, 2);
308 310
 #if defined MW_DEVBOARD_V2
309
-	snprintf(tstr, 16, "acc is 0x%02x 0x%02x\n", pReadRegisterData[0], pReadRegisterData[1]);
311
+	debug_uart_tx("acc is 0x");
312
+	hexnum2str(pReadRegisterData[0],tstr,2);
310 313
 	debug_uart_tx(tstr);
314
+	debug_uart_tx(" 0x");
315
+	hexnum2str(pReadRegisterData[1],tstr,2);
316
+	debug_uart_tx(tstr);
317
+	debug_uart_tx("\n");
311 318
 #endif
312 319
 
313 320
 	/* 
... ...
@@ -400,12 +407,17 @@ void mw_acc_handle_irq(void)
400 407
 
401 408
 	mw_acc_i2c_read(KIONIX_INT_SRC_REG1, &srcreg1, 1);
402 409
 #if defined MW_DEVBOARD_V2
403
-	snprintf(tstr, 16, "accsrc1: 0x%02x\n", srcreg1);
410
+	debug_uart_tx("accsrc1: 0x");
411
+	hexnum2str(srcreg1,tstr,2);
404 412
 	debug_uart_tx(tstr);
413
+	debug_uart_tx("\n");
405 414
 #endif
406 415
 	mw_acc_i2c_read(KIONIX_INT_SRC_REG2, &srcreg2, 1);
407 416
 #if defined MW_DEVBOARD_V2
408
-	snprintf(tstr, 16, "accsrc2: 0x%02x\n", srcreg2);
417
+	debug_uart_tx("accsrc2: 0x");
418
+	hexnum2str(srcreg2,tstr,2);
419
+	debug_uart_tx(tstr);
420
+	debug_uart_tx("\n");
409 421
 	debug_uart_tx(tstr);
410 422
 #endif
411 423
 	if (srcreg1 & INT_TAP_SINGLE) {
Browse code

Power saving changes, add new fonts, bitmaps and screens

Nils Faerber authored on 19/05/2013 00:07:04
Showing 1 changed files
... ...
@@ -49,6 +49,7 @@ __interrupt void ACCERLEROMETER_I2C_ISR(void)
49 49
 			nop();
50 50
 			break; 
51 51
 		case ACCELEROMETER_STPIFG: 
52
+			nop();
52 53
 			break;
53 54
 		case ACCELEROMETER_RXIFG:
54 55
 			if (LengthCount > 0) {
... ...
@@ -106,6 +107,8 @@ void mw_acc_disable_i2c(void)
106 107
 
107 108
 void mw_acc_i2c_write(uint8_t RegisterAddress, uint8_t *pData, uint8_t Length)
108 109
 {
110
+	int tmo;
111
+
109 112
 	if (Length == 0 || pData == 0)
110 113
 		return;  
111 114
   
... ...
@@ -134,8 +137,15 @@ void mw_acc_i2c_write(uint8_t RegisterAddress, uint8_t *pData, uint8_t Length)
134 137
 	ACCELEROMETER_IE |= UCTXIE;
135 138
 	ACCELEROMETER_TXBUF = RegisterAddress;
136 139
 
137
-	while (AccelerometerBusy)
138
-		nop();
140
+	tmo = 0;
141
+	while (AccelerometerBusy) {
142
+		while (tmo++ < 1000)
143
+			__delay_cycles(16000);
144
+		if (tmo >= 1000) {
145
+			debug_uart_tx("ACC I2C tx tmo\n");
146
+			return;
147
+		}
148
+	}
139 149
 
140 150
 	while (ACCELEROMETER_CTL1 & UCTXSTP)
141 151
 		nop();
... ...
@@ -180,17 +190,21 @@ void mw_acc_i2c_read_single(const uint8_t RegisterAddress, const uint8_t *pData)
180 190
 	 * received. If this is interrupted an extra byte may be read.
181 191
 	 * however, it will be discarded during the next read
182 192
 	 */
183
-	if ( LengthCount == 1 ) {
193
+	if (LengthCount == 1) {
184 194
 		/* errata usci30: prevent interruption of sending stop 
185 195
 		 * so that only one byte is read
186 196
 		 * this requires 62 us @ 320 kHz, 51 @ 400 kHz
187 197
 		 */
198
+		__disable_interrupt();
199
+
188 200
 		ACCELEROMETER_CTL1 |= UCTXSTT;
189 201
   
190 202
 		while(ACCELEROMETER_CTL1 & UCTXSTT)
191 203
 			nop();
192 204
 
193 205
 		ACCELEROMETER_CTL1 |= UCTXSTP;
206
+
207
+		__enable_interrupt();
194 208
 	} else {
195 209
 		ACCELEROMETER_CTL1 |= UCTXSTT;
196 210
 	}
... ...
@@ -225,7 +239,9 @@ void mw_acc_init(void)
225 239
 	char tstr[16];
226 240
 #endif
227 241
 
242
+	// it takes at least 20ms to power up
228 243
 	ENABLE_ACCELEROMETER_POWER();
244
+	__delay_cycles(320000);
229 245
 
230 246
 	mw_acc_init_i2c();
231 247
 
... ...
@@ -350,7 +366,7 @@ void mw_acc_disable(void)
350 366
 
351 367
 		ACCELEROMETER_INT_DISABLE();
352 368
 		mw_acc_disable_i2c();
353
-		DISABLE_ACCELEROMETER_POWER();
369
+		/// DISABLE_ACCELEROMETER_POWER();
354 370
 		AccelState = ACCEL_STATE_DISABLED;
355 371
 	}
356 372
 }
Browse code

Maybe a little sniff mode, add ambient light adc (not working), fix accelerometer display orientation

Nils Faerber authored on 06/05/2013 23:39:18
Showing 1 changed files
... ...
@@ -277,7 +277,7 @@ void mw_acc_init(void)
277 277
     
278 278
 	/* this causes data to always be sent */
279 279
 	// WriteRegisterData = 0x00;
280
-	WriteRegisterData = 0x02 /*0x08*/;
280
+	WriteRegisterData = 0x01 /*0x08*/;
281 281
 	mw_acc_i2c_write(KIONIX_WUF_THRESH, &WriteRegisterData, 1);
282 282
      
283 283
 	/* single byte read test */
Browse code

Fix buttom half irq handling if acc is already disabled

Nils Faerber authored on 05/05/2013 22:07:15
Showing 1 changed files
... ...
@@ -379,6 +379,9 @@ void mw_acc_handle_irq(void)
379 379
 	char tstr[16];
380 380
 #endif
381 381
 
382
+	if (AccelState != ACCEL_STATE_ENABLED)
383
+		return;
384
+
382 385
 	mw_acc_i2c_read(KIONIX_INT_SRC_REG1, &srcreg1, 1);
383 386
 #if defined MW_DEVBOARD_V2
384 387
 	snprintf(tstr, 16, "accsrc1: 0x%02x\n", srcreg1);
Browse code

Make accelerometer work, interrup driven tilt change mode

Nils Faerber authored on 05/05/2013 21:22:33
Showing 1 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
 
Browse code

Start support for the accelerometer, change text position for clock setup

Nils Faerber authored on 04/05/2013 22:31:14
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,71 @@
1
+#include <msp430.h>
2
+#include <msp430xgeneric.h>
3
+#include <stdint.h>
4
+
5
+#include "mw_main.h"
6
+
7
+#include "mw_acc.h"
8
+
9
+void mw_init_acc_i2c(void)
10
+{
11
+	/* enable reset before configuration */
12
+	ACCELEROMETER_CTL1 |= UCSWRST;
13
+
14
+	/* configure as master using smclk / 40 = 399.5 kHz */
15
+	ACCELEROMETER_CTL0 = UCMST + UCMODE_3 + UCSYNC;
16
+	ACCELEROMETER_CTL1 = UCSSEL__SMCLK + UCSWRST;
17
+	ACCELEROMETER_BR0 = 42;
18
+
19
+	ACCELEROMETER_BR1 = 0;
20
+	ACCELEROMETER_I2CSA = KIONIX_DEVICE_ADDRESS;
21
+
22
+	/* release reset */
23
+	ACCELEROMETER_CTL1 &= ~UCSWRST;
24
+}
25
+
26
+/*
27
+ * DMA2 = SPI for LCD
28
+ */
29
+static void mw_acc_i2c_write_byte(uint8_t byte)
30
+{
31
+	ACCELEROMETER_TXBUF = byte;
32
+	while ((ACCELEROMETER_CTL1 & ACCELEROMETER_IFG) == 0)
33
+		nop();
34
+}
35
+
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)
38
+{
39
+	int i;
40
+
41
+	if (len == 0) {
42
+		return;  
43
+	}
44
+  
45
+	while (UCB1STAT & UCBBUSY)
46
+		nop();
47
+  
48
+	/* 
49
+	 * setup for write and send the start condition
50
+	 */
51
+	ACCELEROMETER_IFG = 0;
52
+	ACCELEROMETER_CTL1 |= UCTR + UCTXSTT;
53
+	while (!(ACCELEROMETER_IFG & UCTXIFG))
54
+		nop();
55
+  
56
+	/* 
57
+	 * clear transmit interrupt flag,
58
+	 * send the register address
59
+	 */
60
+	ACCELEROMETER_IFG = 0;
61
+
62
+	mw_acc_i2c_write_byte(addr);
63
+
64
+	for (i=0; i<len; i++)
65
+		mw_acc_i2c_write_byte(*(uint8_t *)(data+i));
66
+
67
+	while (ACCELEROMETER_CTL1 & UCTXSTP)
68
+		nop();
69
+}
70
+
71
+