Update

Dependents:   COG_UART_Base

Revision:
0:860fafcf34d6
--- /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);
+}