X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=yue%2Fmain.cpp;h=1b02887c2eaf9f0125657e4fac90065e1969bc7b;hb=1b5c06b19c797e100b852c2b15a58fa1e3bd606a;hp=20186e1f54595b01466b25c9cfc8c271b3719d27;hpb=9d420b97abb440f7ab2ac92754d1019131758873;p=~andy%2Fcsm213a-hw diff --git a/yue/main.cpp b/yue/main.cpp index 20186e1..1b02887 100644 --- a/yue/main.cpp +++ b/yue/main.cpp @@ -1,212 +1,439 @@ -#include "mbed.h" -#include "TSISensor.h" // Touch Sensor -#include "MAG3110.h" // Magnetic Sensor -#include "MMA8451Q.h" // AcceleroMeter - - -#define MMA8451_I2C_ADDRESS (0x1d<<1) // acc sensor address -#define TIME_ACCURACY 0.1 -#define LIGHT_SNS_DEFAULT 1 // default collecting interval in seconds -#define ACC_SNS_DEFAULT 1 -#define MAG_SNS_DEFAULT 1 -#define TOUCH_SNS_DEFAULT 1 - -// Define Devices & Pins -MMA8451Q accSensor(PTE25, PTE24, MMA8451_I2C_ADDRESS); -TSISensor touchSensor; -MAG3110 magSensor(PTE25, PTE24); -Serial serial(USBTX, USBRX); -Ticker clock1; -AnalogIn lightSensor(PTE22); - - -// Global Variables -// Initial interval: in seconds -float lightTmr = LIGHT_SNS_DEFAULT; -float accTmr = ACC_SNS_DEFAULT; -float magTmr = MAG_SNS_DEFAULT; -float touchTmr = TOUCH_SNS_DEFAULT; - -bool lightEnable = true; -bool accEnable = true; -bool magEnable = true; -bool touchEnable = true; - -void clock1_interrupt(); -void serialRx_interrupt(); -void sendLightInfo(); -void sendAccInfo(); -void sendMagInfo(); -void sendTouchInfo(); - - -int main() { - // Initialization - // Interruption Declarations - clock1.attach(&clock1_interrupt, TIME_ACCURACY); // maximun accuracy be 0.1s - serial.attach(&serialRx_interrupt, Serial::RxIrq); // receive interrupt for serialS - magSensor.begin(); - - serial.printf("\r\n============= Start of the program ============\r\n"); - while(1){ - wait(3); - } -} - - -/*--------------------------------------------------------------- - ## Receive Interruption of the Serial ## - -> used to receive & process user command - -> and configure the board accordingly - ---------------------------------------------------------------*/ -void serialRx_interrupt(){ - clock1.detach(); // close the interrupt - serial.printf("\r\n"); - - // Receive the Serial Input - float interval; - char buffer[255]; - char temp[255]; - char ch = serial.getc(); - int i; - for (i=0 ; ch!='\n' && ch!='\r'; i++){ - serial.putc(ch); - buffer[i] = ch; - if (ch==127){ // BackSpace - i--; - i--; - } - ch = serial.getc(); - } - buffer[i] = '\0'; - serial.printf("\r\nBUFFER: %s %d\r\n", buffer,i); - // TODO: buffer -> lower case - - // Process the Serial Input - // Set-Interval Command - if (strstr(buffer, "set")!=NULL && strstr(buffer, "int")!= NULL){ - sscanf(buffer, "%*[^0123456789.]%s", temp); // find the number in buffer - sscanf(temp, "%f", &interval); // translate into float - if (interval<0.1 || interval>5){ - interval = 1; - } - if (strstr(buffer, "acc")){ - accTmr = interval; - } - if (strstr(buffer, "mag")){ - magTmr = interval; - } - if (strstr(buffer, "light")){ - lightTmr = interval; - } - if (strstr(buffer, "touch")){ - touchTmr = interval; - } - } - - // Stop Command - else if (strstr(buffer, "stop")!= NULL){ - serial.printf("STOP\r\n"); - if (strstr(buffer, "acc")){ - accEnable = false; - accTmr = ACC_SNS_DEFAULT; - } - if (strstr(buffer, "mag")){ - magEnable = false; - magTmr = MAG_SNS_DEFAULT; - } - if (strstr(buffer, "light")){ - lightEnable = false; - lightTmr = LIGHT_SNS_DEFAULT; - } - if (strstr(buffer, "touch")){ - touchEnable = false; - touchTmr = TOUCH_SNS_DEFAULT; - } - } - - // Start Command - else if (strstr(buffer, "start")!=NULL){ - if (strstr(buffer, "acc") && !accEnable){ - accEnable = true; - accTmr = ACC_SNS_DEFAULT; - } - if (strstr(buffer, "mag") && !magEnable){ - magEnable = true; - magTmr = MAG_SNS_DEFAULT; - } - if (strstr(buffer, "light") && !lightEnable){ - lightEnable = true; - lightTmr = LIGHT_SNS_DEFAULT; - } - if (strstr(buffer, "touch") && !touchEnable){ - touchEnable = true; - touchTmr = TOUCH_SNS_DEFAULT; - } - } - clock1.attach(&clock1_interrupt,0.1); -} - - -void clock1_interrupt(){ - static int accCnt; - static int magCnt; - static int lightCnt; - static int touchCnt; - - accCnt++; - magCnt++; - lightCnt++; - touchCnt++; - - // TODO: send data through Serial - if (lightEnable && (lightCnt<0 || lightCnt>=lightTmr/TIME_ACCURACY)){ - sendLightInfo(); - lightCnt = 0; - } - if (magEnable && (magCnt<0 || magCnt>=magTmr/TIME_ACCURACY)){ - sendMagInfo(); - magCnt = 0; - } - if (touchEnable && (touchCnt<0 || touchCnt>=touchTmr/TIME_ACCURACY)){ - sendTouchInfo(); - touchCnt = 0; - } - if (accEnable && (accCnt<0 || accCnt>=accTmr/TIME_ACCURACY)){ - sendAccInfo(); - accCnt = 0; - } -} - -void sendLightInfo(){ - serial.printf("[LGT] Light Intensity=%f\r\n", lightSensor.read()); -} - - -void sendAccInfo(){ - // get acc data - float accX = accSensor.getAccX(); - float accY = accSensor.getAccY(); - float accZ = accSensor.getAccZ(); - - // send acc data - serial.printf("[ACC] accX=%-2.4f accY=%-2.4f accZ=%-2.4f\r\n",accX,accY,accZ); -} - -void sendTouchInfo(){ - // get data - float touchForce = touchSensor.readPercentage(); - float distance = touchSensor.readDistance(); - - // send data - serial.printf("[TCH] Force=%0.4f Distance=%2.2f\r\n", touchForce, distance); -} - -void sendMagInfo(){ - // get data - int magX, magY, magZ; - magSensor.getValues(&magX, &magY, &magZ); - - // send data - serial.printf("[MAG] magX=%d magY=%d magZ=%d\r\n",magX,magY,magZ); -} +#include +#include + +#include "mbed.h" +#include "TSISensor.h" // Touch Sensor +#include "MAG3110.h" // Magnetic Sensor +#include "MMA8451Q.h" // AcceleroMeter + +#include "serial_dma.h" // AcceleroMeter + +//#include "DataFrame.h" + +#define CLAMP(x, min, max) \ + ((x) < (min) ? (min) : \ + (x) > (max) ? (max) : (x)) + +#define MMA8451_I2C_ADDRESS (0x1d<<1) // acc sensor address +#define TIME_ACCURACY 0.01 + +#define ACC_SNS_DEFAULT 0.1 // default collecting interval in seconds +#define MAG_SNS_DEFAULT 1.0 +#define LGT_SNS_DEFAULT 1.0 +#define TCH_SNS_DEFAULT 1.0 +#define A2D_SNS_DEFAULT 1.0 +#define LED_OUT_DEFAULT 0.5 + +#define MIN_RATE 1E-4 // 1 kHz +#define MAX_RATE 10.0 // 0.1 Hz + +// Common Frame Information +#define HEADER 0x02 +#define TAIL 0x0A // '\n' + +#define MAX_FRAME_SIZE 256 + +#define SNS_NUM 5 +#define TYPE_NUM 4 +#define OPER_NUM 3 + +typedef enum { + ACC_SNS, + MAG_SNS, + LGT_SNS, + TCH_SNS, + A2D_SNS, +} sns_t; + +typedef enum { + INT, + LONG, + FLOAT, + DOUBLE, +} type_t; + +typedef enum { + STOP, + START, + RATE, +} oper_t; + +// Data Frame Information +typedef struct { + uint8_t header; + struct { + uint8_t type : 4; + uint8_t sns : 4; + } bits; + uint8_t count; + uint8_t data[]; +} __attribute__((__packed__)) state_t; + +// Command Frame Information +typedef struct { + uint8_t header; + struct { + uint8_t oper : 4; + uint8_t sns : 4; + } bits; + float interval; +} __attribute__((__packed__)) command_t; + +// Define Devices & Pins +MMA8451Q accSensor(PTE25, PTE24, MMA8451_I2C_ADDRESS); +MAG3110 magSensor(PTE25, PTE24); +TSISensor tchSensor; +AnalogIn lgtSensor(PTE22); +AnalogIn a2dSensor(A0); + +DigitalOut led1(LED1); +DigitalOut led2(LED2); + +Serial serial(USBTX, USBRX); +Ticker clock1; + +// Global Variables +// Initial interval: in seconds +float accTmr = ACC_SNS_DEFAULT; +float magTmr = MAG_SNS_DEFAULT; +float tchTmr = TCH_SNS_DEFAULT; +float lgtTmr = LGT_SNS_DEFAULT; +float a2dTmr = A2D_SNS_DEFAULT; +float ledTmr = LED_OUT_DEFAULT; + +bool accEnable = false; +bool magEnable = true; +bool lgtEnable = false; +bool tchEnable = false; +bool a2dEnable = false; +bool ledEnable = true; + +bool useStr = true; +bool useHex = false; +bool useBin = false; + +uint8_t txFrame[MAX_FRAME_SIZE]; +uint8_t rxFrame[MAX_FRAME_SIZE]; + +// Prototypes +void clock1_interrupt(void); +void serialRx_interrupt(void); + +void runCommand(command_t *cmd); + +void sendAccInfo(void); +void sendMagInfo(void); +void sendLgtInfo(void); +void sendTchInfo(void); +void sendA2dInfo(void); + +int calDataSize(uint8_t); +int packToFrame(uint8_t *frame, sns_t snsType, type_t dataType, int dataNum, void *data); + +void printStr(const char *str, ...); +void printHex(uint8_t *frame, int len); +void printBin(uint8_t *frame, int len); + +/******** + * Main * + ********/ + +int main(void) { + // Initialization + // Interruption Declarations + clock1.attach(&clock1_interrupt, TIME_ACCURACY); // maximun accuracy be 0.1s + serial.attach(&serialRx_interrupt, Serial::RxIrq); // receive interrupt for serialS + serial.baud(115200); + magSensor.begin(); + + sdma_setup(UART0, 0); + + printStr("\r\n============= Start of the program ============\r\n"); + + while(1){ + wait(3); + } +} + +/********************** + * Interrupt handlers * + **********************/ + +void serialRx_interrupt(void) { // Byte version + static int state = 0; + static int index = 0; + static int length = 0; + + command_t *cmd = (command_t*)rxFrame; + + while (serial.readable()) { + rxFrame[index++] = serial.getc(); + switch (state) { + case 0: // Header + if (cmd->header == HEADER) + state = 1; + else + index = 0; + break; + case 1: // Bits + if (cmd->bits.sns >= SNS_NUM || + cmd->bits.oper >= OPER_NUM) { + state = index = 0; + } else if (cmd->bits.oper == RATE) { + length = 4; + state = 2; + } else { + state = 3; + } + break; + case 2: // Data + if (--length == 0) + state = 3; + break; + case 3: // Tail + if (rxFrame[index-1] == TAIL) + runCommand(cmd); + state = 0; + index = 0; + break; + } + } +} + +void clock1_interrupt(void){ + static int accCnt; + static int magCnt; + static int lgtCnt; + static int tchCnt; + static int a2dCnt; + static int ledCnt; + + accCnt++; + magCnt++; + lgtCnt++; + tchCnt++; + a2dCnt++; + ledCnt++; + + // Send data through Serial + if (accEnable && (accCnt<0 || accCnt>=accTmr/TIME_ACCURACY)){ + sendAccInfo(); + accCnt = 0; + } + if (magEnable && (magCnt<0 || magCnt>=magTmr/TIME_ACCURACY)){ + sendMagInfo(); + magCnt = 0; + } + if (lgtEnable && (lgtCnt<0 || lgtCnt>=lgtTmr/TIME_ACCURACY)){ + sendLgtInfo(); + lgtCnt = 0; + } + if (tchEnable && (tchCnt<0 || tchCnt>=tchTmr/TIME_ACCURACY)){ + sendTchInfo(); + tchCnt = 0; + } + if (a2dEnable && (a2dCnt<0 || a2dCnt>=a2dTmr/TIME_ACCURACY)){ + sendA2dInfo(); + a2dCnt = 0; + } + + // Toggel LED for debugging + if (ledEnable && (ledCnt<0 || ledCnt>=ledTmr/TIME_ACCURACY)){ + led1 = !led1; + ledCnt = 0; + } + + sdma_flush(); +} + +/******************* + * Command handler * + *******************/ + +void runCommand(command_t *cmd) +{ + // Validate interval + sns_t snsType = (sns_t )cmd->bits.sns; + oper_t operType = (oper_t)cmd->bits.oper; + float interval = CLAMP(cmd->interval, MIN_RATE, MAX_RATE); + + // Save value to global data + switch(snsType){ + case ACC_SNS: + switch(operType){ + case STOP: accEnable = false; break; + case START: accEnable = true; break; + case RATE: accTmr = interval; break; + } + break; + + case MAG_SNS: + switch(operType){ + case STOP: magEnable = false; break; + case START: magEnable = true; break; + case RATE: magTmr = interval; break; + } + break; + + case LGT_SNS: + switch(operType){ + case STOP: lgtEnable = false; break; + case START: lgtEnable = true; break; + case RATE: lgtTmr = interval; break; + } + break; + + case TCH_SNS: + switch(operType){ + case STOP: tchEnable = false; break; + case START: tchEnable = true; break; + case RATE: tchTmr = interval; break; + } + break; + + case A2D_SNS: + switch(operType){ + case STOP: a2dEnable = false; break; + case START: a2dEnable = true; break; + case RATE: a2dTmr = interval; break; + } + break; + } +} + +/******************* + * Sensors reading * + *******************/ + +void sendAccInfo(void){ + float accData[3]; + accData[0] = accSensor.getAccX(); + accData[1] = accSensor.getAccY(); + accData[2] = accSensor.getAccZ(); + int len = packToFrame(txFrame, ACC_SNS, FLOAT, 3, accData); + + printStr("[ACC] accX=%-2.4f accY=%-2.4f accZ=%-2.4f\r\n", + accData[0], accData[1], accData[2]); + printHex(txFrame, len); + printBin(txFrame, len); +} + +void sendMagInfo(void){ + int magData[3]; + magSensor.getValues(&magData[0], &magData[1], &magData[2]); + int len = packToFrame(txFrame, MAG_SNS, INT, 3, magData); + + printStr("[MAG] magX=%hd magY=%hd magZ=%hd %d\r\n", + magData[0], magData[1], magData[2], sizeof(int)); + printHex(txFrame, len); + printBin(txFrame, len); +} + +void sendLgtInfo(void){ + float lgtData = lgtSensor.read(); + int len = packToFrame(txFrame, LGT_SNS, FLOAT, 1, &lgtData); + + printStr("[LGT] intensity=%f\r\n", + lgtSensor.read()); + printHex(txFrame, len); + printBin(txFrame, len); +} + +void sendTchInfo(void){ + float tchData[2]; + tchData[0] = tchSensor.readPercentage(); + tchData[1] = tchSensor.readDistance(); + int len = packToFrame(txFrame, TCH_SNS, FLOAT, 2, tchData); + + printStr("[TCH] force=%0.4f distance=%2.2f\r\n", + tchData[0], tchData[1]); + printHex(txFrame, len); + printBin(txFrame, len); +} + +void sendA2dInfo(void){ + float a2dData[6]; + a2dData[0] = 0; + a2dData[1] = 0; + a2dData[2] = 0; + a2dData[3] = 0; + a2dData[4] = 0; + a2dData[5] = 0; + int len = packToFrame(txFrame, A2D_SNS, FLOAT, 6, a2dData); + + printStr("[A2D] data=%2.2f %2.2f %2.2f %2.2f %2.2f %2.2f\r\n", + a2dData[0], a2dData[1], a2dData[2], + a2dData[3], a2dData[4], a2dData[5]); + printHex(txFrame, len); + printBin(txFrame, len); +} + +/******************** + * Helper functions * + ********************/ + +int calDataSize(type_t dataType){ + switch(dataType){ + case INT: return 2; + case LONG: return 4; + case FLOAT: return 4; + case DOUBLE: return 8; + } + return 4; +} + +/******************* + * Frame functions * + *******************/ + +int packToFrame(uint8_t *frame, sns_t snsType, type_t dataType, int dataNum, void *data){ + //const char pattern[] = "\x80\x81\x82\x83" + // "\x84\x85\x86\x87" + // "\x88\x89\x8A\x8B" + // "\x8C\x8D\x8E\x8F"; + + int size = dataNum * calDataSize(dataType); + state_t *state = (state_t*)frame; + uint8_t *tail = &state->data[size]; + + state->header = HEADER; + state->bits.sns = snsType; + state->bits.type = dataType; + state->count = dataNum;; + memcpy(&state->data, data, size); + tail[0] = TAIL; + tail[1] = '\0'; + + return (3 + size + 1); +} + +/******************* + * Print functions * + *******************/ + +void printHex(uint8_t *frame, int len){ + if (!useHex) + return; + + sdma_printf(" "); + for (int i=0; i