library for enebular edge agent board(version p1)
Eeabp1.cpp
- Committer:
- koyo_take
- Date:
- 2017-10-22
- Revision:
- 2:d48fcae8b5bd
- Parent:
- 1:da9fd2252ed5
- Child:
- 3:f80f2838a956
File content as of revision 2:d48fcae8b5bd:
#include "Eeabp1.h" #include <string.h> 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; } static char linebuf[64]; int Eeabp1::setLoRaPower(bool on) { int ret; int retry; const int retry_max = 10; 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); for(retry=0; retry < retry_max; retry++) { serial->printf("lorawan join otaa\r\n"); // Gatewayに接続(OTAA) ret = chkSerialCharRes('a'); // 成功 ">> accepted" 失敗 ">> unsuccess" if (ret == 0) break; wait(10); } if (retry == retry_max) return __LINE__; 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::sendLoRaStringAndReceiveResponse(char res[], const char * format, ...) { char str[lora_msg_max_len+1] = {0x00, }; char msg[64]; char *p = msg; // int count; char *tp; int ret; std::va_list arg; va_start(arg, format); vsnprintf(str, sizeof(str), format, arg); va_end(arg); p += sprintf(msg, "lorawan tx ucnf 3 "); for (unsigned int i = 0; i < strlen(str); i++) { p += sprintf(p, "%02x", str[i]); } sprintf(p, "\r\n"); flushSerial(); serial->puts(msg); getline(linebuf, sizeof(linebuf), 10000); // count = getline(linebuf, sizeof(linebuf), 10000); // this->debug("%d '%s'\r\n", count, linebuf); ret = -1; res[0] = '\0'; tp = strtok(linebuf, " \r\n"); while(tp != NULL){ // this->debug("%s\r\n", tp); if (strcmp(tp, "tx_ok") == 0) { ret = 0; } else if (strcmp(tp, "err") == 0) { ret = -2; } else if (strcmp(tp, "rx") == 0) { // this->debug("rx found\r\n"); tp = strtok(NULL, " \r\n"); // this->debug("%s\r\n", tp); tp = strtok(NULL, " \r\n"); // this->debug("%s\r\n", tp); strcpy(res, tp); } tp = strtok(NULL, " \r\n"); } return ret; } 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); } } inline ssize_t Eeabp1::getline(char *buf, size_t bufsize, int timeout_ms) { char c; size_t receivedChars = 0; Timer t; t.start(); *buf = '\0'; do { if (!serial->readable()) { wait_us(50); continue; } c = serial->getc(); /* if (c == '\r' || c == '\n') { if (receivedChars == 0) { continue; //Ignore if first character is delimiter } if (serial->readable()) { continue; //continue to read next line } break; } */ if (receivedChars < bufsize - 1) { *buf++ = c; receivedChars++; } } while(t.read_ms() < timeout_ms); *buf++ = '\0'; t.stop(); return receivedChars; } 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; }