adxl362 csv output format

Files at this revision

API Documentation at this revision

Comitter:
APS_Lab
Date:
Thu May 16 07:02:24 2019 +0000
Commit message:
adxl362

Changed in this revision

.gitignore Show annotated file Show diff for this revision Revisions of this file
ADXL362.cpp Show annotated file Show diff for this revision Revisions of this file
ADXL362.h Show annotated file Show diff for this revision Revisions of this file
CONTRIBUTING.md Show annotated file Show diff for this revision Revisions of this file
README.md Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
mbed_app.json Show annotated file Show diff for this revision Revisions of this file
stats_report.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.gitignore	Thu May 16 07:02:24 2019 +0000
@@ -0,0 +1,4 @@
+.build
+.mbed
+projectfiles
+*.py*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ADXL362.cpp	Thu May 16 07:02:24 2019 +0000
@@ -0,0 +1,380 @@
+#include "ADXL362.h"
+
+#define WAIT_US(value)		(0.000001 * ((float)value))
+
+#define REGADDR_WRITE		(0x80)
+#define REGADDR_WR_L		(0x00)
+#define REGADDR_WR_H		(0x01)
+
+#define GET_VAL_L(value)	((value >> 0) & 0xFF)
+#define GET_VAL_H(value)	((value >> 8) & 0xFF)
+
+// define for EV-COG-AD3029LZ
+#define SPI_CS    SPI1_CS3
+
+/** ==========================================
+ *  Public ( initializing )
+ *  ========================================== */
+ADXL362::ADXL362(Serial *setUart, SPI* spi1) {	
+    int check;
+
+	uart = setUart;  
+	_spi = spi1;
+	_cs = new DigitalOut(SPI_CS);
+	
+	_spi->format(8,3);
+	_spi->frequency(1000000);
+	
+	chipSelOff();
+
+	/* start */
+	check = regRD(DEVID_AD);
+	if (check != DEVID_AD_ADXL362) {	
+		return;
+	}
+	check = regRD(DEVID_MST);
+	if (check != DEVID_MST_ADXL362) {	
+		return;
+	}
+	check = regRD(PARTID);
+	if (check != PARTID_ADXL362) {	
+		return;
+	}
+
+	/* init MIN/MAX store */
+	initMinMax(&minStore, &maxStore);	
+	/* set convert parameter */		
+	SoftReset();
+
+	scaleAccel = PARAM_ADXL362_SCALE_ACCEL;
+    scaleThermal = PARAM_ADXL362_SCALE_THERMAL;
+    offsetThermal = PARAM_ADXL362_THERMAL_OFFSET;
+	
+	//SetMesureParam(POWER_CTL_PARAM_LOWNOISE_ULTRA);
+	//StartMesure();
+}
+
+ADXL362::~ADXL362() {
+    delete this->_cs;
+}
+
+
+/** ==========================================
+ *  Private ( Control Pins )
+ *  ========================================== */
+/* Assert CHIP_SEL = enable */
+void ADXL362::chipSelOn() {
+	chipSelDelay();
+	*_cs = 0;
+}
+
+/* Assert CHIP_SEL = disable */
+void ADXL362::chipSelOff() {
+	*_cs = 1;
+}
+
+/* delay for CHIP_SEL */
+void ADXL362::chipSelDelay() {
+    wait(WAIT_US(0.2));
+}
+/** ==========================================
+ *  Public ( ADXL Configuration )
+ *  ========================================== */
+void ADXL362::set_gravity(int g)
+{
+	int value;
+	unsigned char g_reg;
+	
+	switch(g)
+	{
+		case GRAVITY_2G:
+			ADXL362::gravity = GRAVITY_2G;
+			g_reg = 0x00;
+			break;
+		case GRAVITY_4G:
+			ADXL362::gravity = GRAVITY_4G;
+			g_reg = 0x40;
+			break;
+		case GRAVITY_8G:
+			ADXL362::gravity = GRAVITY_8G;
+			g_reg = 0x80;
+			break;
+		default:
+			ADXL362::gravity = GRAVITY_2G;
+			g_reg = 0x00;
+			break;
+	}
+	value = regRD(FILTER_CTL);
+	value &= 0x3f;
+	value |= g_reg;
+	regWR(FILTER_CTL, value);
+	set_scalefactor();
+}
+
+void ADXL362::set_ODR(int o)
+{
+	int value;
+	unsigned char o_reg;
+	
+	switch(o)
+	{
+		case ODR_12:
+			odr = ODR_12;
+			o_reg = 0x00; 
+			break;
+		case ODR_25:
+			odr = ODR_25;
+			o_reg = 0x01; 
+			break;
+		case ODR_50:
+			odr = ODR_50;
+			o_reg = 0x02; 
+			break;
+		case ODR_100:
+			odr = ODR_100;
+			o_reg = 0x03; 
+			break;
+		case ODR_200:
+			odr = ODR_200;
+			o_reg = 0x04; 
+			break;
+		case ODR_400:
+			odr = ODR_400;
+			o_reg = 0x07; 
+			break;
+		default:
+			odr = ODR_100;
+			o_reg = 0x03;
+			break;
+	}
+	value = regRD(FILTER_CTL);
+	value &= 0xf8;
+	value |= o_reg;
+	regWR(FILTER_CTL, value);
+}
+
+void ADXL362::set_powermode(int m)
+{
+	ADXL362::SetMesureParam(m);
+}
+
+void ADXL362::set_wakeupmode(void)
+{
+	regWR(THRESH_ACT_L, 0x50);
+	regWR(THRESH_ACT_H, 0x00);
+	regWR(TIME_ACT, 0x00);
+	regWR(THRESH_INACT_L, 0xff);
+	regWR(THRESH_INACT_H, 0x07);
+	regWR(TIME_INACT_L, 0x06);
+	regWR(TIME_INACT_H, 0x00);
+	regWR(ACT_INACT_CTL, 0x1F);
+	regWR(INTMAP1, 0xC0);
+	regWR(POWER_CTL, 0x0E);
+}
+
+void ADXL362::set_scalefactor(void)
+{
+	float base, sf;
+	
+	base = (ADXL362::gravity / 2.0f);
+	sf = base*(0.001f)*9.80665f;
+	scaleAccel = sf;
+}
+
+void ADXL362::start(void)
+{
+	int value;
+	value = regRD(POWER_CTL);
+	value &= 0xfc;
+	value |= POWER_CTL_MESURE;
+	regWR(POWER_CTL, value);
+    wait_ms(5);
+	GetStatus();
+}
+	
+void ADXL362::stop(void)
+{
+	int value;
+	value = regRD(POWER_CTL);
+	value &= 0xfc;
+	value |= POWER_CTL_STOP;
+	regWR(POWER_CTL, value);
+	wait_ms(5);
+	GetStatus();
+}
+
+/** ==========================================
+ *  Public ( Send Command to Device )
+ *  ========================================== */
+/* Write 16bit-Aligned Register */
+void ADXL362::SoftReset() {
+	regWR(SOFT_RESET, SOFT_RESET_ADXL362);
+	wait(0.5);	
+}
+
+void ADXL362::SetMesureParam(int param) {
+	int value;
+	value = regRD(POWER_CTL);
+	param &= ~(POWER_CTL_MODEMASK);
+	value &= POWER_CTL_MODEMASK;
+	value |= param;
+	regWR(POWER_CTL, value);
+}
+
+void ADXL362::StartMesure() {
+	int value;
+	GetStatus();
+	value = regRD(POWER_CTL);
+	value &= ~(POWER_CTL_MODEMASK);
+	value |= POWER_CTL_MESURE;
+	regWR(POWER_CTL, POWER_CTL_MESURE);
+	value = regRD(POWER_CTL);	
+    wait_ms(5);
+	GetStatus();
+}
+
+int ADXL362::GetStatus() {
+	int value;
+	value = regRD(STATUS);
+	return value;
+}
+
+/** ==========================================
+ *  Public ( Sensing )
+ *  ========================================== */
+void ADXL362::SensorRead(AccelTemp *pAT) {
+	int burstBuf[8];
+	/* Xx2 + Yx2 + Zx2 + Tempx2 = 8*/
+	regBurstRD(XDATA_L, 8, burstBuf);
+	convertSensorData(pAT, burstBuf);
+#if 0	
+	uart->printf("ADXL362[ax] = 0x%02x\n", pAT->ax);
+	uart->printf("ADXL362[ay] = 0x%02x\n", pAT->ay);
+	uart->printf("ADXL362[az] = 0x%02x\n", pAT->az);
+	uart->printf("ADXL362[tm] = 0x%02x\n", pAT->tm)
+#endif	
+	updateMinMax(&minStore, &maxStore, pAT);	
+}
+
+/** ==========================================
+ *  Public ( Sub Infomation )
+ *  ========================================== */
+/* Get Internal Store (for Min Info) */
+AccelTemp* ADXL362::GetMinInfo(void) {
+	return &minStore;
+}
+
+/* Get Internal Store (for Max Info) */
+AccelTemp* ADXL362::GetMaxInfo(void) {
+	return &maxStore;
+}
+
+/* Convert CtrlValue to Real for Accelerometer */
+float ADXL362::ConvAccel(int ctrlval) {
+	return scaleAccel * (float)ctrlval;
+}
+
+/* Convert CtrlValue to Real for Thermal Sensor */
+float ADXL362::ConvThermal(int ctrlval) {
+	return (scaleThermal * (float)ctrlval) + offsetThermal;
+}
+
+/** ==========================================
+ *  Private ( convert sensing value )
+ *  ========================================== */
+void ADXL362::convertSensorData(AccelTemp *at, int *buf) {
+	at->ax = ext12bitToInt(buf[0], buf[1]);
+	at->ay = ext12bitToInt(buf[2], buf[3]);
+	at->az = ext12bitToInt(buf[4], buf[5]);
+	at->tm = ext12bitToInt(buf[6], buf[7]);	
+}
+
+int ADXL362::ext12bitToInt(int l, int h)
+{
+	h <<= 8;
+	h &= 0x0f00;
+	h |= l & 0xff;
+	if ((h & 0x800) != 0) {
+		h |= 0xfffff000;
+	}
+	return h;
+}
+
+/** ==========================================
+ *  Private ( SPI Communication )
+ *  ========================================== */
+#define ADXL362_SPI_CMD_WR		0x0A
+#define ADXL362_SPI_CMD_RD		0x0B
+#define ADXL362_SPI_CMD_RD_FIFO	0x0D
+ 
+/* Read Single Register */
+int ADXL362::regRD(int regAddr) {
+	int recvData;
+	regBurstRD(regAddr, 1, &recvData);
+	return recvData;
+}
+
+/* Read Multi Register */
+void ADXL362::regBurstRD(int regAddr, int numBurst, int *recvBuf) {
+	int cnt;
+
+	/* SPI Burst Read Loop **
+	 * Write A -> Write B : Read A -> Write C : Read B -> ... */
+	_spi->lock();
+	chipSelOn();
+	/* WriteADDR[n] and ReadData[n-1] */
+	_spi->write(ADXL362_SPI_CMD_RD);
+	_spi->write(regAddr);		
+	for (cnt = 0; cnt < numBurst; cnt++) {
+		/* WriteADDR[n] and ReadData[n-1] */
+		recvBuf[cnt] = _spi->write(0x00);		
+	}
+	chipSelOff();	
+	_spi->unlock();
+	return;
+}
+
+/* Write 16bit-Aligned Register */
+void ADXL362::regWR(int regAddr, int value) {
+	_spi->lock();
+	chipSelOn();
+	_spi->write(ADXL362_SPI_CMD_WR);	
+	_spi->write(regAddr);
+	_spi->write(value);
+	chipSelOff();
+	_spi->unlock();
+	return;
+}
+
+/** ==========================================
+ *  Private ( Control internal Stores )
+ *  ========================================== */
+/* clear internal Min/Max infomation */	
+void ADXL362::initMinMax
+(AccelTemp *minData, AccelTemp *maxData) {
+    minData->ax = INT_MAX;
+    minData->ay = INT_MAX;
+    minData->az = INT_MAX;
+    minData->tm = INT_MAX;
+
+    maxData->ax = INT_MIN;
+    maxData->ay = INT_MIN;
+    maxData->az = INT_MIN;
+    maxData->tm = INT_MIN;
+}
+
+/* update internal Min/Max infomation */
+#define TEST_MIN_AND_SET(now, test) (now = (now >= test)? test : now)
+#define TEST_MAX_AND_SET(now, test) (now = (now <= test)? test : now)
+void ADXL362::updateMinMax
+(AccelTemp *minData, AccelTemp *maxData, AccelTemp *getData) {
+    TEST_MIN_AND_SET(minData->ax, getData->ax);
+    TEST_MIN_AND_SET(minData->ay, getData->ay);
+    TEST_MIN_AND_SET(minData->az, getData->az);
+	TEST_MIN_AND_SET(minData->tm, getData->tm);
+
+    TEST_MAX_AND_SET(maxData->ax, getData->ax);
+    TEST_MAX_AND_SET(maxData->ay, getData->ay);
+    TEST_MAX_AND_SET(maxData->az, getData->az);
+    TEST_MAX_AND_SET(maxData->tm, getData->tm);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ADXL362.h	Thu May 16 07:02:24 2019 +0000
@@ -0,0 +1,160 @@
+#ifndef _ADXL362_H_
+#define _ADXL362_H_
+#include "mbed.h"
+#include <SPI.h>
+
+// Register Memory Map
+#define DEVID_AD        0x00
+#define DEVID_MST       0x01
+#define PARTID          0x02
+#define REVID           0x03
+/* _ reserved _ */
+#define XDATA           0x08
+#define YDATA           0x09
+#define ZDATA           0x0A
+#define STATUS          0x0B
+#define FIFO_ENTRIES_L  0x0C
+#define FIFO_ENTRIES_H  0x0D
+#define XDATA_L         0x0E
+#define XDATA_H         0x0F
+#define YDATA_L         0x10
+#define YDATA_H         0x11
+#define ZDATA_L         0x12
+#define ZDATA_H         0x13
+#define TEMP_L          0x14
+#define TEMP_H          0x15
+/* _ reserved _ */
+#define SOFT_RESET      0x1F
+#define THRESH_ACT_L    0x20
+#define THRESH_ACT_H    0x21
+#define TIME_ACT        0x22
+#define THRESH_INACT_L  0x23
+#define THRESH_INACT_H  0x24
+#define TIME_INACT_L    0x25
+#define TIME_INACT_H    0x26
+#define ACT_INACT_CTL   0x27
+#define FIFO_CONTROL    0x28
+#define FIFO_SAMPLES    0x29
+#define INTMAP1         0x2A
+#define INTMAP2         0x2B
+#define FILTER_CTL      0x2C
+#define POWER_CTL       0x2D
+#define SELF_TEST       0x2E
+
+/* ADXL const parameters */
+#define SOFT_RESET_ADXL362      (0x52)
+
+#define POWER_CTL_PARAM_LOWNOISE_NORM   (0x00)
+#define POWER_CTL_PARAM_LOWNOISE_LOW    (0x10)
+#define POWER_CTL_PARAM_LOWNOISE_ULTRA  (0x20)
+
+#define POWER_CTL_MODEMASK      (0x03)
+#define POWER_CTL_STOP          (0x00)
+#define POWER_CTL_STANDBY       (0x01)
+#define POWER_CTL_MESURE        (0x02)
+
+/* ADXL362 configuration */     
+#define DEVID_AD_ADXL362        (0xAD)
+#define DEVID_MST_ADXL362       (0x1D)
+#define PARTID_ADXL362          (0xF2)
+
+#define GRAVITY_2G              (2)
+#define GRAVITY_4G              (4)
+#define GRAVITY_8G              (8)
+
+#define ODR_12                  0
+#define ODR_25                  1
+#define ODR_50                  2
+#define ODR_100                 3
+#define ODR_200                 4
+#define ODR_400                 5
+
+
+#define PARAM_ADXL362_SCALE_ACCEL     (1.0f * 0.001f * 9.80665f)  // DATA
+#define PARAM_ADXL362_SCALE_THERMAL   (0.0025f)                   // TEMP
+#define PARAM_ADXL362_THERMAL_OFFSET  (25.0f)                     // TEMP
+
+
+
+/* Output of Accelerometers */
+typedef struct _struct_AccelTemp {
+    int ax;
+    int ay;
+    int az;
+    int tm;
+} AccelTemp;
+
+/* ADIS16460 class definition */
+class ADXL362 {
+
+public:
+
+    /* ADIS16460 initializer */
+    ADXL362(Serial*, SPI*);
+    ~ADXL362();
+    
+    /* Control */
+    void SoftReset();
+    void SetMesureParam(int param);
+    void StartMesure();
+    int GetStatus();
+
+    /* Sensing */
+    void SensorRead(AccelTemp*);
+
+    /* GetSubInfo */
+    AccelTemp* GetMinInfo(void);
+    AccelTemp* GetMaxInfo(void);
+    
+    /* convert real scale */
+    float ConvAccel(int ctrlval);
+    float ConvThermal(int ctrlval);
+    
+    /* configuration */
+    void set_gravity(int g);
+    void set_ODR(int o);
+    void set_powermode(int m);
+    void set_wakeupmode(void);
+    void set_scalefactor(void);
+    void start(void);
+    void stop(void);
+        
+private:    
+    /* locked */
+    ADXL362();
+
+    /* information store */
+    Serial *uart;
+    SPI *_spi;
+    DigitalOut *_cs;
+    int odr;
+    AccelTemp minStore;
+    AccelTemp maxStore;
+    
+    /* realvalue */
+    float gravity;
+    float scaleAccel;
+    float scaleThermal;
+    float offsetThermal;
+
+    /* convert value */
+    void convertSensorData(AccelTemp*, int *);
+    int ext12bitToInt(int l, int h);
+    
+    /* update internal min/max */
+    void initMinMax(AccelTemp *min, AccelTemp *max);
+    void updateMinMax(AccelTemp *min, AccelTemp *max, AccelTemp *getData);
+     
+    
+    /* communication via SPI*/
+    void chipSelOn(void);
+    void chipSelOff(void);
+    void chipSelDelay(void);
+    
+    /* R/W primitives */
+    int regRD(int);
+    void regWR(int, int);
+    void regBurstRD(int, int, int*);
+};
+
+#endif /* _ADXL362_H_ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CONTRIBUTING.md	Thu May 16 07:02:24 2019 +0000
@@ -0,0 +1,5 @@
+# Contributing to Mbed OS
+
+Mbed OS is an open-source, device software platform for the Internet of Things. Contributions are an important part of the platform, and our goal is to make it as simple as possible to become a contributor.
+
+To encourage productive collaboration, as well as robust, consistent and maintainable code, we have a set of guidelines for [contributing to Mbed OS](https://os.mbed.com/docs/mbed-os/latest/contributing/index.html).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Thu May 16 07:02:24 2019 +0000
@@ -0,0 +1,152 @@
+# Getting started example for Mbed OS
+
+This guide reviews the steps required to get Blinky with the addition of dynamic OS statistics working on an Mbed OS platform. (Note: To see a rendered example you can import into the Arm Online Compiler, please see our [quick start](https://os.mbed.com/docs/mbed-os/latest/quick-start/online-with-the-online-compiler.html#importing-the-code).)
+
+Please install [Mbed CLI](https://github.com/ARMmbed/mbed-cli#installing-mbed-cli).
+
+## Import the example application
+
+From the command-line, import the example:
+
+```
+mbed import mbed-os-example-blinky
+cd mbed-os-example-blinky
+```
+
+### Now compile
+
+Invoke `mbed compile`, and specify the name of your platform and your favorite toolchain (`GCC_ARM`, `ARM`, `IAR`). For example, for the Arm Compiler:
+
+```
+mbed compile -m K64F -t ARM
+```
+
+Your PC may take a few minutes to compile your code. At the end, you see the following result:
+
+```
+[snip]
+
+Image: ./BUILD/K64F/GCC_ARM/mbed-os-example-blinky.bin
+```
+
+### Program your board
+
+1. Connect your Mbed device to the computer over USB.
+1. Copy the binary file to the Mbed device.
+1. Press the reset button to start the program.
+
+The LED on your platform turns on and off. The main thread will additionally take a snapshot of the device's runtime statistics and display it over serial to your PC. The snapshot includes:
+
+* System Information:
+    * Mbed OS Version: Will currently default to 999999
+    * Compiler ID
+        * ARM = 1
+        * GCC_ARM = 2
+        * IAR = 3
+    * [CPUID Register Information](#cpuid-register-information)
+    * [Compiler Version](#compiler-version)
+* CPU Statistics
+    * Percentage of runtime that the device has spent awake versus in sleep
+* Heap Statistics
+    * Current heap size
+    * Max heap size which refers to the largest the heap has grown to
+* Thread Statistics
+    * Provides information on all running threads in the OS including
+        * Thread ID
+        * Thread Name
+        * Thread State
+        * Thread Priority
+        * Thread Stack Size
+        * Thread Stack Space
+
+#### Compiler Version
+
+| Compiler | Version Layout |
+| -------- | -------------- |
+| ARM      | PVVbbbb (P = Major; VV = Minor; bbbb = build number) |
+| GCC      | VVRRPP  (VV = Version; RR = Revision; PP = Patch)    |
+| IAR      | VRRRPPP (V = Version; RRR = Revision; PPP = Patch)   |
+
+#### CPUID Register Information
+
+| Bit Field | Field Description | Values |
+| --------- | ----------------- | ------ |
+|[31:24]    | Implementer       | 0x41 = ARM |
+|[23:20]    | Variant           | Major revision 0x0  =  Revision 0 |
+|[19:16]    | Architecture      | 0xC  = Baseline Architecture |
+|           |                   | 0xF  = Constant (Mainline Architecture) |
+|[15:4]     | Part Number       | 0xC20 =  Cortex-M0 |
+|           |                   | 0xC60 = Cortex-M0+ |
+|           |                   | 0xC23 = Cortex-M3  |
+|           |                   | 0xC24 = Cortex-M4  |
+|           |                   | 0xC27 = Cortex-M7  |
+|           |                   | 0xD20 = Cortex-M23 |
+|           |                   | 0xD21 = Cortex-M33 |
+|[3:0]      | Revision          | Minor revision: 0x1 = Patch 1 |
+
+
+
+You can view individual examples and additional API information of the statistics collection tools at the bottom of the page in the [related links section](#related-links).
+
+
+### Output
+
+To view the serial output you can use any terminal client of your choosing such as [PuTTY](http://www.putty.org/) or [CoolTerm](http://freeware.the-meiers.org/). Unless otherwise specified, printf defaults to a baud rate of 9600 on Mbed OS.
+
+You can find more information on the Mbed OS configuration tools and serial communication in Mbed OS in the related [related links section](#related-links).
+
+The output should contain the following block transmitted at the blinking LED frequency (actual values may vary depending on your target, build profile, and toolchain):
+
+```
+=============================== SYSTEM INFO  ================================
+Mbed OS Version: 999999
+CPU ID: 0x410fc241
+Compiler ID: 2
+Compiler Version: 60300
+RAM0: Start 0x20000000 Size: 0x30000
+RAM1: Start 0x1fff0000 Size: 0x10000
+ROM0: Start 0x0 Size: 0x100000
+================= CPU STATS =================
+Idle: 98% Usage: 2%
+================ HEAP STATS =================
+Current heap: 1096
+Max heap size: 1096
+================ THREAD STATS ===============
+ID: 0x20001eac
+Name: main_thread
+State: 2
+Priority: 24
+Stack Size: 4096
+Stack Space: 3296
+
+ID: 0x20000f5c
+Name: idle_thread
+State: 1
+Priority: 1
+Stack Size: 512
+Stack Space: 352
+
+ID: 0x20000f18
+Name: timer_thread
+State: 3
+Priority: 40
+Stack Size: 768
+Stack Space: 664
+
+```
+
+## Troubleshooting
+
+If you have problems, you can review the [documentation](https://os.mbed.com/docs/latest/tutorials/debugging.html) for suggestions on what could be wrong and how to fix it.
+
+## Related Links
+
+* [Mbed OS Stats API](https://os.mbed.com/docs/latest/apis/mbed-statistics.html)
+* [Mbed OS Configuration](https://os.mbed.com/docs/latest/reference/configuration.html)
+* [Mbed OS Serial Communication](https://os.mbed.com/docs/latest/tutorials/serial-communication.html)
+
+### License and contributions
+
+The software is provided under Apache-2.0 license. Contributions to this project are accepted under the same license. Please see contributing.md for more info.
+
+This project contains code from other projects. The original license text is included in those source files. They must comply with our license guide.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu May 16 07:02:24 2019 +0000
@@ -0,0 +1,333 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 ARM Limited
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "mbed.h"
+#include "stats_report.h"
+#include "ADXL362.h"
+#include "math.h"
+
+#define G_2 1.0
+#define G_4 2.0
+#define G_8 4.0
+
+
+
+#define MODE_NORMAL 0
+#define MODE_LOW_POWER 1
+#define MODE_ULTRA_LOW_POWER 2
+
+DigitalOut led1(LED1);
+Serial PC(USBTX, USBRX);
+
+char Buf[128];
+char command[8];
+char mode[8];
+char val[8];
+int f_val;
+
+int set_mode(int m);
+int set_freq(int v);
+int set_grav(int v);
+void set_start(void);
+void set_stop(void);
+static void clearDisplay(void);
+static void drawCLI(ADXL362 *adxlCtrl, AccelTemp *getData);
+static void draw_Raw(ADXL362 *adxlCtrl, AccelTemp *getData);
+
+volatile int f_run = 0;
+volatile int f_wake = 0;
+SPI         *spi1;
+ADXL362     *adxlCtrl;
+AccelTemp GetData;
+DigitalIn ADXL_WAKE(WAKE2);
+ 
+void help(void);
+        
+// main() runs in its own thread in the OS
+int main()
+{
+    PC.baud(115200);
+    PC.printf("EV-COG-AD4050LZ Demo\n");
+
+    spi1 = new SPI(SPI1_MOSI, SPI1_MISO, SPI1_SCLK);
+    adxlCtrl = new ADXL362(&PC, spi1); 
+
+    clearDisplay();
+    
+    help();
+    
+    while (true) {
+        // Blink LED and wait 0.5 seconds
+        led1 = !led1;
+        wait_ms(500);
+
+        PC.scanf("%s", command);
+        
+        if(strncmp(command, "set", 3) == 0)
+        {
+            PC.scanf("%s",mode);
+            
+            if(strncmp(mode, "freq", 4) == 0)
+            {
+                PC.scanf("%s", val);
+                f_val = atoi(val);
+                set_freq(f_val);
+            }
+            else if(strncmp(mode, "mode", 4) == 0)
+            {
+                PC.scanf("%s", val);
+                f_val = atoi(val);
+                set_mode(f_val);
+            }
+            else if(strncmp(mode, "grav", 4) == 0)
+            {
+                PC.scanf("%s", val);
+                f_val = atoi(val);
+                set_grav(f_val);
+            }
+            else if(strncmp(mode, "wakeup", 6) == 0)
+            {
+                PC.printf("ADXL362 wakeup mode\n");
+                adxlCtrl->set_wakeupmode();
+                f_wake = 1;
+                PC.printf("ADXL362 wakeup waiting......\n");
+                while(f_wake)
+                {
+                    if(ADXL_WAKE.read() == 1)
+                    {
+                        f_wake = 0;
+                        PC.printf("ADXL362 Wake-up\n");
+                        led1 = 1;
+                        PC.printf("ADXL362 Condition %d\n", ADXL_WAKE.read());
+                        adxlCtrl->GetStatus();
+                    }
+                    else
+                    {
+                        PC.printf(".");
+                    }
+                    wait_ms(100);
+                }
+                
+                
+            }else
+            {
+                PC.printf("Command Invalid\n");
+            }
+        }
+        else if(strncmp(command, "start", 5) == 0)
+        {
+            set_start();
+            while(f_run)
+            {
+                adxlCtrl->SensorRead(&GetData);
+                draw_Raw(adxlCtrl, &GetData);
+                wait(0.2);
+            }
+        }
+        //else if(strncmp(command, "stop", 4) == 0)
+        //{
+        //    set_stop();
+        //}
+        else
+        {
+            help();
+        }
+        // Following the main thread wait, report on the current system status
+        //sys_state.report_state();
+    }
+}
+
+void help(void)
+{
+    PC.printf("Command Usage\n");
+    PC.printf("Command : only 'set'\n");
+    PC.printf("Mode    : 'freq' is ODR configuration\n");
+    PC.printf("        : ODR frequency from 12, 25, 50, 100, 200, 400Hz\n");
+    PC.printf("Mode    : 'grav' is select gravity\n");
+    PC.printf("        : 0:2g 1:4g 2:8g\n");
+    PC.printf("Mode    : 'mode' is power mode\n");
+    PC.printf("        : 0:Normal 1:Low Power 2:Ultra Low Power(freq is fixed at 100Hz)\n");
+    PC.printf("i.e.  'set mode 0'\n");
+    PC.printf("i.e.  'set freq 1000'\n");
+    PC.printf("i.e.  'start'\n");    
+}
+
+int set_freq(int v)
+{
+    if((v < 12) || (v > 400)) 
+    {
+        PC.printf("ODR Freqency Range is over/under. Please configure for 12-400 Hz.\n");
+        return 1;
+    }
+    else
+    {
+        PC.printf("Set Frequency %d Hz\n", v);
+        return 0;
+    }
+}
+
+int set_grav(int v)
+{
+    switch(v)
+    {
+        case 0:
+            PC.printf("Set gravity 2g\n");
+            adxlCtrl->set_gravity(GRAVITY_2G);
+            break;
+        case 1:
+            PC.printf("Set gravity 4g\n");
+            adxlCtrl->set_gravity(GRAVITY_4G);
+            break;
+        case 2:
+            PC.printf("Set gravity 8g\n");
+            adxlCtrl->set_gravity(GRAVITY_8G);
+            break;
+        default:
+            PC.printf("Unknown Command\n");
+            break;
+    };
+    
+    return 0;
+}
+int set_mode(int m)
+{
+    switch(m)
+    {
+        case MODE_NORMAL:
+            PC.printf("Set Normal Mode\n");
+            adxlCtrl->set_powermode(POWER_CTL_PARAM_LOWNOISE_NORM);
+            break;
+        case MODE_LOW_POWER:
+            PC.printf("Set Low Power Mode\n");
+            adxlCtrl->set_powermode(POWER_CTL_PARAM_LOWNOISE_LOW);
+            break;
+        case MODE_ULTRA_LOW_POWER:
+            PC.printf("Set Ultra Low Power Mode\n");
+            adxlCtrl->set_powermode(POWER_CTL_PARAM_LOWNOISE_ULTRA);
+            break;
+        default:
+            PC.printf("Unknown Command\n");
+            break;
+    };
+    
+    return 0;
+}
+
+void set_start(void)
+{
+    f_run = 1;
+    adxlCtrl->start();
+    PC.printf("Start Accel\n");
+}
+
+void set_stop(void)
+{
+    f_run = 0;
+    adxlCtrl->stop();
+    PC.printf("Stop Accel\n");
+}
+
+static void clearDisplay(void)
+{
+    PC.printf("\033[2J");
+    PC.printf("\033[0;0H");
+    PC.printf("\033[0m\033[37m");    
+}
+
+static void drawCLI(ADXL362 *adxlCtrl, AccelTemp *getData)
+{
+    AccelTemp *min = adxlCtrl->GetMinInfo();
+    AccelTemp *max = adxlCtrl->GetMaxInfo();
+    AccelTemp *p;
+    float x, y, z, t;
+    
+    PC.printf("\033[2J");
+    
+    /* BLANK LINE */
+    
+    PC.printf("\033[0m\033[33m\033[1m");
+    PC.printf("\033[2;1H");
+    PC.printf("\033[K");
+    PC.printf("ACCELEROMETERs");
+    
+    PC.printf("\033[0m\033[37m");
+    PC.printf("\033[3;3H");
+    PC.printf("\033[K");
+    PC.printf("\033[3;10H-X---\033[3;20H-Y---\033[3;30H-Z---");
+    
+    PC.printf("\033[0m\033[35m");
+    PC.printf("\033[4;3H");
+    PC.printf("\033[K");
+    p = min;
+    x = sin(adxlCtrl->ConvAccel(p->ax));
+    y = adxlCtrl->ConvAccel(p->ay);
+    z = adxlCtrl->ConvAccel(p->az);
+    PC.printf("min\033[4;10H%04.2f\033[4;20H%04.2f\033[4;30H%04.2f", x, y, z);
+    
+    PC.printf("\033[0m\033[37m\033[1m");
+    PC.printf("\033[5;3H");
+    PC.printf("\033[K");
+    p = getData;
+    x = adxlCtrl->ConvAccel(p->ax);
+    y = adxlCtrl->ConvAccel(p->ay);
+    z = adxlCtrl->ConvAccel(p->az);
+    PC.printf("-->\033[5;10H%04.2f\033[5;20H%04.2f\033[5;30H%04.2f", x, y, z);
+    
+    PC.printf("\033[0m\033[36m");
+    PC.printf("\033[6;3H");
+    PC.printf("\033[K");
+    p = max;
+    x = adxlCtrl->ConvAccel(p->ax);
+    y = adxlCtrl->ConvAccel(p->ay);
+    z = adxlCtrl->ConvAccel(p->az);
+    PC.printf("max\033[6;10H%04.2f\033[6;20H%04.2f\033[6;30H%04.2f", x, y, z);
+    
+    /* BLANK LINE */
+        
+    PC.printf("\033[0m\033[31m\033[1m");
+    PC.printf("\033[8;1H");
+    PC.printf("\033[K");
+    PC.printf("Temperature");
+
+    /* BLANK LINE */
+
+    PC.printf("\033[0m\033[35m");
+    PC.printf("\033[10;3H");
+    PC.printf("\033[K");
+    p = min;
+    t = adxlCtrl->ConvThermal(p->tm);
+    PC.printf("min\033[10;10H%04.2f", t);
+
+    PC.printf("\033[0m\033[37m\033[1m");
+    PC.printf("\033[11;3H");
+    PC.printf("\033[K");
+    p = getData;
+    t = adxlCtrl->ConvThermal(p->tm);
+    PC.printf("-->\033[11;10H%04.2f", t);
+    
+    PC.printf("\033[0m\033[36m");
+    PC.printf("\033[12;3H");
+    PC.printf("\033[K");
+    p = max;
+    t = adxlCtrl->ConvThermal(p->tm);
+    PC.printf("max\033[12;10H%04.2f", t);
+}
+
+static void draw_Raw(ADXL362 *adxlCtrl, AccelTemp *getData)
+{
+    AccelTemp *p;
+    float x, y, z, t;
+    
+    /* BLANK LINE */
+    p = getData;
+    t = adxlCtrl->ConvThermal(p->tm);
+    x = adxlCtrl->ConvAccel(p->ax);
+    y = adxlCtrl->ConvAccel(p->ay);
+    z = adxlCtrl->ConvAccel(p->az);
+    PC.printf("%04.2f, %04.2f, %04.2f, %04.2f\n", x, y, z, t);
+}
+
+
+    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Thu May 16 07:02:24 2019 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#a8e5a4cb0f4facb615c32306d9b509aec07a0b5a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_app.json	Thu May 16 07:02:24 2019 +0000
@@ -0,0 +1,11 @@
+{
+    "target_overrides": {
+        "*": {
+            "platform.stack-stats-enabled": true,
+            "platform.heap-stats-enabled": true,
+            "platform.cpu-stats-enabled": true,
+            "platform.thread-stats-enabled": true,
+            "platform.sys-stats-enabled": true
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stats_report.h	Thu May 16 07:02:24 2019 +0000
@@ -0,0 +1,132 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 ARM Limited
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef STATS_REPORT_H
+#define STATS_REPORT
+
+#include "mbed.h"
+
+/**
+ *  System Reporting library. Provides runtime information on device:
+ *      - CPU sleep, idle, and wake times
+ *      - Heap and stack usage
+ *      - Thread information
+ *      - Static system information
+ */
+class SystemReport {
+    mbed_stats_heap_t   heap_stats;
+    mbed_stats_cpu_t    cpu_stats;
+    mbed_stats_sys_t    sys_stats;
+
+    mbed_stats_thread_t *thread_stats;
+    uint8_t   thread_count;
+    uint8_t   max_thread_count;
+    uint32_t  sample_time_ms;
+
+public:
+    /**
+     *  SystemReport - Sample rate in ms is required to handle the CPU percent awake logic
+     */
+    SystemReport(uint32_t sample_rate) : max_thread_count(8), sample_time_ms(sample_rate)
+    {
+        thread_stats = new mbed_stats_thread_t[max_thread_count];
+
+        // Collect the static system information
+        mbed_stats_sys_get(&sys_stats);
+
+        printf("=============================== SYSTEM INFO  ================================\r\n");
+        printf("Mbed OS Version: %ld \r\n", sys_stats.os_version);
+        printf("CPU ID: 0x%lx \r\n", sys_stats.cpu_id);
+        printf("Compiler ID: %d \r\n", sys_stats.compiler_id);
+        printf("Compiler Version: %ld \r\n", sys_stats.compiler_version);
+
+        for (int i = 0; i < MBED_MAX_MEM_REGIONS; i++) {
+            if (sys_stats.ram_size[i] != 0) {
+                printf("RAM%d: Start 0x%lx Size: 0x%lx \r\n", i, sys_stats.ram_start[i], sys_stats.ram_size[i]);
+            }
+        }
+        for (int i = 0; i < MBED_MAX_MEM_REGIONS; i++) {
+            if (sys_stats.rom_size[i] != 0) {
+                printf("ROM%d: Start 0x%lx Size: 0x%lx \r\n", i, sys_stats.rom_start[i], sys_stats.rom_size[i]);
+            }
+        }
+    }
+
+    ~SystemReport(void)
+    {
+        free(thread_stats);
+    }
+
+    /**
+     *  Report on each Mbed OS Platform stats API
+     */
+    void report_state(void)
+    {
+        report_cpu_stats();
+        report_heap_stats();
+        report_thread_stats();
+
+        // Clear next line to separate subsequent report logs
+        printf("\r\n");
+    }
+
+    /**
+     *  Report CPU idle and awake time in terms of percentage
+     */
+    void report_cpu_stats(void)
+    {
+        static uint64_t prev_idle_time = 0;
+
+        printf("================= CPU STATS =================\r\n");
+
+        // Collect and print cpu stats
+        mbed_stats_cpu_get(&cpu_stats);
+
+        uint64_t diff = (cpu_stats.idle_time - prev_idle_time);
+        uint8_t idle = (diff * 100) / (sample_time_ms * 1000);  // usec;
+        uint8_t usage = 100 - ((diff * 100) / (sample_time_ms * 1000));  // usec;;
+        prev_idle_time = cpu_stats.idle_time;
+
+        printf("Idle: %d%% Usage: %d%% \r\n", idle, usage);
+    }
+
+    /**
+     *  Report current heap stats. Current heap refers to the current amount of
+     *  allocated heap. Max heap refers to the highest amount of heap allocated
+     *  since reset.
+     */
+    void report_heap_stats(void)
+    {
+        printf("================ HEAP STATS =================\r\n");
+
+        // Collect and print heap stats
+        mbed_stats_heap_get(&heap_stats);
+
+        printf("Current heap: %lu\r\n", heap_stats.current_size);
+        printf("Max heap size: %lu\r\n", heap_stats.max_size);
+    }
+
+    /**
+     *  Report active thread stats
+     */
+    void report_thread_stats(void)
+    {
+        printf("================ THREAD STATS ===============\r\n");
+
+        // Collect and print running thread stats
+        int count = mbed_stats_thread_get_each(thread_stats, max_thread_count);
+
+        for (int i = 0; i < count; i++) {
+            printf("ID: 0x%lx \r\n",        thread_stats[i].id);
+            printf("Name: %s \r\n",         thread_stats[i].name);
+            printf("State: %ld \r\n",       thread_stats[i].state);
+            printf("Priority: %ld \r\n",    thread_stats[i].priority);
+            printf("Stack Size: %ld \r\n",  thread_stats[i].stack_size);
+            printf("Stack Space: %ld \r\n", thread_stats[i].stack_space);
+        }
+    }
+};
+
+#endif // STATS_REPORT_H