library for enebular edge agent board(version p1)
Diff: Eeabp1.cpp
- 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; +}