IM920のライブラリ
Diff: IM920.cpp
- Revision:
- 0:ccdeb3bea793
- Child:
- 1:11ae0d702ecc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/IM920.cpp Thu Aug 10 19:34:50 2017 +0000 @@ -0,0 +1,382 @@ +#include "IM920.h" +#include "mbed.h" + +short IM920::toShort(char *array){ + im920_cast.s = ((uint16_t)array[0] << 8) | (uint16_t)array[1]; + return im920_cast.s; +} +int IM920::toInt(char *array){ + im920_cast.i = ((uint32_t)array[0] << 24) | ((uint32_t)array[1] << 16) | ((uint32_t)array[2] << 8) | (uint32_t)array[3]; + return im920_cast.i; +} +float IM920::toFloat(char *array){ + im920_cast.u[0] = array[0]; + im920_cast.u[1] = array[1]; + im920_cast.u[2] = array[2]; + im920_cast.u[3] = array[3]; + + return im920_cast.f; +} +long IM920::toLong(char *array){ + for(int i = 0; i < 8; i++){ + im920_cast.u[i] = array[i]; + } + return im920_cast.l; +} +double IM920::toDouble(char *array){ + for(int i = 0; i< 8; i++){ + im920_cast.u[i] = array[i]; + } + return im920_cast.d; +} + +void IM920::dummyFunc(){ + printf("NO FUNCTION\r\n"); +}; + +char IM920::im920CheckSum(int count){ + char ans = 0; + for(int i = 0; i < count; i++){ + ans = ans ^ data[i]; + } + return ans; +} + +IM920::IM920(Serial &serial, Serial &pc, int baudrate){ + + ser = &serial;//参照渡し + _pc = &pc; + + ser->baud(baudrate); + + memset(buff_A, '\0', IM920_BUFF_SIZE); + memset(buff_B, '\0', IM920_BUFF_SIZE); + readBuffAddr = buff_B; + writeBuffAddr = buff_A; + sendDataSize = 0; + interactiveFlag = 0; + for(int i = 0;i < 256; i++){ + p_callFunc[i] = &this->dummyFunc; + } + memset(data, 0, 64); + im920_dataLength = 0; + memset(im920_sendBuff, '\0', 129); + sendDataSize = 0; + nodeNumber = 0; + AS = DATA_STRING; + checkSum = 0; + for(int i = 0; i < 8; i++){ + im920_cast.u[i] = 0; + } + node = 0; + RSSI = 0; + rID = 0; + ID = 0; + + receiveCheckSum = 0; + ser->attach(this, &IM920::im920Handler, Serial::RxIrq); +} + + + + + + +void IM920::im920_debug(){ + printf("%s\r\n", readBuffAddr); + return; +} + + + +int IM920::asciiToNumber(char c){ + //printf("%c ", c); + if((int)c >= 65){//A ~ F + return ((int)c - 55); + } + else{//0 ~ 9 + return ((int)c - 48); + } +} + +void IM920::data_analyze(){ + //00,0001,78:01,02,03,04,...,FF\0 + //| | | | +- <CR><LF>文字列終了 + //| | | +-------------------- 16進数をascii文字にしたもの、最大64区切り(64Byte) + //| | +----------------------- 受信強度、RSSI値 + //| +---------------------------- 送信モジュールの固有ID + //+------------------------------- ノード番号 + char tempStr[160]; + strcpy(tempStr, readBuffAddr); + char *tok = strtok(tempStr, ",");//ノード番号 + node = ((asciiToNumber(tok[0]) << 4)) | asciiToNumber(tok[1]); + tok = strtok(NULL, ",");//送信機のID + rID = 0; + rID = (asciiToNumber(tok[0]) << 12) | (asciiToNumber(tok[1]) << 8) | (asciiToNumber(tok[2]) << 4) | asciiToNumber(tok[3]); + tok = strtok(NULL, ":");//受信強度 + RSSI = (char)((asciiToNumber(tok[0]) << 4) | (asciiToNumber(tok[1]))); + im920_dataLength = 64; + memset(data, 0, 64); + receiveCheckSum = 0; + if(tok != NULL){ + for(int i = 0; i < 64; i++){ + if(tok[0] == '\0'){ + im920_dataLength = i - 1; + break; + } + tok = strtok(NULL, ","); + data[i] = (asciiToNumber(tok[0]) << 4) | asciiToNumber(tok[1]); + receiveCheckSum = receiveCheckSum ^ tok[0] ^ tok[1]; + } + } + else{ + im920_dataLength = 0; + } + return; +} + +void IM920::im920Handler(){ + static int current = 0; + static char c = 0; + c = ser->getc(); + if(AS == RESPONSE_STRING || AS == INTERACTIVE_STRING){ + printf("%c", c);//描画、後で1行描画だと次の行がすぐ来た時にハングアップしてしまう + } + + if(c == '\r'){//文字列終了 + writeBuffAddr[current] = '\0'; + if(AB == BUFF_A){//現在バッファAに書き込み中 + readBuffAddr = buff_A; + writeBuffAddr = buff_B; + AB = BUFF_B; + } + else{//現在バッファBに書き込み中 + readBuffAddr = buff_B; + writeBuffAddr = buff_A; + AB = BUFF_A; + } + + //im920_debug(); + //---------------------- + // 文字列の解析 + //---------------------- + if(AS == DATA_STRING){//データの形式によって分岐 + if(current > 9){ + //データの取り出し、配列化 + data_analyze(); + for(int i = 0;i < 64;i++){ + printf("%d ",data[i]); + } + printf("\r\n"); + //printf("header: %0X\r\n",(uint8_t)data[0]); + //header0xFF(); + // 関数の呼び出し + (*p_callFunc[(uint8_t)data[0]])(); + } + } + //初期化 + current = 0; + //memset(writeBuffAddr, '\0', IM920_BUFF_SIZE); + return; + } + else if(c !='\n'){ + //文字列生成 + writeBuffAddr[current] = c; + current++; + if(current >= IM920_BUFF_SIZE){//初期化 + current = 0; + memset(writeBuffAddr, '\0', IM920_BUFF_SIZE); + } + return; + } +} + +void IM920::attach(void (*funcAddr)(void), unsigned header){ + p_callFunc[header] = funcAddr; + return; +} + +/** + @bref パラメータ不揮発メモリ書き込み許可モードへ移行 +*/ +bool IM920::enableWrite(){ + AS = RESPONSE_STRING;//レスポンス受信モードへ移行 + ser->printf("ENWR\r\n"); + wait_us(WAIT_TIME_US);//待つ + AS = DATA_STRING; //データ受信モードへ以降 + if(strncmp(readBuffAddr, "OK", 2) == 0){ + return true; + } + else{ + return false; + } +} + +bool IM920::disableWrite(){ + AS = RESPONSE_STRING;//レスポンス受信モードへ移行 + ser->printf("DSWR\r\n"); + wait_us(WAIT_TIME_US); + AS = DATA_STRING; + if(strncmp(readBuffAddr, "OK", 2) == 0){ + return true; + } + else{ + return false; + } +} + +/** + @bref 固有IDを読み出す +*/ +int IM920::readID(){ + AS = NORMAL_STRING; + ser->printf("RDID\r\n"); + wait_us(WAIT_TIME_US); + AS = DATA_STRING; + int val = 0; + + //pc.printf("%c:%c:%c:%c\r\n",readBuffAddr[0],readBuffAddr[1],readBuffAddr[2],readBuffAddr[3]); + val = asciiToNumber(readBuffAddr[0]) << 24; + val |= asciiToNumber(readBuffAddr[1]) << 16; + val |= asciiToNumber(readBuffAddr[2]) << 8; + val |= asciiToNumber(readBuffAddr[3]); + ID = val; + return val; +} + +bool IM920::setReceiveID(int ID){ + AS = RESPONSE_STRING; + printf("SRID %4X\r\n", ID); + ser->printf("SRID %4X\r\n", ID); + wait_us(WAIT_TIME_US); + if(strncmp(readBuffAddr, "OK", 2) == 0){ + return true; + } + else{ + return false; + } +} + +bool IM920::setChannel(char ch){ + AS = RESPONSE_STRING; + printf("STCH %2d\r\n", ch); + ser->printf("STCH %4d\r\n", ch); + wait_us(WAIT_TIME_US); + AS = DATA_STRING; + if(strncmp(readBuffAddr, "OK", 2) == 0){ + return true; + } + else return false; +} + +char IM920::readChannel(){ + AS = RESPONSE_STRING; + printf("RDCH\r\n"); + ser->printf("RDCH\r\n"); + wait_us(WAIT_TIME_US); + AS = DATA_STRING; + if(strncmp(readBuffAddr, "OK", 2 ) == 0){ + return true; + } + else{ + return false; + } +} + +bool IM920::enableCharacterIO(){ + AS = RESPONSE_STRING; + printf("ECIO\r\n"); + ser->printf("ECIO\r\n"); + wait_us(WAIT_TIME_US); + AS = DATA_STRING; + if(strncmp(readBuffAddr, "OK", 2) == 0){ + return true; + } + else{ + return false; + } +} + +bool IM920::disableCharacterIO(){ + AS = RESPONSE_STRING; + printf("DCIO\r\n"); + ser->printf("DCIO\r\n"); + wait_us(WAIT_TIME_US); + AS = DATA_STRING; + if(strncmp(readBuffAddr, "OK", 2) == 0){ + return true; + } + else{ + return false; + } +} +void IM920::printFormat(){ + _pc->printf("-----------------------\r\n"); + _pc->printf(" ENWR : EEPROMへの書き込みを許可\r\n"); + _pc->printf(" DSWR : EEPROMへの書き込みを禁止\r\n"); + _pc->printf(" RDID : 固有IDを読み出す\r\n"); + _pc->printf(" STNN パラメータ : ノード番号を設定,00~FF\r\n"); + _pc->printf(" RDNN : ノード番号を読み出す\r\n"); + _pc->printf(" SRID XXXX : 受信ID設定,0000~FFFF\r\n"); + _pc->printf(" RRID : 受信IDを読み出す\r\n"); + _pc->printf(" ERID : 設定された受信IDの全消去\r\n"); + _pc->printf(" STCH XX : チャンネル設定,01~15\r\n"); + _pc->printf(" RDCH : チャンネル読み出し\r\n"); + _pc->printf(" ECIO : キャラクタ入出力設定\r\n"); + _pc->printf(" DCIO : キャラクタ入出力設定解除\r\n"); + _pc->printf(" TXDT data : 8バイトデータ送信,dataは16進数をASCII文字で入力\r\n"); + _pc->printf(" TXDA data : 1~64バイトデータ送信,dataは16進数をASCII文字で入力\r\n"); + _pc->printf(" RDRS : RSSI値読み出し\r\n"); + _pc->printf(" STPO 送信出力 : 1~3で入力, 1:0.1mW, 2:1mW, 3:10mW\r\n"); + _pc->printf(" RDPO : 送信出力読み出し\r\n"); + _pc->printf(" STRT 速度値 : 無線通信速度設定, 1:高速(50kbps), 2:長距離(1.25kbps)\r\n"); + _pc->printf(" RDRT : 無線通信速度を読み出す\r\n"); + _pc->printf(" RDVR : 製品バージョンの読み出し\r\n"); + _pc->printf(" ERPT : 簡易中継ON\r\n"); + _pc->printf(" DRPT : 簡易中継OFF\r\n"); + _pc->printf(" RPRM : パラメータ一括読み出し\r\n"); + _pc->printf(" SRST : ソフトウェアリセット\r\n"); + _pc->printf(" PCLR : パラメータクリア\r\n"); + _pc->printf("-----------------------\r\n"); +} +void IM920::interactiveMode(){ + AS = INTERACTIVE_STRING; + //interactiveFlag = 1; + int current = 0; + static char buf[IM920_BUFF_SIZE] = {'\0'}; + memset(buf, '\0', IM920_BUFF_SIZE); + _pc->printf("Start Interactive mode!!\r\n"); + printFormat(); + while(1){ + if(_pc->readable()){ + char ccc = _pc->getc(); + + if(ccc == '@'){ + _pc->printf("Interactive mode finish!!\r\n"); + break; + } + if(ccc == '\r'){ + _pc->printf("\r\n"); + buf[current] = '\0'; + + ser->printf("%s\r\n", buf); + current = 0; + memset(buf, '\0', IM920_BUFF_SIZE); + wait(1.0); + printFormat(); + while(_pc->readable()){ _pc->getc();} + } + else if(ccc != '\n'){ + _pc->printf("%c", ccc); + buf[current] = ccc; + current++; + if(current >= 160){ + current = 0; + memset(buf, '\0', IM920_BUFF_SIZE); + } + } + } + } + AS = DATA_STRING; + return; +} \ No newline at end of file