library for enebular edge agent board(version p1)

Dependents:   ina-hack-2nd

Revision:
0:c6b2a8ace823
Child:
1:da9fd2252ed5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Eeabp1.cpp	Sat Aug 26 08:58:38 2017 +0000
@@ -0,0 +1,541 @@
+#include "Eeabp1.h"
+//#include "rtos.h"
+
+//Thread thread;
+static const int lora_msg_max_len = 11;
+
+Eeabp1::Eeabp1() : pwr_en(P0_0), led(P0_23), 
+    lora_power(P0_5), lora_reset(P0_22), grove_power(P0_6),
+    grv_sel2a(P0_19), grv_sel2g(P0_18), grv_sel1a(P0_17), grv_sel1g(P0_16),
+    grv_p1s1a(P0_2), grv_p1s2a(P0_1),
+    grv_p2s1a(P0_4), grv_p2s2a(P0_3)
+{
+    this->led_state = LED_OFF;
+    this->led = 0;
+    this->serial = new RawSerial(P0_9, P0_11);
+    this->serial->baud(9600); /* use for LoRa */
+    this->pwr_en = 1; // メイン電源投入
+    this->lora_power = 0;
+    this->lora_reset = 0;
+    this->grove_power = 0;
+    this->lora_enabled = false;
+    this->grove_enabled = false;
+    // Grove端子をHiZに
+    this->grv_sel1g = 1;
+    this->grv_sel1a = 1;
+    this->grv_sel2g = 1;
+    this->grv_sel2a = 1;
+    grv_p1s1do = NULL, grv_p1s2do = NULL, grv_p1s1di = NULL, grv_p1s2di = NULL;
+    grv_p2s1do = NULL, grv_p2s2do = NULL, grv_p2s1di = NULL, grv_p2s2di = NULL;
+    temp_humid_sensor = NULL;
+}
+
+int Eeabp1::setLedState(EeabLedState state)
+{
+    this->led_state = state;
+
+    if (this->led_state == LED_OFF) {
+        this->led = 0;
+    } else {
+        this->led = 1;
+    }
+
+    return 0;
+}
+
+void Eeabp1::loop(void)
+{
+    switch (this->led_state) {
+        case LED_OFF:
+            /* fall through */
+        case LED_ON:
+            break;
+        case LED_BLINK_FAST:
+        case LED_BLINK_MID:
+        case LED_BLINK_SLOW:
+            this->led = !this->led;
+            break;
+    }
+}
+
+int Eeabp1::debug(const char * format, ...)
+{
+    char tmp[80];
+    int ret;
+
+    std::va_list arg;
+    va_start(arg, format);
+    vsnprintf(tmp, sizeof(tmp), format, arg);
+    va_end(arg);
+
+    delete this->serial;
+    this->serial = new RawSerial(P0_8, P0_10);
+    ret = this->serial->puts(tmp);
+    delete this->serial;
+    this->serial = new RawSerial(P0_9, P0_11);
+
+    return ret;
+}
+
+int Eeabp1::setLoRaPower(bool on)
+{
+    int ret;
+
+    if (on) {
+        if (lora_enabled)
+            return 0;  /* power is already on, do nothing */
+
+        this->lora_power= 1;
+        this->lora_reset = 1;
+        wait_us(500000);
+        serial->printf("mod set_echo off\r\n"); // ローカルエコー:無効
+        wait(1);
+        flushSerial();
+        serial->printf("mod factory_reset\r\n"); // ファクトリーリセットを行い鍵をリフレッシュ
+        ret = chkSerialCharOk();
+        if (ret != 0)
+            return ret;
+        serial->printf("mod set_echo off\r\n"); // ローカルエコー:無効
+        wait(1);
+        serial->printf("lorawan join otaa\r\n"); // Gatewayに接続(OTAA)
+        ret = chkSerialCharRes('a'); // 成功 ">> accepted" 失敗 ">> unsuccess"
+        if (ret != 0)
+            return ret;
+        serial->printf("lorawan set_dr 2\r\n"); // データレートの設定(11byte)
+        ret = chkSerialCharOk();
+        if (ret != 0)
+            return ret;
+
+        this->lora_enabled = true;
+    } else { /* off */
+        if (!lora_enabled)
+            return 0;  /* power is already off, do nothing */
+
+        lora_power= 0;
+        lora_enabled = false;
+    }
+
+    return 0;
+}
+
+int Eeabp1::sendLoRaString(const char * format, ...)
+{
+    char str[lora_msg_max_len+1] = {0x00, };
+    char msg[64];
+    char *p = msg;
+
+    std::va_list arg;
+    va_start(arg, format);
+    vsnprintf(str, sizeof(str), format, arg);
+    va_end(arg);
+
+    p += sprintf(msg, "lorawan tx ucnf 16 ");
+    for (unsigned int i = 0; i < strlen(str); i++) {
+        p += sprintf(p, "%02x", str[i]);
+    }
+    sprintf(p, "\r\n");
+
+    flushSerial();
+    serial->puts(msg);
+
+    return 0;
+}
+
+int Eeabp1::sendLoRaBinary(const char *payload, size_t len)
+{
+    char msg[64];
+    char *p = msg;
+
+    if (lora_msg_max_len < len)
+        return -1;
+
+    p += sprintf(msg, "lorawan tx ucnf 16 ");
+    for (unsigned int i = 0; i < len; i++) {
+        p += sprintf(p, "%02x", payload[i]);
+    }
+    sprintf(p, "\r\n");
+
+    flushSerial();
+    serial->puts(msg);
+
+    return 0;
+}
+
+void Eeabp1::setGrovePower(bool on)
+{
+    if (on) {
+        if (grove_enabled)
+            return; /* power is already on, do nothing */
+
+        grove_power = 1;
+    } else {
+        if (!grove_enabled)
+            return; /* power is already off, do nothing */
+        
+        // Grove端子をHiZに
+        grv_sel1g = 1;
+        grv_sel1a = 1;
+        grv_sel2g = 1;
+        grv_sel2a = 1;
+        grove_power = 0;
+    }
+}
+
+int Eeabp1::setGrovePortType(EeabGrovePort port, EeabGrovePortType type)
+{
+    switch (port) {
+        case GROVE_CH1:
+            if (type == GROVE_ANALOG) {
+                grv_sel1g = 1;
+                grv_sel1a = 0;
+            } else {
+                grv_sel1g = 0;
+                grv_sel1a = 1;
+            }
+            break;
+        case GROVE_CH2:
+            if (type == GROVE_ANALOG) {
+                grv_sel2g = 1;
+                grv_sel2a = 0;
+            } else {
+                grv_sel2g = 0;
+                grv_sel2a = 1;
+            }
+            break;
+        default:
+            /* do nothing */
+            break;
+    }
+
+    return 0;
+}
+
+int Eeabp1::setGroveDioDirection(EeabGrovePort port, EeabGroveDioDirection dir, Callback<void()> f)
+{
+    switch (port) {
+        case GROVE_CH1:
+            if(dir == GROVE_DIO_OUT) {
+                if (grv_p1s1di) {
+                    delete grv_p1s1di;
+                    grv_p1s1di = NULL;
+                }
+                grv_p1s1do = new DigitalOut(P0_13);
+
+                if (grv_p1s2di) {
+                    delete grv_p1s2di;
+                    grv_p1s2di = NULL;
+                }
+                grv_p1s2do = new DigitalOut(P0_12);
+            } else { /* GROVE_DIO_IN */
+                if (grv_p1s1do) {
+                    delete grv_p1s1do;
+                    grv_p1s1do = NULL;
+                }
+                grv_p1s1di = new InterruptIn(P0_13);
+                if (f)
+                    grv_p1s1di->rise(f);
+
+                if (grv_p1s2do) {
+                    delete grv_p1s2do;
+                    grv_p1s2do = NULL;
+                }
+                grv_p1s2di = new InterruptIn(P0_12);
+                grv_p1s2di->rise(f);
+            }
+            break;
+        case GROVE_CH2:
+            if(dir == GROVE_DIO_OUT) {
+                if (grv_p2s1di) {
+                    delete grv_p2s1di;
+                    grv_p2s1di = NULL;
+                }
+                grv_p2s1do = new DigitalOut(P0_15);
+
+                if (grv_p2s2di) {
+                    delete grv_p2s2di;
+                    grv_p2s2di = NULL;
+                }
+                grv_p2s2do = new DigitalOut(P0_14);
+            } else { /* GROVE_DIO_IN */
+                if (grv_p2s1do) {
+                    delete grv_p2s1do;
+                    grv_p2s1do = NULL;
+                }
+                grv_p2s1di = new InterruptIn(P0_15);
+                if (f)
+                    grv_p2s1di->rise(f);
+
+                if (grv_p2s2do) {
+                    delete grv_p2s2do;
+                    grv_p2s2do = NULL;
+                }
+                grv_p2s2di = new InterruptIn(P0_14);
+                grv_p2s2di->rise(f);
+            }
+            break;
+        default:
+            /* do nothing */
+            break;
+    }
+
+    return 0;
+}
+
+int Eeabp1::setGroveDio(EeabGrovePort port, EeabGroveDio val)
+{
+    switch (port) {
+        case GROVE_CH1:
+            *grv_p1s1do = val;
+            *grv_p1s2do = val;
+            break;
+        case GROVE_CH2:
+            *grv_p2s1do = val;
+            *grv_p2s2do = val;
+            break;
+        default:
+            break;
+    }
+
+    return 0;
+}
+
+int Eeabp1::setGroveDio(EeabGrovePort port, EeabGroveSig sig , EeabGroveDio val)
+{
+    switch (port) {
+        case GROVE_CH1:
+                    (sig == GROVE_SIG1) ? *grv_p1s1do = val : *grv_p1s2do = val;
+            break;
+        case GROVE_CH2:
+                    (sig == GROVE_SIG1) ? *grv_p2s1do = val : *grv_p2s2do = val;
+            break;
+        default:
+            break;
+    }
+    return 0;
+}
+
+
+int Eeabp1::getGroveDio(EeabGrovePort port, EeabGroveSig sig)
+{
+    switch (port) {
+        case GROVE_CH1:
+            if (grv_p1s1di == NULL)
+                return -1;
+            return (sig == GROVE_SIG1) ?
+                grv_p1s1di->read() : grv_p1s2di->read();
+        case GROVE_CH2:
+            if (grv_p2s1di == NULL)
+                return -1;
+            return (sig == GROVE_SIG1) ?
+                grv_p2s1di->read() : grv_p2s2di->read();
+        default:
+            break;
+    }
+
+    return -1;
+}
+
+float Eeabp1::getGroveAnalog(EeabGrovePort port, EeabGroveSig sig)
+{
+    switch (port) {
+        case GROVE_CH1:
+            return (sig == GROVE_SIG1) ?
+                grv_p1s1a.read() : grv_p1s2a.read();
+        case GROVE_CH2:
+            return (sig == GROVE_SIG1) ?
+                grv_p2s1a.read() : grv_p2s2a.read();
+        default:
+            break;
+    }
+
+    return -1;
+}
+
+int Eeabp1::enableTempHumidSensor(void)
+{
+    temp_humid_sensor = new Sht31(P0_30, P0_7);    
+    return 0;
+}
+
+float Eeabp1::getTemp(void)
+{
+    if (!temp_humid_sensor)
+        return -1;
+
+    return temp_humid_sensor->readTemperature();
+}
+
+float Eeabp1::getHumid(void)
+{
+    if (!temp_humid_sensor)
+        return -1;
+
+    return temp_humid_sensor->readHumidity();
+}
+
+int Eeabp1::enableAccelerometer(void)
+{
+    accelerometer = new ADXL345_I2C(P0_30, P0_7);
+
+    this->debug("Device ID is: 0x%02x\n", accelerometer->getDeviceID());
+    wait(.001);
+    
+    // These are here to test whether any of the initialization fails. It will print the failure
+    if (accelerometer->setPowerControl(0x00)) {
+         this->debug("didn't intitialize power control\n"); 
+         return -1;
+    }
+    wait(.001);
+     
+    //Full resolution, +/-16g, 4mg/LSB.
+    if(accelerometer->setDataFormatControl(0x0B)) {
+        this->debug("didn't set data format\n");
+        return -1;
+    }
+     wait(.001);
+     
+    //3.2kHz data rate.
+    if(accelerometer->setDataRate(ADXL345_3200HZ)) {
+        this->debug("didn't set data rate\n");
+        return -1;
+    }
+    wait(.001);
+     
+    //Measurement mode.
+    if(accelerometer->setPowerControl(MeasurementMode)) {
+        this->debug("didn't set the power control to measurement\n");
+        return -1;
+    }
+    
+    return 0;
+}
+
+int Eeabp1::getAcc(int *x, int *y, int *z)
+{
+    int readings[3] = {0, 0, 0};
+    accelerometer->getOutput(readings);
+    *x = readings[0];
+    *y = readings[1];
+    *z = readings[2];
+    
+    return 0;
+}
+
+/* private functions */
+void Eeabp1::flushSerial()
+{
+    while(serial->readable() == true) {
+        serial->getc();
+        wait_us(1000);
+    }
+}
+
+int Eeabp1::chkSerialChar(const char ch,uint16_t timeout_ms)
+{
+    uint32_t timeoutCount = 0;
+
+    while(serial->readable() == false) {
+        wait_us(50);
+        timeoutCount++;
+        if((timeoutCount  / 20) >= timeout_ms)
+            return -2;
+    }
+
+    return (serial->getc() == ch) ? 0 : -1;
+}
+
+int Eeabp1::waitSerialChar(const char ch,uint16_t timeout_ms)
+{
+    uint32_t timeoutCount = 0;
+
+    do {
+        while(serial->readable() == false) {
+            wait_us(50);
+            timeoutCount++;
+            if((timeoutCount  / 20) >= timeout_ms)
+                return -2;
+        }
+    } while(serial->getc() != ch);
+
+    return 0;
+}
+
+int Eeabp1::chkSerialCharOk()
+{
+    int ret;
+    ret = waitSerialChar('>',4000);
+    if (ret != 0)
+        return __LINE__;
+
+    ret = chkSerialChar('>',2000);
+    if (ret != 0)
+        return __LINE__;
+
+    ret = chkSerialChar(' ',2000);
+    if (ret != 0)
+        return __LINE__;
+
+    ret = chkSerialChar('O',2000);
+    if (ret != 0)
+        return __LINE__;
+
+    ret = chkSerialChar('k',2000);
+    if (ret != 0)
+        return __LINE__;
+
+    ret = waitSerialChar('>',4000);
+    if (ret != 0)
+        return __LINE__;
+
+    wait_us(1000);
+
+    return 0;
+}
+
+int Eeabp1::chkSerialCharRes(char chkchr)
+{
+    int ret;
+    ret = waitSerialChar('>', 10000);
+    if (ret != 0)
+        return __LINE__;
+
+    ret = chkSerialChar('>',2000);
+    if (ret != 0)
+        return __LINE__;
+
+    ret = chkSerialChar(' ',2000);
+    if (ret != 0)
+        return __LINE__;
+
+    ret = chkSerialChar('O',2000);
+    if (ret != 0)
+        return __LINE__;
+
+    ret = chkSerialChar('k',2000);
+    if (ret != 0)
+        return __LINE__;
+
+    ret = waitSerialChar('>',16000);
+    if (ret != 0)
+        return __LINE__;
+
+    ret = chkSerialChar('>',2000);
+    if (ret != 0)
+        return __LINE__;
+
+    ret = chkSerialChar(' ',2000);
+    if (ret != 0)
+        return __LINE__;
+
+    ret = waitSerialChar(chkchr,4000);
+    if (ret != 0)
+        return __LINE__;
+
+    ret = waitSerialChar('>',4000);
+    if (ret != 0)
+        return __LINE__;
+
+    wait_us(1000);
+
+    return 0;
+}