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
--- /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);
+}
--- /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