test
Dependencies: BufferedSerial WatchdogTimer
main.cpp
- Committer:
- harada_jpms
- Date:
- 2018-06-08
- Revision:
- 3:455575531b33
- Parent:
- 2:a88b0b4c4f37
- Child:
- 4:1920e4a63bde
File content as of revision 3:455575531b33:
// Include -------------------------------------------------------------------- #include "mbed.h" #include "BLE.h" #include "DiscoveredCharacteristic.h" #include "DiscoveredService.h" #include "UARTService.h" // Definition ----------------------------------------------------------------- #define NUM_ONCE 20 #define BFSIZE (NUM_ONCE+4) #define SOFT_DEVICE_FATHER_HANDLE 3 // Object --------------------------------------------------------------------- BLE& ble_uart = BLE::Instance(); Serial pc(P0_1, P0_3, 115200); // DEBUG BOARD //Serial pc(P0_9, P0_11, 115200); // NEW BOARD Ticker main_timer; // メインタイ216 DigitalOut led(P0_6); DigitalOut state(P0_24); // DEBUG BOARD //DigitalOut state(P0_3); // NEW BOARD // ROM / Constant data -------------------------------------------------------- Gap::Address_t mac_board_0 = {0xFF, 0x42, 0xD5, 0x9C, 0x9C, 0xE1}; // RAM ------------------------------------------------------------------------ Gap::Handle_t connectionHandle = 0xFFFF; DiscoveredCharacteristic uartTXCharacteristic; DiscoveredCharacteristic uartRXCharacteristic; bool foundUartRXCharacteristic = false; bool connected2server = false; bool connection_tx = false; bool connection_rx = false; UARTService * uartServicePtr = NULL; Gap::Address_t my_mac; int my_board_index = -1; bool received_uart_dat = false; int8_t uart_buffer[BFSIZE]; uint8_t uart_bf_len; volatile bool rx_isr_busy = false; unsigned long mac_1; unsigned long mac_2; unsigned long mac_3; #define SIO_BUF_SIZE 256 /* SIO リングバッファーサイズ (1K byte) */ typedef struct { unsigned short data_cnt; /* リング・バッファ データカウント */ unsigned short rp; /* リング・バッファ Read ポインタ */ unsigned short wp; /* リング・バッファ Write ポインタ */ unsigned char buf[SIO_BUF_SIZE]; /* リング・バッファ */ } ring_cnt_t; /* リング・バッファ 制御用構造体 */ ring_cnt_t pc_uart_buf; // 通信用リングバッファ ring_cnt_t pc_cmd_buf; // 通信用コマンドバッファ ring_cnt_t ble_uart_buf; // 通信用リングバッファ ring_cnt_t ble_cmd_buf; // 通信用コマンドバッファ int timer_cnt; int timer_cnt_d; // Function prototypes -------------------------------------------------------- // BLE void advertisementCallback(const Gap::AdvertisementCallbackParams_t *); void serviceDiscoveryCallback(const DiscoveredService *); void characteristicDiscoveryCallback(const DiscoveredCharacteristic *); void discoveryTerminationCallback(Gap::Handle_t ); void onReceivedDataFromDeviceCallback(const GattHVXCallbackParams *); void connectionCallback(const Gap::ConnectionCallbackParams_t *); void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *); // Pre-check bool mac_equals(const Gap::Address_t, const Gap::Address_t); int get_board_index(const Gap::Address_t); void uart_init(); void main_timer_proc(); unsigned int atow(char *str,unsigned short leng); unsigned long atoh(char *str,unsigned short leng); void ble_rs232c_cmd(); void pc_rs232c_cmd(); void ble_write(char* dat); //------------------------------------------------------------------------------ // Control Program //------------------------------------------------------------------------------ int main(void) { uart_init(); // メインタイマー設定(1ms) main_timer.attach(&main_timer_proc, 0.001); // opening message pc.printf("UART Communication / Client(Central) side\r\n"); pc.printf(" need Server module (run BLE_Uart_Server program)\r\n"); // Mixed role ************************************************************** ble_uart.init(); ble_uart.gap().onConnection(connectionCallback); ble_uart.gap().onDisconnection(disconnectionCallback); // Client(Central) role **************************************************** ble_uart.gattClient().onHVX(onReceivedDataFromDeviceCallback); ble_uart.gap().setScanParams(500, 450); //ble_uart.gap().startScan(advertisementCallback); while(true) { // allow notifications from Server(Peripheral) if (foundUartRXCharacteristic && !ble_uart.gattClient().isServiceDiscoveryActive()) { // need to do the following only once foundUartRXCharacteristic = false; uint16_t value = BLE_HVX_NOTIFICATION; ble_uart.gattClient().write( GattClient::GATT_OP_WRITE_REQ, connectionHandle, uartRXCharacteristic.getValueHandle() + 1, sizeof(uint16_t), reinterpret_cast<const uint8_t *>(&value) ); } // タイマーカウント更新時(1ms以上経過している) if( timer_cnt != timer_cnt_d ) { timer_cnt_d = timer_cnt; state = connected2server; led = connected2server; //ble_rs232c_cmd(); pc_rs232c_cmd(); } ble_uart.waitForEvent(); } } void onReceivedDataFromDeviceCallback(const GattHVXCallbackParams *params) { if (params->type == BLE_HVX_NOTIFICATION) { if ((params->handle == uartRXCharacteristic.getValueHandle()) && (params->len > 0)) { uart_bf_len = params->len; strcpy((char *)uart_buffer, (char *)params->data); received_uart_dat = true; ble_rs232c_cmd(); } } } bool mac_equals(const Gap::Address_t mac_1, const Gap::Address_t mac_2) { for (int i = 0; i < 6; i++) { } for (int i = 0; i < 6; i++) { if (mac_1[i] != mac_2[i]) { return false; } else { } } return true; } int get_board_index(const Gap::Address_t mac) { if (mac_equals(mac, mac_board_0)) { return 0; } #if 0 if (mac_equals(mac, mac_board_1)) { return 1; } if (mac_equals(mac, mac_board_2)) { return 2; } if (mac_equals(mac, mac_board_3)) { return 3; } if (mac_equals(mac, mac_board_4)) { return 4; } #endif return -1; } // Client(Central) role ******************************************************** void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) { // connections int peer_board_index = get_board_index(params->peerAddr); if (peer_board_index != -1) { pc.printf(""); pc.printf( "adv peerAddr [%02x %02x %02x %02x %02x %02x]\r\n", params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0] ); pc.printf( "rssi=%+4d, isScanResponse %u, AdvertisementType %u\r\n", params->rssi, params->isScanResponse, params->type ); ble_uart.gap().connect( params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL); } } void serviceDiscoveryCallback(const DiscoveredService *service) { if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { } else { const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { } } } void characteristicDiscoveryCallback( const DiscoveredCharacteristic *characteristicP) { if (characteristicP->getUUID().getShortUUID() == UARTServiceTXCharacteristicShortUUID) { uartTXCharacteristic = *characteristicP; connection_tx = true; } else if (characteristicP->getUUID().getShortUUID() == UARTServiceRXCharacteristicShortUUID) { uartRXCharacteristic = *characteristicP; foundUartRXCharacteristic = true; connection_rx = true; } } void discoveryTerminationCallback(Gap::Handle_t connectionHandle) { } // Mixed role ****************************************************************** void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { if (params->role == Gap::CENTRAL) { pc.printf("connected as Client(Central) (handle = %d)\r\n\r", params->handle); connected2server = true; connectionHandle = params->handle; ble_uart.gattClient().onServiceDiscoveryTermination( discoveryTerminationCallback); ble_uart.gattClient().launchServiceDiscovery( params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback ); } pc.printf( "Client(Central/Myself) %02x:%02x:%02x:%02x:%02x:%02x\r\n", params->ownAddr[5], params->ownAddr[4], params->ownAddr[3], params->ownAddr[2], params->ownAddr[1], params->ownAddr[0] ); pc.printf( "Connected Server(Peripheral) %02x:%02x:%02x:%02x:%02x:%02x\r\n", params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0] ); } void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { pc.printf(" -> disconnected\r\n", params->handle); connected2server = false; // connection_1st = false; connection_tx = false; connection_rx = false; #if 0 if (params->handle == SOFT_DEVICE_FATHER_HANDLE) { ble_uart.startAdvertising(); // restart advertising } else { ble_uart.gap().startScan(advertisementCallback);// restart scan } #endif } /****************************************************************************/ /* 関数名 : uart_init */ /* 概要 : 通信初期化 */ /* 作成者 : JPMS H.Harada */ /* 作成日 : 2017.08.30 */ /****************************************************************************/ void uart_init() { int k; // 初期化時のごみを出力 while( pc.readable() ) { pc.getc(); } // UART バッファ初期化 /////////////////////////////////////////////// pc_uart_buf.data_cnt = 0; pc_uart_buf.rp = 0; pc_uart_buf.wp = 0; ble_uart_buf.data_cnt = 0; ble_uart_buf.rp = 0; ble_uart_buf.wp = 0; for(k=0;k<SIO_BUF_SIZE;k++) { pc_uart_buf.buf[k] = 0; ble_uart_buf.buf[k] = 0; } // コマンド バッファ初期化 /////////////////////////////////////////////// pc_cmd_buf.data_cnt = 0; pc_cmd_buf.rp = 0; pc_cmd_buf.wp = 0; ble_cmd_buf.data_cnt = 0; ble_cmd_buf.rp = 0; ble_cmd_buf.wp = 0; for(k=0;k<SIO_BUF_SIZE;k++) { pc_cmd_buf.buf[k] = 0; ble_cmd_buf.buf[k] = 0; } ///////////////////////////////////////////////////////////////// } /****************************************************************************/ /* 関数名 : main_timer_proc */ /* 概要 : メインタイマ処理 */ /* 作成者 : JPMS H.Harada */ /* 作成日 : 2018.02.22 */ /****************************************************************************/ void main_timer_proc() { timer_cnt++; // タイマカウントを加算 } /****************************************************************************/ /* 関数名 : atow */ /* 概要 : アスキー変換処理 */ /* 作成者 : JPMS H.Harada */ /* 作成日 : 2017.08.30 */ /****************************************************************************/ unsigned int atow(char *str,unsigned short leng) { register unsigned short i; unsigned int ret_data = 0; /*---------------- データー長エラー -----------------*/ // if(leng >= 11) // { // ret_data = ATOW_ERROR; /* データエラー */ // } /*---------------- データー長 OK ------------------*/ // else // { i = leng; while(i) { ret_data *= 10; /* 10倍 */ /*------ データ '0' ~ '9' 範囲内 -----*/ if( (*str >= '0') && (*str <= '9') ) { ret_data += (*str) - '0'; str++; } /*------ データ '0' ~ '9' 範囲外 -----*/ else { // ret_data = ATOW_ERROR; /* データエラー */ break; } i--; } /*-------------- データオバーフロー ----------*/ // if(ret_data & 0x8000) // { // ret_data = ATOW_ERROR; /* データエラー */ // } // } return(ret_data); } /****************************************************************************/ /* 関数名 : atoh */ /* 概要 : アスキー変換処理 */ /* 作成者 : JPMS H.Harada */ /* 作成日 : 2017.08.30 */ /****************************************************************************/ unsigned long atoh(char *str,unsigned short leng) { register unsigned short i; unsigned long ret_data = 0; /*---------------- データー長エラー -----------------*/ // if(leng >= 11) // { // ret_data = ATOW_ERROR; /* データエラー */ // } /*---------------- データー長 OK ------------------*/ // else // { i = leng; while(i) { ret_data *= 16; /* 16倍 */ /*------ データ '0' ~ '9' 範囲内 -----*/ if( (*str >= '0') && (*str <= '9') ) { ret_data += (*str) - '0'; str++; } /*------ データ 'A' ~ 'F' 範囲内 -----*/ else if( (*str >= 'A') && (*str <= 'F') ) { ret_data += (*str) - 'A' + 10; str++; } /*------ データ '0' ~ '9' 範囲外 -----*/ else { // ret_data = ATOW_ERROR; /* データエラー */ break; } i--; } /*-------------- データオバーフロー ----------*/ // if(ret_data & 0x8000) // { // ret_data = ATOW_ERROR; /* データエラー */ // } // } return(ret_data); } char ble_str[32][10]; char ble_str2[10][8] = { "P ", "U ", " ", "RESP ", " ", " ", " ", " ", " ", " " }; /****************************************************************************/ /* 関数名 : rs232c_cmd */ /* 概要 : 通信コマンド処理 */ /* 作成者 : JPMS H.Harada */ /* 作成日 : 2017.08.30 */ /****************************************************************************/ void ble_rs232c_cmd() { unsigned int c, i, j; int rdat; for( int i=0; i<uart_bf_len; i++ ) { //pc.putc(uart_buffer[i]); ble_uart_buf.buf[ ble_uart_buf.wp ] = uart_buffer[i]; ble_uart_buf.data_cnt++; if( ble_uart_buf.wp == SIO_BUF_SIZE-1 ) { ble_uart_buf.wp = 0; } else { ble_uart_buf.wp++; } } uart_bf_len = 0; if( ble_uart_buf.data_cnt > 0 ) { unsigned int len = ble_uart_buf.data_cnt; for( c=0; c<len; c++ ) { rdat = ble_uart_buf.buf[ble_uart_buf.rp]; ble_uart_buf.data_cnt--; if( ble_uart_buf.rp == SIO_BUF_SIZE-1 ) { ble_uart_buf.rp = 0; } else { ble_uart_buf.rp++; } if( rdat != '\n' ) { ble_cmd_buf.buf[ble_cmd_buf.data_cnt++] = rdat; } if (rdat == '\r') { int k = 0; int l = 0; int p = 0; for (i=0;i<ble_cmd_buf.data_cnt;i++) { if( ( ( ble_cmd_buf.buf[i] == ' ' ) && ( p > 0 ) ) || ( ble_cmd_buf.buf[i] == '\r') ) { ble_str[k++][l] = '\0'; l = 0; p = 0; } else { p++; ble_str[k][l++] = ble_cmd_buf.buf[i]; } } if( ble_cmd_buf.data_cnt == 1 ) { k = 0; } ble_cmd_buf.data_cnt = 0; ble_cmd_buf.buf[0] = '\0'; if (k > 0) { int ret; int cmd_no = 0xFF; for( j=0; j<10; j++ ) { ret = 1; if( strlen(ble_str[0]) > 0 ) { for( i=0; i<strlen(ble_str[0]); i++ ) { if( ble_str[0][i] != ble_str2[j][i] ) { ret = 0; } } if( ret ) { cmd_no = j; break; } } } // コマンド P if( cmd_no == 0 ) { int data_cnt = atow(ble_str[1], strlen(ble_str[1])); int left = atow(ble_str[2], strlen(ble_str[2])); int right = atow(ble_str[3], strlen(ble_str[3])); pc.printf( "POINT %4d %d %d\r", data_cnt, left, right ); } // コマンド U else if( cmd_no == 1 ) { unsigned int high = atoh(ble_str[1], strlen(ble_str[1])); unsigned int low = atoh(ble_str[2], strlen(ble_str[2])); pc.printf( "UID %08X %08X\r\n", high, low ); } // コマンド else if( cmd_no == 2 ) { } // コマンド RESP else if( cmd_no == 3 ) { pc.printf( "RESP\r" ); } // コマンド else if( cmd_no == 4 ) { } // コマンド else if( cmd_no == 5 ) { } // コマンド else if( cmd_no == 6 ) { } // コマンド else if( cmd_no == 7 ) { } // コマンド else if( cmd_no == 8 ) { } // コマンド else if( cmd_no == 9 ) { } else { //pc.printf("CMD_ERR\r\n"); } } } } } } #define CMD_NUM 24 char pc_str[16][10]; char pc_str2[CMD_NUM][8] = { "START ", // 0 "STOP ", // 1 " ", // 2 "MSET ", // 3 " ", // 4 " ", // 5 " ", // 6 "ISETL ", // 7 "ISETR ", // 8 " ", // 9 " ", // 10 "CONNECT", // 11 "DISCO ", // 12 "INTVL ", // 13 "NTC ", // 14 "OTC ", // 15 " ", // 16 " ", // 17 "IDGET ", // 18 " ", // 19 " ", // 20 " ", // 21 " ", // 22 " "}; // 23 /****************************************************************************/ /* 関数名 : rs232c_cmd */ /* 概要 : 通信コマンド処理 */ /* 作成者 : JPMS H.Harada */ /* 作成日 : 2017.08.30 */ /****************************************************************************/ void pc_rs232c_cmd() { unsigned int c, i, j; int rdat; while( pc.readable() ) { pc_uart_buf.buf[pc_uart_buf.wp] = pc.getc(); pc_uart_buf.data_cnt++; if( pc_uart_buf.wp == SIO_BUF_SIZE-1 ) { pc_uart_buf.wp = 0; } else { pc_uart_buf.wp++; } } if( pc_uart_buf.data_cnt > 0 ) { unsigned int len = pc_uart_buf.data_cnt; for( c=0; c<len; c++ ) { rdat = pc_uart_buf.buf[pc_uart_buf.rp]; pc_uart_buf.data_cnt--; if( pc_uart_buf.rp == SIO_BUF_SIZE-1 ) { pc_uart_buf.rp = 0; } else { pc_uart_buf.rp++; } if( rdat != '\n' ) { pc_cmd_buf.buf[pc_cmd_buf.data_cnt++] = rdat; } if( rdat == '\r' ) { int k = 0; int l = 0; for (i=0;i<pc_cmd_buf.data_cnt;i++) { if( pc_cmd_buf.buf[i] == ' ' || pc_cmd_buf.buf[i] == '\r' || pc_cmd_buf.buf[i] == '\t' ) { pc_str[k++][l] = '\0'; l = 0; } else { pc_str[k][l++] = pc_cmd_buf.buf[i]; } } if( pc_cmd_buf.data_cnt == 1 ) { k = 0; } pc_cmd_buf.data_cnt = 0; pc_cmd_buf.buf[0] = '\0'; if (k > 0) { int ret; int cmd_no = 0xFF; for( j=0; j<CMD_NUM; j++ ) { ret = 1; if( strlen(pc_str[0]) > 0 ) { for( i=0; i<strlen(pc_str[0]); i++ ) { if( pc_str[0][i] != pc_str2[j][i] ) { ret = 0; } } if( ret ) { cmd_no = j; break; } } } // コマンド START if (cmd_no == 0) { ble_write( "START\r" ); pc.printf( "START OK\r\n" ); } // コマンド STOP else if( cmd_no == 1 ) { ble_write( "STOP\r" ); pc.printf( "STOP OK\r\n" ); } // コマンド else if (cmd_no == 2) { } // コマンド MSET else if( cmd_no == 3 ) { mac_1 = atoh(pc_str[1], strlen(pc_str[1])); mac_2 = atoh(pc_str[2], strlen(pc_str[2])); mac_3 = atoh(pc_str[3], strlen(pc_str[3])); mac_board_0[0] = ( mac_3 >> 0 ) & 0x00FF; mac_board_0[1] = ( mac_3 >> 8 ) & 0x00FF; mac_board_0[2] = ( mac_2 >> 0 ) & 0x00FF; mac_board_0[3] = ( mac_2 >> 8 ) & 0x00FF; mac_board_0[4] = ( mac_1 >> 0 ) & 0x00FF; mac_board_0[5] = ( mac_1 >> 8 ) & 0x00FF; pc.printf( "%02X %02X %02X %02X %02X %02X\r", mac_board_0[5], mac_board_0[4], mac_board_0[3], mac_board_0[2], mac_board_0[1], mac_board_0[0] ); pc.printf( "MSET OK\r\n" ); } // コマンド else if( cmd_no == 4 ) { } // コマンド else if( cmd_no == 5 ) { } // コマンド else if( cmd_no == 6 ) { } // コマンド ISETL else if( cmd_no == 7 ) { int id_LH = atoh(pc_str[1], strlen(pc_str[1])); int id_LL = atoh(pc_str[2], strlen(pc_str[2])); char buf[BFSIZE]; sprintf( buf, "L %8X %8X\r", id_LH, id_LL ); ble_write( buf ); pc.printf( "ISETL OK\r\n" ); } // コマンド ISETR else if( cmd_no == 8 ) { int id_RH = atoh(pc_str[1], strlen(pc_str[1])); int id_RL = atoh(pc_str[2], strlen(pc_str[2])); char buf[BFSIZE]; sprintf( buf, "R %8X %8X\r", id_RH, id_RL ); ble_write( buf ); pc.printf( "ISETR OK\r\n" ); } // コマンド else if( cmd_no == 9 ) { } // コマンド else if( cmd_no == 10 ) { } // コマンド CONNECT else if( cmd_no == 11 ) { if( connected2server == false ) { // CONNECT処理 ble_uart.gap().connect( mac_board_0, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL); pc.printf( "CONNECT OK\r\n" ); } else { // DISC処理 Gap::DisconnectionReason_t reason; ble_uart.gap().disconnect( reason ); pc.printf( "CONNECT NG\r\n" ); } } // コマンド DISC else if( cmd_no == 12 ) { if( connected2server == true ) { // DISC処理 Gap::DisconnectionReason_t reason; ble_uart.gap().disconnect( reason ); } pc.printf( "DISC OK\r\n" ); } // コマンド INTVL else if( cmd_no == 13 ) { unsigned int interval = atow(pc_str[1], strlen(pc_str[1])); char buf[BFSIZE]; sprintf( buf, "INTVL %d\r", interval ); ble_write( buf ); pc.printf( "INTVL OK\r\n" ); } // コマンド NTC else if( cmd_no == 14 ) { unsigned int not_touch_cnt = atow(pc_str[1], strlen(pc_str[1])); char buf[BFSIZE]; sprintf( buf, "NTC %d\r", not_touch_cnt ); ble_write( buf ); pc.printf( "NTC OK\r\n" ); } // コマンド OTC else if( cmd_no == 15 ) { unsigned int touch_cnt = atow(pc_str[1], strlen(pc_str[1])); char buf[BFSIZE]; sprintf( buf, "OTC %d\r", touch_cnt ); ble_write( buf ); pc.printf( "OTC OK\r\n" ); } // コマンド else if( cmd_no == 16 ) { } // コマンド else if( cmd_no == 17 ) { } // コマンド IDGET else if( cmd_no == 18 ) { ble_write( "IDGET\r\n" ); } // コマンド else if( cmd_no == 19 ) { } // コマンド else if( cmd_no == 20 ) { } // コマンド else if( cmd_no == 21 ) { } // コマンド else if( cmd_no == 22 ) { } else { //pc.printf("CMD_ERR\r"); } } } } } } void ble_write(char* dat) { uint8_t linebf_irq[BFSIZE]; sprintf( (char *)linebf_irq, "%s", dat); if( connected2server == true ) { uartTXCharacteristic.write(NUM_ONCE, linebf_irq); } }