5 #include "TSISensor.h" // Touch Sensor
\r
6 #include "MAG3110.h" // Magnetic Sensor
\r
7 #include "MMA8451Q.h" // AcceleroMeter
\r
9 #include "serial_dma.h" // AcceleroMeter
\r
11 //#include "DataFrame.h"
\r
13 #define CLAMP(x, min, max) \
\r
14 ((x) < (min) ? (min) : \
\r
15 (x) > (max) ? (max) : (x))
\r
17 #define MMA8451_I2C_ADDRESS (0x1d<<1) // acc sensor address
\r
18 #define TIME_ACCURACY 0.0005
\r
20 #define ACC_SNS_DEFAULT 0.01 // default collecting interval in seconds
\r
21 #define MAG_SNS_DEFAULT 0.1
\r
22 #define LGT_SNS_DEFAULT 0.1
\r
23 #define TCH_SNS_DEFAULT 0.1
\r
24 #define A2D_SNS_DEFAULT 0.1
\r
25 #define LED_OUT_DEFAULT 0.5
\r
27 #define MIN_RATE 1E-4 // 1 kHz
\r
28 #define MAX_RATE 10.0 // 0.1 Hz
\r
30 // Common Frame Information
\r
32 #define TAIL 0x0A // '\n'
\r
34 #define MAX_FRAME_SIZE 256
\r
49 TYP_S8, TYP_S16, TYP_S32,
\r
50 TYP_U8, TYP_U16, TYP_U32,
\r
60 // Data Frame Information
\r
73 // Command Frame Information
\r
85 // Define Devices & Pins
\r
86 MMA8451Q accSensor(PTE25, PTE24, MMA8451_I2C_ADDRESS);
\r
87 MAG3110 magSensor(PTE25, PTE24);
\r
88 TSISensor tchSensor;
\r
89 AnalogIn lgtSensor(PTE22);
\r
91 AnalogIn a2dSensor0(A0);
\r
92 AnalogIn a2dSensor1(A1);
\r
93 AnalogIn a2dSensor2(A2);
\r
94 AnalogIn a2dSensor3(A3);
\r
95 AnalogIn a2dSensor4(A4);
\r
96 AnalogIn a2dSensor5(A5);
\r
98 AnalogOut a2dOutput(PTE30);
\r
100 DigitalOut led1(LED1);
\r
101 DigitalOut led2(LED2);
\r
103 Serial serial(USBTX, USBRX);
\r
106 // Global Variables
\r
107 // Initial interval: in seconds
\r
108 float accTmr = ACC_SNS_DEFAULT;
\r
109 float magTmr = MAG_SNS_DEFAULT;
\r
110 float tchTmr = TCH_SNS_DEFAULT;
\r
111 float lgtTmr = LGT_SNS_DEFAULT;
\r
112 float a2dTmr = A2D_SNS_DEFAULT;
\r
113 float ledTmr = LED_OUT_DEFAULT;
\r
115 bool accEnable = false;
\r
116 bool magEnable = false;
\r
117 bool lgtEnable = false;
\r
118 bool tchEnable = false;
\r
119 bool a2dEnable = true;
\r
120 bool ledEnable = true;
\r
122 bool useStr = false;
\r
123 bool useHex = false;
\r
124 bool useBin = true;
\r
126 uint8_t txFrame[MAX_FRAME_SIZE];
\r
127 uint8_t rxFrame[MAX_FRAME_SIZE];
\r
130 void clock1_interrupt(void);
\r
131 void serialRx_interrupt(void);
\r
133 void runCommand(control_t *cmd);
\r
135 void sendAccInfo(void);
\r
136 void sendMagInfo(void);
\r
137 void sendLgtInfo(void);
\r
138 void sendTchInfo(void);
\r
139 void sendA2dInfo(void);
\r
141 int calDataSize(uint8_t);
\r
142 int packToFrame(uint8_t *frame, sns_t snsType, type_t dataType, int dataNum, void *data);
\r
144 void printStr(const char *str, ...);
\r
145 void printHex(uint8_t *frame, int len);
\r
146 void printBin(uint8_t *frame, int len);
\r
154 // Interruption Declarations
\r
155 //clock1.attach(&clock1_interrupt, TIME_ACCURACY); // maximun accuracy be 0.1s
\r
156 serial.attach(&serialRx_interrupt, Serial::RxIrq); // receive interrupt for serialS
\r
157 //serial.baud(115200);
\r
158 serial.baud(230400);
\r
161 sdma_setup(UART0, 0);
\r
163 printStr("\r\n============= Start of the program ============\r\n");
\r
165 int ticks = 0, tocks = 0;
\r
167 ticks = (us_ticker_read()*1E-6) / TIME_ACCURACY;
\r
168 if (tocks < ticks) {
\r
169 clock1_interrupt();
\r
175 /**********************
\r
176 * Interrupt handlers *
\r
177 **********************/
\r
179 void serialRx_interrupt(void) { // Byte version
\r
180 static int state = 0;
\r
181 static int index = 0;
\r
182 static int length = 0;
\r
184 control_t *cmd = (control_t*)rxFrame;
\r
186 while (serial.readable()) {
\r
187 rxFrame[index++] = serial.getc();
\r
190 if (cmd->header == HEADER)
\r
196 if (cmd->bits.sns >= SNS_NUM ||
\r
197 cmd->bits.cmd >= CMD_NUM) {
\r
199 } else if (cmd->bits.cmd == CMD_RATE) {
\r
211 if (rxFrame[index-1] == TAIL)
\r
220 void clock1_interrupt(void){
\r
229 static float sinAmp = 0.5; // 0..1
\r
230 static float sinFreq = 0.25; // Hz
\r
232 // Write A2D output sine wave
\r
233 a2dOutput.write(sinAmp*sin(sinCnt * TIME_ACCURACY * (2*PI) * sinFreq)*0.5 + 0.5);
\r
235 // Send data through Serial
\r
236 if (accEnable && accCnt >= (int)(accTmr/TIME_ACCURACY+0.5)){
\r
240 if (magEnable && magCnt >= (int)(magTmr/TIME_ACCURACY+0.5)){
\r
244 if (lgtEnable && lgtCnt >= (int)(lgtTmr/TIME_ACCURACY+0.5)){
\r
248 if (tchEnable && tchCnt >= (int)(tchTmr/TIME_ACCURACY+0.5)){
\r
252 if (a2dEnable && a2dCnt >= (int)(a2dTmr/TIME_ACCURACY+0.5)){
\r
257 // Toggel LED for debugging
\r
258 if (ledEnable && ledCnt>=ledTmr/TIME_ACCURACY){
\r
274 /*******************
\r
275 * Command handler *
\r
276 *******************/
\r
278 void runCommand(control_t *cmd)
\r
280 // Validate interval
\r
281 sns_t snsType = (sns_t)cmd->bits.sns;
\r
282 cmd_t cmdType = (cmd_t)cmd->bits.cmd;
\r
283 float interval = CLAMP(cmd->interval, MIN_RATE, MAX_RATE);
\r
285 // Save value to global data
\r
289 case CMD_STOP: accEnable = false; break;
\r
290 case CMD_START: accEnable = true; break;
\r
291 case CMD_RATE: accTmr = interval; break;
\r
297 case CMD_STOP: magEnable = false; break;
\r
298 case CMD_START: magEnable = true; break;
\r
299 case CMD_RATE: magTmr = interval; break;
\r
305 case CMD_STOP: lgtEnable = false; break;
\r
306 case CMD_START: lgtEnable = true; break;
\r
307 case CMD_RATE: lgtTmr = interval; break;
\r
313 case CMD_STOP: tchEnable = false; break;
\r
314 case CMD_START: tchEnable = true; break;
\r
315 case CMD_RATE: tchTmr = interval; break;
\r
321 case CMD_STOP: a2dEnable = false; break;
\r
322 case CMD_START: a2dEnable = true; break;
\r
323 case CMD_RATE: a2dTmr = interval; break;
\r
329 /*******************
\r
330 * Sensors reading *
\r
331 *******************/
\r
333 void sendAccInfo(void){
\r
335 accData[0] = accSensor.getAccX();
\r
336 accData[1] = accSensor.getAccY();
\r
337 accData[2] = accSensor.getAccZ();
\r
338 int len = packToFrame(txFrame, SNS_ACC, TYP_F32, 3, accData);
\r
340 printStr("[ACC] accX=%-2.4f accY=%-2.4f accZ=%-2.4f\r\n",
\r
341 accData[0], accData[1], accData[2]);
\r
342 printHex(txFrame, len);
\r
343 printBin(txFrame, len);
\r
346 void sendMagInfo(void){
\r
347 // magSensor uses the wrong types,
\r
348 // so we have to convert it
\r
350 magSensor.getValues(&tmp[0], &tmp[1], &tmp[2]);
\r
351 uint16_t magData[3];
\r
352 magData[0] = tmp[0];
\r
353 magData[1] = tmp[1];
\r
354 magData[2] = tmp[2];
\r
355 int len = packToFrame(txFrame, SNS_MAG, TYP_S16, 3, magData);
\r
357 printStr("[MAG] magX=%hd magY=%hd magZ=%hd %d\r\n",
\r
358 magData[0], magData[1], magData[2], sizeof(int));
\r
359 printHex(txFrame, len);
\r
360 printBin(txFrame, len);
\r
363 void sendLgtInfo(void){
\r
364 float lgtData = lgtSensor.read();
\r
365 int len = packToFrame(txFrame, SNS_LGT, TYP_F32, 1, &lgtData);
\r
367 printStr("[LGT] intensity=%f\r\n",
\r
369 printHex(txFrame, len);
\r
370 printBin(txFrame, len);
\r
373 void sendTchInfo(void){
\r
375 tchData[0] = tchSensor.readPercentage();
\r
376 tchData[1] = tchSensor.readDistance();
\r
377 int len = packToFrame(txFrame, SNS_TCH, TYP_F32, 2, tchData);
\r
379 printStr("[TCH] force=%0.4f distance=%2.2f\r\n",
\r
380 tchData[0], tchData[1]);
\r
381 printHex(txFrame, len);
\r
382 printBin(txFrame, len);
\r
385 void sendA2dInfo(void){
\r
387 a2dData[0] = a2dSensor0.read();
\r
388 a2dData[1] = a2dSensor1.read();
\r
389 a2dData[2] = a2dSensor2.read();
\r
390 a2dData[3] = a2dSensor3.read();
\r
391 a2dData[4] = a2dSensor4.read();
\r
392 a2dData[5] = a2dSensor5.read();
\r
393 int len = packToFrame(txFrame, SNS_A2D, TYP_F32, 6, a2dData);
\r
395 printStr("[A2D] data=%2.2f %2.2f %2.2f %2.2f %2.2f %2.2f\r\n",
\r
396 a2dData[0], a2dData[1], a2dData[2],
\r
397 a2dData[3], a2dData[4], a2dData[5]);
\r
398 printHex(txFrame, len);
\r
399 printBin(txFrame, len);
\r
402 /********************
\r
403 * Helper functions *
\r
404 ********************/
\r
406 int calDataSize(type_t dataType){
\r
408 case TYP_S8: return 1;
\r
409 case TYP_S16: return 2;
\r
410 case TYP_S32: return 4;
\r
411 case TYP_U8: return 1;
\r
412 case TYP_U16: return 2;
\r
413 case TYP_U32: return 4;
\r
414 case TYP_F32: return 4;
\r
415 case TYP_F64: return 8;
\r
420 /*******************
\r
421 * Frame functions *
\r
422 *******************/
\r
424 int packToFrame(uint8_t *frame, sns_t snsType, type_t dataType, int dataNum, void *data){
\r
425 //const char pattern[] = "\x80\x81\x82\x83"
\r
426 // "\x84\x85\x86\x87"
\r
427 // "\x88\x89\x8A\x8B"
\r
428 // "\x8C\x8D\x8E\x8F";
\r
430 int size = dataNum * calDataSize(dataType);
\r
431 state_t *state = (state_t*)frame;
\r
432 uint8_t *tail = &state->data[size];
\r
434 state->header = HEADER;
\r
435 state->bits.sns = snsType;
\r
436 state->bits.type = dataType;
\r
437 state->count = dataNum;;
\r
438 memcpy(&state->data, data, size);
\r
442 return (3 + size + 1);
\r
445 /*******************
\r
446 * Print functions *
\r
447 *******************/
\r
449 void printHex(uint8_t *frame, int len){
\r
454 for (int i=0; i<len; i++)
\r
455 sdma_printf("%02hx ", frame[i]);
\r
456 sdma_printf("\r\n");
\r
459 void printStr(const char *fmt, ...){
\r
465 sdma_vprintf(fmt, ap);
\r
469 void printBin(uint8_t *frame, int len){
\r
473 sdma_write(frame, len);
\r