Update

Dependents:   COG_UART_Base

Files at this revision

API Documentation at this revision

Comitter:
APS_Lab
Date:
Fri Jan 11 07:05:02 2019 +0000
Commit message:
First;

Changed in this revision

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
diff -r 000000000000 -r 860fafcf34d6 ADXL362.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ADXL362.cpp	Fri Jan 11 07:05:02 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:
+			gravity = GRAVITY_2G;
+			g_reg = 0x00;
+			break;
+		case GRAVITY_4G:
+			gravity = GRAVITY_4G;
+			g_reg = 0x40;
+			break;
+		case GRAVITY_8G:
+			gravity = GRAVITY_8G;
+			g_reg = 0x80;
+			break;
+		default:
+			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 = (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);
+}
diff -r 000000000000 -r 860fafcf34d6 ADXL362.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ADXL362.h	Fri Jan 11 07:05:02 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.0)
+#define GRAVITY_4G              (4.0)
+#define GRAVITY_8G              (8.0)
+
+#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