diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..afdc5d4 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,52 @@ +plugins { + id 'com.android.application' +} + +android { + compileSdk 32 + + defaultConfig { + applicationId "com.xinyingpower.testcomm" + minSdk 28 + targetSdk 32 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + externalNativeBuild { + cmake { + cppFlags '-std=c++17' + } + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + externalNativeBuild { + cmake { + path file('src/main/cpp/CMakeLists.txt') + version '3.18.1' + } + } + buildFeatures { + viewBinding true + } +} + +dependencies { + + implementation 'androidx.appcompat:appcompat:1.3.0' + implementation 'com.google.android.material:material:1.4.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/xinyingpower/testcomm/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/xinyingpower/testcomm/ExampleInstrumentedTest.java new file mode 100644 index 0000000..44bbb0d --- /dev/null +++ b/app/src/androidTest/java/com/xinyingpower/testcomm/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.xinyingpower.testcomm; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.xinyingpower.testcomm", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..6aed52f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/WeatherComm.cpp b/app/src/main/WeatherComm.cpp new file mode 100644 index 0000000..9a2a648 --- /dev/null +++ b/app/src/main/WeatherComm.cpp @@ -0,0 +1,558 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GPIOControl.h" +#include "WeatherComm.h" +#include + +SIO_PARAM_SERIAL_DEF serialport; +float weatherpntmsg[10]; + +static void set_baudrate (struct termios *opt, unsigned int baudrate) +{ + cfsetispeed(opt, baudrate); + cfsetospeed(opt, baudrate); +} + +static void set_data_bit (struct termios *opt, unsigned int databit) +{ + opt->c_cflag &= ~CSIZE; + switch (databit) + { + case 8: + opt->c_cflag |= CS8; + break; + case 7: + opt->c_cflag |= CS7; + break; + case 6: + opt->c_cflag |= CS6; + break; + case 5: + opt->c_cflag |= CS5; + break; + default: + opt->c_cflag |= CS8; + break; + } +} + +static void set_parity (struct termios *opt, char parity) +{ + switch (parity) + { + case'N':/* 无校验 */ + case 'n': + opt->c_cflag &= ~PARENB; + break; + case'E':/*偶校验*/ + case 'e': + opt->c_cflag |= PARENB; + opt->c_cflag &= ~PARODD; + break; + case'O':/* 奇校验 */ + case 'o': + opt->c_cflag |= PARENB; + opt->c_cflag |= ~PARODD; + break; + default: /*其它选择为无校验 */ + opt->c_cflag &= ~PARENB; + break; + } +} + +static void set_stopbit (struct termios *opt, const char *stopbit) +{ + if (strcmp(stopbit, "1") == 0) + { + opt->c_cflag &= ~CSTOPB;/*1 位停止位 t */ + } + else if(0 == strcmp(stopbit, "1.5")) + { + opt->c_cflag &= ~CSTOPB;/*1.5 位停止位 */ + } + else if(0 == strcmp (stopbit,"2")) + { + opt->c_cflag |= CSTOPB; /*2 位停止位 */ + } + else + { + opt->c_cflag &= ~CSTOPB; /*1 位停止位 */ + } +} + +int set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin ) +{ + struct termios opt; + tcgetattr(fd, &opt); + set_baudrate(&opt, baudrate); + //opt.c_cflag |= CLOCAL|CREAD; /*|CRTSCTS */ + opt.c_lflag &= ~(ICANON | ECHO |ECHOE |ISIG); + set_data_bit(&opt, databit); + set_parity(&opt, parity); + set_stopbit(&opt, stopbit); + opt.c_oflag = 0; + //opt.c_lflag |= 0; + opt.c_oflag &= ~OPOST; + opt.c_cc[VTIME] = vtime; + opt.c_cc[VMIN] = vmin; + tcflush (fd, TCIFLUSH); + return (tcsetattr (fd, TCSANOW, &opt)); +} + +static void setInt(int cmd, int value) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + IOT_PARAM param; + param.cmd = cmd; + param.value = value; + // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value); + if( fd > 0 ) + { + int res = ioctl(fd, IOT_PARAM_WRITE, ¶m); + // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result); + close(fd); + } + return; +} +static void setRS485Enable(bool z) { + setInt(CMD_SET_485_EN_STATE, z ? 1 : 0); +} + +static void set485WriteMode() { + setInt(CMD_SET_485_STATE, 1); +} + +static void set485ReadMode() { + setInt(CMD_SET_485_STATE, 0); +} +static void set12VEnable(bool z) { + setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0); +} + +static void setCam3V3Enable(bool enabled) +{ + setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0); +} + + +/********************************************************************************* +* 气象数据处理 * +**********************************************************************************/ +void PortDataProcess( void ) +{ + float fvalue, fcorvalue, *fvalua, frnb/*, fwind*/; + //WORD uDevAddr; + unsigned char cmdidx; + int i, j, aipnt, datanum; + SIO_PARAM_SERIAL_DEF *pPortParam; + char szbuf[64]; + + pPortParam = &serialport; + //取出装置地址,开始处理地址+++ + if(0x02 == pPortParam->m_au8RecvBuf[5]) + { + //pPortParam->devaddr = pPortParam->m_au8RecvBuf[4]; + return; + } + cmdidx = pPortParam->m_au8RecvBuf[5]; +#if 0 + aipnt = pPortParam->SameTypeDevIdx; + uDevAddr = serialport->m_au8RecvBuf[4]; + if(0 == srdt.IsReadWireTem) + { + if(uDevAddr != pPortParam->devaddr) + return; + } +#endif + fvalua = &fvalue; + datanum = pPortParam->m_au8RecvBuf[6]; + if((0x08 != cmdidx) && (0x09 != cmdidx)) + return; + + for(i = 0, j=7; (im_au8RecvBuf[1]); i++, j+=5 ) + { + if(0x08 == cmdidx) + fvalue = (pPortParam->m_au8RecvBuf[j+1]<<24)+(pPortParam->m_au8RecvBuf[j+2]<<16) + +(pPortParam->m_au8RecvBuf[j+3]<<8)+pPortParam->m_au8RecvBuf[j+4]; + else + { + *(u_char *)fvalua = pPortParam->m_au8RecvBuf[j+4]; + *((u_char *)fvalua+1) = pPortParam->m_au8RecvBuf[j+3]; + *((u_char *)fvalua+2) = pPortParam->m_au8RecvBuf[j+2]; + *((u_char *)fvalua+3) = pPortParam->m_au8RecvBuf[j+1]; + } + switch(pPortParam->m_au8RecvBuf[j]) + { + case 1: /*温度*/ + weatherpntmsg[0] = fvalue; + LOGE("温度:%0.3f ", fvalue); + break; + case 2: /*气压*/ + weatherpntmsg[5] = fvalue; + LOGE("气压:%0.3f ", fvalue); + break; + case 3: /*湿度*/ + weatherpntmsg[1] = fvalue; + LOGE("湿度:%0.3f ", fvalue); + break; + case 4: /*雨量*/ + break; + case 5: /*日照*/ + break; + case 6: /*风速*/ + weatherpntmsg[2] = fvalue; + LOGE("风速:%0.3f ", fvalue); + break; + case 7: /*风向*/ + weatherpntmsg[3] = fvalue; + LOGE("风向:%0.3f ", fvalue); + break; + case 8: /*拉力*/ + case 9: /*倾角传感器X轴倾角*/ + case 10: /*倾角传感器Y轴倾角*/ + case 11: /*测温球导线温度*/ + case 12: /*测温球内部温度*/ + break; + case 13: /*测温球导线X轴倾角*/ + break; + case 14: /*测温球导线Y轴倾角*/ + break; + case 15: /*测温球导线电流*/ + break; + case 16: /*测温球电池电压*/ + break; + case 17: /*A相泄漏电流平均值;*/ + break; + case 18: /*A相泄漏电流最大值;*/ + break; + case 19: /*A相超过3mA的脉冲频次*/ + break; + case 20: /*A相超过10mA的脉冲频次*/ + break; + case 21: /*B相泄漏电流平均值;*/ + break; + case 22: /*B相泄漏电流最大值;*/ + break; + case 23: /*B相超过3mA的脉冲频次*/ + break; + case 24: /*B相超过10mA的脉冲频次*/ + case 25: /*C相泄漏电流平均值;*/ + case 26: /*C相泄漏电流最大值;*/ + case 27: /*C相超过3mA的脉冲频次*/ + case 28: /*C相超过10mA的脉冲频次*/ + break; + } + } +} + +//*************************************************************** +//* 按照协议格式化接收数据 * +//*************************************************************** +static void RecvData(u_char *buf, int len)// 规约读数据处理 +{ + int i, ictime; + //WORD crc, check; + SIO_PARAM_SERIAL_DEF *pPortParam; + + pPortParam = &serialport; + ictime = (int)time(NULL); + + if(pPortParam->m_iRecvLen == 0) + { + pPortParam->iRecvTime = ictime; + } + else + { + if((ictime-pPortParam->iRecvTime > 6) || (ictime - pPortParam->iRecvTime < 0)) + pPortParam->iRecvTime = ictime; + else if(ictime - pPortParam->iRecvTime > 2) + { + pPortParam->m_iRecvLen = 0; + pPortParam->m_iRevStatus = 0; + } + } + + for(i=0; im_iRevStatus) + { + case 0: // 0x68 + pPortParam->m_iRecvLen = 0; + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(0x68 == buf[i]) + pPortParam->m_iRevStatus++; + else + pPortParam->m_iRevStatus = 18; + break; + case 1: // len1 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iRevStatus++; + break; + case 2: // len2 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(buf[i] == pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2]) + { + pPortParam->m_iRevStatus++; + pPortParam->m_iNeedRevLength = buf[i]+5; + } + else + pPortParam->m_iRevStatus = 18; + break; + case 3: // 0x68 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iNeedRevLength--; + if(0x68 == buf[i]) + pPortParam->m_iRevStatus++; + else + pPortParam->m_iRevStatus = 18; + break; + case 4: // 正确接收数据 + pPortParam->m_iNeedRevLength--; + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(pPortParam->m_iNeedRevLength > 0) + break; + if(buf[i] != 0x16) + { + pPortParam->m_iRevStatus=18; + break; + } + + //if(CheckLpcError(serialport->m_au8RecvBuf, pPortParam->m_iRecvLen) == TRUE) + { + PortDataProcess(); + pPortParam->m_iRevStatus = 0; + pPortParam->RevCmdFlag = 1; + } + pPortParam->m_iRecvLen = 0; + break; + case 255:// 错误接收数据 + default: + if(buf[i] == 0x68) + { + pPortParam->m_iRevStatus = 1; + pPortParam->m_iRecvLen = 1; + pPortParam->m_au8RecvBuf[0] = buf[i]; + } + else if(buf[i] == 0x16) + { + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iRevStatus = 0; + pPortParam->m_iRecvLen = 0; + } + else + { + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(pPortParam->m_iRecvLen > 200) + { + pPortParam->m_iRecvLen = 0; + } + } + break; + } + } +} + +static long get_msec(void ) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + long time_in_msec = tv.tv_sec * 1000 + tv.tv_usec/1000; + + return time_in_msec; +} +//int inum =0; +//int itimecnt=0; +static int weather_comm(SERIAL_PARAM weatherport) +{ + int fd = -1; + int len, i,ret, icnt=0; + long ictime, iruntime, isendtime, irecvtime; + unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x01,0x09,0x0a,0x16}; + char recvbuf[256], szbuf[512]; + //char serial_description[] = "/dev/ttyS0"; + +#if 0 + DIR *dir = opendir("/dev"); + if (dir == NULL) { + LOGE("_test_ opendir"); + return -1; + } + + // 读取目录项 + struct dirent *entry; + while ((entry = readdir(dir)) != NULL) { + // 过滤出串口设备,通常以"ttyS"或"ttyUSB"开头 + if ((strncmp(entry->d_name, "ttyS2", 5) == 0) || + (strncmp(entry->d_name, "ttyS0", 5) == 0)) { + LOGE("_test_ Found serial port: %s\n", entry->d_name); + } + } + + // 关闭目录 + closedir(dir); +#endif + serialport.RevCmdFlag = 1; + serialport.m_iRecvLen = 0; + serialport.m_iRevStatus = 0; + + set12VEnable(true); + setCam3V3Enable(true); + setRS485Enable(true); + sleep(2); + //ictime = (int)time(NULL); + ictime = get_msec(); + for(;;) + { + if(fd < 0) + { + fd = open(weatherport.pathname, O_RDWR | O_NDELAY); + //fd = open(weatherport.pathname, O_RDWR | O_NOCTTY); + if(fd < 0) + { + LOGE("_test_ open serial error \n"); + perror(weatherport.pathname); + return -1; + } + + ret= set_port_attr (fd, weatherport.baudrate,weatherport.databit,weatherport.stopbit,weatherport.parity,0,0 );/*9600 8n1 */ + if(ret < 0) + { + LOGE("_test_ set uart arrt faile \n"); + return -1; + } + } + + usleep(10000); + //iruntime = (int)time(NULL); + iruntime = get_msec(); + if((iruntime - ictime > 120000) || (iruntime - ictime < 0)) + ictime = iruntime; + if(iruntime - ictime > 20000) + { + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf, "气象采样时间=%0.3f秒,停止采样!", (iruntime-ictime)/1000.0); + LOGE("%s", szbuf); + break; + } + + if(1 == serialport.RevCmdFlag) + { + set485WriteMode(); + + len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */ + serialport.RevCmdFlag = 0; + LOGE("发送命令时间差%ld毫秒", get_msec()-isendtime); + //isendtime = time(NULL); + isendtime = get_msec(); + if (len < 0) { + LOGE("write data error \n"); + return -1; + } else { + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf, "Send:"); + for (i = 0; i < len; i++) { + sprintf(szbuf, "%s %02X", szbuf, sendbuf[i]); + } + LOGE("%s", szbuf); + //icnt = 0; + //inum++; + } + tcdrain(fd); + //usleep(50000); + } + else + { + //irecvtime = time(NULL); + irecvtime = get_msec(); + if((irecvtime-isendtime > 6000) ||(irecvtime - isendtime < 0)) + isendtime = irecvtime; + if (irecvtime-isendtime > 300) + { + LOGE("传感器超过%ld毫秒未应答", irecvtime-isendtime); + serialport.RevCmdFlag = 1; + serialport.m_iRecvLen = 0; + serialport.m_iRevStatus = 0; + close(fd); + //set12VEnable(false); + //setCam3V3Enable(false); + //setRS485Enable(false); + fd = -1; + continue; + } + } + set485ReadMode(); + memset(recvbuf, 0, sizeof(recvbuf)); + len = read(fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */ + if (len < 0) { + LOGE("serial read error \n"); + continue; + } + if(0 == len) + { + //icnt++; + continue; + } + + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf, "Recv:"); + for (i = 0; i < len; i++) { + sprintf(szbuf, "%s %02X", szbuf, recvbuf[i]); + } + __android_log_print(ANDROID_LOG_INFO, "serial", "%s", szbuf); + RecvData((u_char*)recvbuf, len); + //LOGE("一周期空循环次数%d, 读取次数%d, 时间:%d %d", icnt, inum, (int)time(NULL), itimecnt); + icnt = 0; + //serialport.RevCmdFlag =1; + } + + close(fd); + set12VEnable(false); + setCam3V3Enable(false); + setRS485Enable(false); + + //exit(-1); + return(0); +} + +int serial_port_comm() +{ + SERIAL_PARAM portparm; + + //struct timeval tv; + + //gettimeofday(&tv, NULL); + //long time_in_microseconds = tv.tv_sec * 1000000 + tv.tv_usec; + + //LOGE("Current time in microseconds: %ld\n", time_in_microseconds); + +#if 1 + memset(portparm.pathname, 0, sizeof(portparm.pathname)); + sprintf(portparm.pathname, "/dev/ttyS0"); + portparm.parity = 'N'; + portparm.databit = 8; + portparm.baudrate = B9600; + memset(portparm.stopbit, 0, sizeof(portparm.stopbit)); + sprintf(portparm.stopbit, "1"); +#endif + //itimecnt = (int)time(NULL); + + //for(;;) + weather_comm(portparm); + return 0; +} + diff --git a/app/src/main/WeatherComm.h b/app/src/main/WeatherComm.h new file mode 100644 index 0000000..80c47f9 --- /dev/null +++ b/app/src/main/WeatherComm.h @@ -0,0 +1,51 @@ +// +// Created by hyz on 2024/6/5. +// + +#ifndef WEATHERCOMM_H +#define WEATHERCOMM_H + +#include +#include "GPIOControl.h" + +#define MAX_STRING_LEN 32 +#define IOT_PARAM_WRITE 0xAE +#define IOT_PARAM_READ 0xAF + +#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "serial_port_comm", fmt, ##args) + +// 串口参数 +typedef struct +{ + int baudrate; /* 波特率*/ + int databit; /* 数据位*/ + char stopbit[8]; /* 停止位*/ + char parity; /* 校验位*/ + char pathname[128];/* 串口文件名及路径*/ +} SERIAL_PARAM; + +typedef struct +{ + int m_iRevStatus; /* */ + int m_iRecvLen; /* */ + int m_iNeedRevLength; /* */ + int iRecvTime; /* */ + int RevCmdFlag; + unsigned char m_au8RecvBuf[128];/* */ +} SIO_PARAM_SERIAL_DEF; + +typedef struct +{ + int cmd; + int value; + int result; + long value2; + char str[MAX_STRING_LEN]; +}IOT_PARAM; + +void PortDataProcess( void ); +int serial_port_comm(); +static int weather_comm(SERIAL_PARAM weatherport); +int set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin ); + +#endif //WEATHERCOMM_H diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000..4015c24 --- /dev/null +++ b/app/src/main/cpp/CMakeLists.txt @@ -0,0 +1,60 @@ +# For more information about using CMake with Android Studio, read the +# documentation: https://d.android.com/studio/projects/add-native-code.html + +# Sets the minimum version of CMake required to build the native library. + +cmake_minimum_required(VERSION 3.18.1) + +# Declares and names the project. + +project("testcomm") + +# Creates and names a library, sets it as either STATIC +# or SHARED, and provides the relative paths to its source code. +# You can define multiple libraries, and CMake builds them for you. +# Gradle automatically packages shared libraries with your APK. + +add_library( # Sets the name of the library. + testcomm + + # Sets the library as a shared library. + SHARED + + # Provides a relative path to your source file(s). + SpiPort.cpp + #spi-test-random.cpp + # NRSEC3000ctl.cpp + SpiLib.cpp + native-lib.cpp + GPIOControl.cpp + #WeatherComm.cpp + serialComm.cpp + SensorsProtocol.cpp + ) + +# Searches for a specified prebuilt library and stores the path as a +# variable. Because CMake includes system libraries in the search path by +# default, you only need to specify the name of the public NDK library +# you want to add. CMake verifies that the library exists before +# completing its build. + +find_library( # Sets the name of the path variable. + log-lib + + # Specifies the name of the NDK library that + # you want CMake to locate. + + log) + +# Specifies libraries CMake should link to your target library. You +# can link multiple libraries, such as libraries you define in this +# build script, prebuilt third-party libraries, or system libraries. + +target_link_libraries( # Specifies the target library. + testcomm + + android + + # Links the target library to the log library + # included in the NDK. + ${log-lib}) \ No newline at end of file diff --git a/app/src/main/cpp/GPIOControl.cpp b/app/src/main/cpp/GPIOControl.cpp new file mode 100644 index 0000000..783025a --- /dev/null +++ b/app/src/main/cpp/GPIOControl.cpp @@ -0,0 +1,144 @@ +// +// Created by Matthew on 2023/12/27. +// + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "GPIOControl.h" + +#ifdef _DEBUG +#include +#endif + +#define IOT_PARAM_WRITE 0xAE +#define IOT_PARAM_READ 0xAF +#define MAX_STRING_LEN 32 + +typedef struct +{ + int cmd; + int value; + int result; + long value2; + char str[MAX_STRING_LEN]; +}IOT_PARAM; + +typedef struct{ + float airtemp; /* 空气温度*/ + float RH; /* 相对湿度*/ + float atmos; /* 大气压*/ + float windspeed; /* 风速*/ + float winddirection; /* 风向*/ + float rainfall; /* 雨量*/ + float sunshine; /* 日照*/ +}Weather; + +void GpioControl::setInt(int cmd, int value) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + IOT_PARAM param; + param.cmd = cmd; + param.value = value; + // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value); + if( fd > 0 ) + { + int res = ioctl(fd, IOT_PARAM_WRITE, ¶m); + // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result); + close(fd); + } + return; +} + +int GpioControl::getInt(int cmd) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + // LOGE("get_int fd=%d,cmd=%d\r\n",fd, cmd); + if( fd > 0 ) + { + IOT_PARAM param; + param.cmd = cmd; + ioctl(fd, IOT_PARAM_READ, ¶m); +#ifdef _DEBUG + ALOGI("getInt cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result); +#endif + close(fd); + return param.value; + } + return -1; +} + +void GpioControl::setLong(int cmd, long value) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + IOT_PARAM param; + param.cmd = cmd; + param.value2 = value; + // LOGE("set_long fd=%d,cmd=%d,value2=%ld\r\n",fd, param.cmd, param.value2); + + if( fd > 0 ) + { + ioctl(fd, IOT_PARAM_WRITE, ¶m); + // LOGE("set_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result); + close(fd); + } +} + +long GpioControl::getLong(int cmd) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + // LOGE("get_long fd=%d,cmd=%d\r\n",fd, cmd); + if( fd > 0 ) + { + IOT_PARAM param; + param.cmd = cmd; + ioctl(fd, IOT_PARAM_READ, ¶m); + // LOGE("get_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result); + close(fd); + return param.value2; + } + return -1; +} + +void GpioControl::setString(int cmd, const std::string& value) +{ + IOT_PARAM param; + // char *pval = jstringToChars(env, value); + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + int len = MAX_STRING_LEN < value.size() ? MAX_STRING_LEN : value.size(); + + param.cmd = cmd; + memset(param.str, 0, MAX_STRING_LEN); + memcpy(param.str, value.c_str(), len); + // LOGE("set_string fd=%d,cmd=%d,str=%s\r\n",fd, param.cmd, param.str); + if( fd > 0 ) + { + ioctl(fd, IOT_PARAM_WRITE, ¶m); + // LOGE("set_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result); + close(fd); + } + return; +} + +std::string GpioControl::getString(int cmd) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + // LOGE("get_string fd=%d,cmd=%d\r\n",fd, cmd); + if( fd > 0 ) + { + IOT_PARAM param; + param.cmd = cmd; + ioctl(fd, IOT_PARAM_READ, ¶m); + // LOGE("get_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result); + close(fd); + return std::string(param.str); + } + return ""; +} diff --git a/app/src/main/cpp/GPIOControl.h b/app/src/main/cpp/GPIOControl.h new file mode 100644 index 0000000..8bb0a5a --- /dev/null +++ b/app/src/main/cpp/GPIOControl.h @@ -0,0 +1,205 @@ +// +// Created by Matthew on 2023/12/27. +// + +#ifndef MICROPHOTO_GPIOCONTROL_H +#define MICROPHOTO_GPIOCONTROL_H + +#include + +#define CMD_GET_LIGHT_ADC 101 +#define CMD_SET_LIGHT_ADC 102 +#define CMD_GET_KEY_LOCKSTATE 103 +#define CMD_GET_BAT_ADC 104 +#define CMD_SET_FLASH_LED 105 +#define CMD_SET_NETWORK_STATE 106 +#define CMD_SET_OTG_STATE 107 +#define CMD_GET_OTG_STATE 108 +#define CMD_GET_CHARGING_VOL_STATE 110 +#define CMD_GET_CHARGING_SHUNT_VOLTAGE_STATE 111 +#define CMD_GET_CHARGING_BUS_VOLTAGE_STATE 112 +#define CMD_GET_CHARGING_POWER_STATE 113 +#define CMD_GET_CHARGING_CURRENT_STATE 114 +#define CMD_GET_BAT_VOL_STATE 115 +#define CMD_GET_BAT_SHUNT_VOLTAGE_STATE 116 +#define CMD_GET_BAT_BUS_VOLTAGE_STATE 117 +#define CMD_GET_BAT_POWER_STATE 118 +#define CMD_GET_BAT_CURRENT_STATE 119 +#define CMD_SET_485_STATE 121 +#define CMD_SET_SPI_MODE 123 +#define CMD_SET_SPI_BITS_PER_WORD 124 +#define CMD_SET_SPI_MAXSPEEDHZ 125 +#define CMD_SET_PWM_BEE_STATE 126 +#define CMD_SET_ALM_MODE 128 +#define CMD_SET_SPI_POWER 129 +#define CMD_SET_485_EN_STATE 131 +#define CMD_SET_CAM_3V3_EN_STATE 132 +#define CMD_SET_12V_EN_STATE 133 +#define CMD_SET_SYSTEM_RESET 202 +#define CMD_SET_WTH_POWER 490 +#define CMD_SET_PULL_POWER 491 +#define CMD_SET_ANGLE_POWER 492 +#define CMD_SET_OTHER_POWER 493 +#define CMD_SET_PIC1_POWER 494 +#define CMD_SET_485_en0 301 +#define CMD_SET_485_en1 302 +#define CMD_SET_485_en2 303 +#define CMD_SET_485_en3 304 +#define CMD_SET_485_en4 305 + +#define CMD_SET_ADC_ENABLE 500 +#define CMD_SET_MIPI_SWITCH 501 +#define CMD_SET_CAM_RSTN1 502 +#define CMD_SET_CAM_RSTN0 503 +#define CMD_SET_SENSOR_ENABLE 504 +#define CMD_SET_SENSOR_PWR_ENABLE 505 +#define CMD_SET_SENSOR2_ENABLE 506 +#define CMD_SET_SD_DECT 507 +#define CMD_SET_PTZ_PWR_ENABLE 508 +#define CMD_SET_SENSOR3_PWR_ENABLE 509 +#define CMD_SET_SENSOR4_ENABLE 510 +#define CMD_SET_RTC_ENABLE 511 +#define CMD_SET_485_ENABLE 512 +#define CMD_SET_SENSOR1_PWR_ENABLE 513 +#define CMD_SET_SENSOR2_PWR_ENABLE 514 +#define CMD_SET_PHOTO_OUT 515 +#define CMD_SET_3V3_PWR_ENABLE 516 +#define CMD_SET_5V_PWR_ENABLE 517 +#define CMD_SET_100M_ENABLE 518 +#define CMD_SET_100M_SWITCH_PWR_ENABLE 519 +#define CMD_SET_PHOTO_IN 520 +#define CMD_SET_AM_POWER_ENABLE 521 +#define CMD_SET_NRSEC_POWER_ENABLE 522 +#define CMD_SET_AMP_ENABLE 523 +#define CMD_SET_LIGHT1_RESISTOR_ENABLE 524 +#define CMD_SET_SENSOR4_PWR_ENABLE 525 +#define CMD_SET_100M_RESET 526 + +class GpioControl +{ +public: + + static void setInt(int cmd, int value); + static int getInt(int cmd); + static void setLong(int cmd, long value); + static long getLong(int cmd); + static void setString(int cmd, const std::string& value); + static std::string getString(int cmd); + + static void setOtgState(bool on) + { + setInt(CMD_SET_OTG_STATE, on ? 1 : 0); + } + + static bool getOtgState() + { + return getInt(CMD_SET_OTG_STATE) != 0; + } + + static void setCam3V3Enable(bool enabled) + { + setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0); + } + + static void reboot() + { + setInt(CMD_SET_SYSTEM_RESET, 1); + } + + static void setLightAdc(int i) + { + setInt(CMD_SET_LIGHT_ADC, i); + } + + static int getLightAdc() + { + return getInt(CMD_GET_LIGHT_ADC); + } + + static int getChargingVoltage() + { + return getInt(CMD_GET_CHARGING_VOL_STATE); + } + + static int getChargingShuntVoltage() + { + return getInt(CMD_GET_CHARGING_SHUNT_VOLTAGE_STATE); + } + + static int getChargingBusVoltage() { + return getInt(CMD_GET_CHARGING_BUS_VOLTAGE_STATE); + } + + static int getChargingPower() { + return getInt(CMD_GET_CHARGING_POWER_STATE); + } + + static int getChargingCurrent() { + return getInt(CMD_GET_CHARGING_CURRENT_STATE); + } + + static int getBatteryVoltage() { + return getInt(CMD_GET_BAT_VOL_STATE); + } + + static int getBatteryShuntVoltage() { + return getInt(CMD_GET_BAT_SHUNT_VOLTAGE_STATE); + } + + static int getBatteryBusVoltage() { + return getInt(CMD_GET_BAT_BUS_VOLTAGE_STATE); + } + + static int getBatteryPower() { + return getInt(CMD_GET_BAT_POWER_STATE); + } + + static int getBatteryCurrent() { + return getInt(CMD_GET_BAT_CURRENT_STATE); + } + + static void set485WriteMode() { + setInt(CMD_SET_485_STATE, 1); + } + + static void set485ReadMode() { + setInt(CMD_SET_485_STATE, 0); + } + + static void setSpiMode(int i) { + setInt(CMD_SET_SPI_MODE, i); + } + + static void setSpiBitsPerWord(int i) { + setInt(CMD_SET_SPI_BITS_PER_WORD, i); + } + + static void setSpiMaxSpeedHz(long j) { + setLong(CMD_SET_SPI_MAXSPEEDHZ, j); + } + + static void setBeeOn(bool z) { + setInt(CMD_SET_PWM_BEE_STATE, z ? 1 : 0); + } + + static void setJidianqiState(bool z) { + setInt(CMD_SET_ALM_MODE, z ? 1 : 0); + } + + static void setSpiPower(bool on) { + setInt(CMD_SET_SPI_POWER, on ? 1 : 0); + } + + static void setRS485Enable(bool z) { + setInt(CMD_SET_485_EN_STATE, z ? 1 : 0); + } + + + static void set12VEnable(bool z) { + setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0); + } + +}; + + +#endif //MICROPHOTO_GPIOCONTROL_H diff --git a/app/src/main/cpp/SensorsProtocol.cpp b/app/src/main/cpp/SensorsProtocol.cpp new file mode 100644 index 0000000..b8cca27 --- /dev/null +++ b/app/src/main/cpp/SensorsProtocol.cpp @@ -0,0 +1,3759 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GPIOControl.h" +#include "serialComm.h" +#include "SensorsProtocol.h" +#include +#include "SensorsProtocol.h" +//#include "Eint.h" + +SIO_PARAM_SERIAL_DEF serialport[MAX_SERIAL_PORT_NUM]; +SERIAL_PARAM devparam[MAX_SERIAL_DEV_NUM]; +SRDT_DEF srdt; +AI_DEF weatherpntmsg[WEATHER_DATA_NUM]; +AI_DEF rallypntmsg[6][RALLY_DATA_NUM]; +AI_DEF slantpntmsg[6][SLANTANGLE_DATA_NUM]; + +static void setInt(int cmd, int value) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + IOT_PARAM param; + param.cmd = cmd; + param.value = value; + // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value); + if( fd > 0 ) + { + ioctl(fd, IOT_PARAM_WRITE, ¶m); + // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result); + close(fd); + } + //return; +} + +int getInt(int cmd) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + // LOGE("get_int fd=%d,cmd=%d\r\n",fd, cmd); + if( fd > 0 ) + { + IOT_PARAM param; + param.cmd = cmd; + ioctl(fd, IOT_PARAM_READ, ¶m); +#ifdef _DEBUG + ALOGI("getInt cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result); +#endif + close(fd); + return param.value; + } + return -1; +} + +static void setRS485Enable(bool z) { + setInt(CMD_SET_485_EN_STATE, z ? 1 : 0); +} + +static void set485WriteMode() { + setInt(CMD_SET_485_STATE, 1); +} + +static void set485ReadMode() { + setInt(CMD_SET_485_STATE, 0); +} +static void set12VEnable(bool z) { + setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0); +} + +static void setCam3V3Enable(bool enabled) +{ + setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0); +} + +#if 0 +/********************************************************************************* +* 气象数据处理 * +**********************************************************************************/ +static void PortDataProcess( void ) +{ + float fvalue, fcorvalue, *fvalua, frnb/*, fwind*/; + //WORD uDevAddr; + unsigned char cmdidx; + int i, j, aipnt, datanum; + SIO_PARAM_SERIAL_DEF *pPortParam; + char szbuf[64]; + + pPortParam = &serialport; + //取出装置地址,开始处理地址+++ + if(0x02 == pPortParam->m_au8RecvBuf[5]) + { + //pPortParam->devaddr = pPortParam->m_au8RecvBuf[4]; + return; + } + cmdidx = pPortParam->m_au8RecvBuf[5]; +#if 0 + aipnt = pPortParam->SameTypeDevIdx; + uDevAddr = serialport->m_au8RecvBuf[4]; + if(0 == srdt.IsReadWireTem) + { + if(uDevAddr != pPortParam->devaddr) + return; + } +#endif + fvalua = &fvalue; + datanum = pPortParam->m_au8RecvBuf[6]; + if((0x08 != cmdidx) && (0x09 != cmdidx)) + return; + + for(i = 0, j=7; (im_au8RecvBuf[1]); i++, j+=5 ) + { + if(0x08 == cmdidx) + fvalue = (pPortParam->m_au8RecvBuf[j+1]<<24)+(pPortParam->m_au8RecvBuf[j+2]<<16) + +(pPortParam->m_au8RecvBuf[j+3]<<8)+pPortParam->m_au8RecvBuf[j+4]; + else + { + *(u_char *)fvalua = pPortParam->m_au8RecvBuf[j+4]; + *((u_char *)fvalua+1) = pPortParam->m_au8RecvBuf[j+3]; + *((u_char *)fvalua+2) = pPortParam->m_au8RecvBuf[j+2]; + *((u_char *)fvalua+3) = pPortParam->m_au8RecvBuf[j+1]; + } + switch(pPortParam->m_au8RecvBuf[j]) + { + case 1: /*温度*/ + weatherpntmsg[0] = fvalue; + LOGE("温度:%0.3f ", fvalue); + break; + case 2: /*气压*/ + weatherpntmsg[5] = fvalue; + LOGE("气压:%0.3f ", fvalue); + break; + case 3: /*湿度*/ + weatherpntmsg[1] = fvalue; + LOGE("湿度:%0.3f ", fvalue); + break; + case 4: /*雨量*/ + break; + case 5: /*日照*/ + break; + case 6: /*风速*/ + weatherpntmsg[2] = fvalue; + LOGE("风速:%0.3f ", fvalue); + break; + case 7: /*风向*/ + weatherpntmsg[3] = fvalue; + LOGE("风向:%0.3f ", fvalue); + break; + case 8: /*拉力*/ + case 9: /*倾角传感器X轴倾角*/ + case 10: /*倾角传感器Y轴倾角*/ + case 11: /*测温球导线温度*/ + case 12: /*测温球内部温度*/ + break; + case 13: /*测温球导线X轴倾角*/ + break; + case 14: /*测温球导线Y轴倾角*/ + break; + case 15: /*测温球导线电流*/ + break; + case 16: /*测温球电池电压*/ + break; + case 17: /*A相泄漏电流平均值;*/ + break; + case 18: /*A相泄漏电流最大值;*/ + break; + case 19: /*A相超过3mA的脉冲频次*/ + break; + case 20: /*A相超过10mA的脉冲频次*/ + break; + case 21: /*B相泄漏电流平均值;*/ + break; + case 22: /*B相泄漏电流最大值;*/ + break; + case 23: /*B相超过3mA的脉冲频次*/ + break; + case 24: /*B相超过10mA的脉冲频次*/ + case 25: /*C相泄漏电流平均值;*/ + case 26: /*C相泄漏电流最大值;*/ + case 27: /*C相超过3mA的脉冲频次*/ + case 28: /*C相超过10mA的脉冲频次*/ + break; + } + } +} + +/*************************************************************** +* 按照协议格式化接收数据 * +***************************************************************/ +static void RecvData(u_char *buf, int len)// 规约读数据处理 +{ + int i, ictime; + //WORD crc, check; + SIO_PARAM_SERIAL_DEF *pPortParam; + + pPortParam = &serialport; + ictime = (int)time(NULL); + + if(pPortParam->m_iRecvLen == 0) + { + pPortParam->iRecvTime = ictime; + } + else + { + if((ictime-pPortParam->iRecvTime > 6) || (ictime - pPortParam->iRecvTime < 0)) + pPortParam->iRecvTime = ictime; + else if(ictime - pPortParam->iRecvTime > 2) + { + pPortParam->m_iRecvLen = 0; + pPortParam->m_iRevStatus = 0; + } + } + + for(i=0; im_iRevStatus) + { + case 0: // 0x68 + pPortParam->m_iRecvLen = 0; + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(0x68 == buf[i]) + pPortParam->m_iRevStatus++; + else + pPortParam->m_iRevStatus = 18; + break; + case 1: // len1 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iRevStatus++; + break; + case 2: // len2 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(buf[i] == pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2]) + { + pPortParam->m_iRevStatus++; + pPortParam->m_iNeedRevLength = buf[i]+5; + } + else + pPortParam->m_iRevStatus = 18; + break; + case 3: // 0x68 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iNeedRevLength--; + if(0x68 == buf[i]) + pPortParam->m_iRevStatus++; + else + pPortParam->m_iRevStatus = 18; + break; + case 4: // 正确接收数据 + pPortParam->m_iNeedRevLength--; + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(pPortParam->m_iNeedRevLength > 0) + break; + if(buf[i] != 0x16) + { + pPortParam->m_iRevStatus=18; + break; + } + + //if(CheckLpcError(serialport->m_au8RecvBuf, pPortParam->m_iRecvLen) == TRUE) + { + PortDataProcess(); + pPortParam->m_iRevStatus = 0; + pPortParam->RevCmdFlag = 1; + } + pPortParam->m_iRecvLen = 0; + break; + case 255:// 错误接收数据 + default: + if(buf[i] == 0x68) + { + pPortParam->m_iRevStatus = 1; + pPortParam->m_iRecvLen = 1; + pPortParam->m_au8RecvBuf[0] = buf[i]; + } + else if(buf[i] == 0x16) + { + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iRevStatus = 0; + pPortParam->m_iRecvLen = 0; + } + else + { + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(pPortParam->m_iRecvLen > 200) + { + pPortParam->m_iRecvLen = 0; + } + } + break; + } + } +} + +static LONG get_msec(void ) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + LONG time_in_msec = tv.tv_sec * 1000 + tv.tv_usec/1000; + + return time_in_msec; +} +//int inum =0; +//int itimecnt=0; +static int weather_comm(SERIAL_PARAM weatherport) +{ + int fd = -1; + int len, i,ret, icnt=0; + LONG ictime, iruntime, isendtime, irecvtime; + unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x01,0x09,0x0a,0x16}; + char recvbuf[256], szbuf[512]; + //char serial_description[] = "/dev/ttyS0"; + +#if 0 + DIR *dir = opendir("/dev"); + if (dir == NULL) { + LOGE("_test_ opendir"); + return -1; + } + + // 读取目录项 + struct dirent *entry; + while ((entry = readdir(dir)) != NULL) { + // 过滤出串口设备,通常以"ttyS"或"ttyUSB"开头 + if ((strncmp(entry->d_name, "ttyS2", 5) == 0) || + (strncmp(entry->d_name, "ttyS0", 5) == 0)) { + LOGE("_test_ Found serial port: %s\n", entry->d_name); + } + } + + // 关闭目录 + closedir(dir); +#endif + serialport.RevCmdFlag = 1; + serialport.m_iRecvLen = 0; + serialport.m_iRevStatus = 0; + + set12VEnable(true); + setCam3V3Enable(true); + setRS485Enable(true); + sleep(2); + //ictime = (int)time(NULL); + ictime = get_msec(); + for(;;) + { + if(fd < 0) + { + fd = open(weatherport.pathname, O_RDWR | O_NDELAY); + //fd = open(weatherport.pathname, O_RDWR | O_NOCTTY); + if(fd < 0) + { + LOGE("_test_ open serial error \n"); + perror(weatherport.pathname); + return -1; + } + + ret= set_port_attr (fd, weatherport.baudrate,weatherport.databit,weatherport.stopbit,weatherport.parity,0,0 );/*9600 8n1 */ + if(ret < 0) + { + LOGE("_test_ set uart arrt faile \n"); + return -1; + } + } + + usleep(10000); + //iruntime = (int)time(NULL); + iruntime = get_msec(); + if((iruntime - ictime > 120000) || (iruntime - ictime < 0)) + ictime = iruntime; + if(iruntime - ictime > 20000) + { + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf, "气象采样时间=%0.3f秒,停止采样!", (iruntime-ictime)/1000.0); + LOGE("%s", szbuf); + break; + } + + if(1 == serialport.RevCmdFlag) + { + set485WriteMode(); + + len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */ + serialport.RevCmdFlag = 0; + LOGE("发送命令时间差%ld毫秒", get_msec()-isendtime); + //isendtime = time(NULL); + isendtime = get_msec(); + if (len < 0) { + LOGE("write data error \n"); + return -1; + } else { + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf, "Send:"); + for (i = 0; i < len; i++) { + sprintf(szbuf, "%s %02X", szbuf, sendbuf[i]); + } + LOGE("%s", szbuf); + //icnt = 0; + //inum++; + } + tcdrain(fd); + //usleep(50000); + } + else + { + //irecvtime = time(NULL); + irecvtime = get_msec(); + if((irecvtime-isendtime > 6000) ||(irecvtime - isendtime < 0)) + isendtime = irecvtime; + if (irecvtime-isendtime > 300) + { + LOGE("传感器超过%ld毫秒未应答", irecvtime-isendtime); + serialport.RevCmdFlag = 1; + serialport.m_iRecvLen = 0; + serialport.m_iRevStatus = 0; + close(fd); + fd = -1; + continue; + } + } + set485ReadMode(); + memset(recvbuf, 0, sizeof(recvbuf)); + len = read(fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */ + if (len < 0) { + LOGE("serial read error \n"); + continue; + } + if(0 == len) + { + //icnt++; + continue; + } + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf, "Recv:"); + for (i = 0; i < len; i++) { + sprintf(szbuf, "%s %02X", szbuf, recvbuf[i]); + } + __android_log_print(ANDROID_LOG_INFO, "serial", "%s", szbuf); + RecvData((u_char*)recvbuf, len); + //LOGE("一周期空循环次数%d, 读取次数%d, 时间:%d %d", icnt, inum, (int)time(NULL), itimecnt); + icnt = 0; + //serialport.RevCmdFlag =1; + } + + close(fd); + set12VEnable(false); + setCam3V3Enable(false); + setRS485Enable(false); + + //exit(-1); + return(0); +} + +int serial_port_comm() +{ + SERIAL_PARAM portparm; + + //struct timeval tv; + + //gettimeofday(&tv, NULL); + //LONG time_in_microseconds = tv.tv_sec * 1000000 + tv.tv_usec; + + //LOGE("Current time in microseconds: %ld\n", time_in_microseconds); + +#if 1 + memset(portparm.pathname, 0, sizeof(portparm.pathname)); + sprintf(portparm.pathname, "/dev/ttyS0"); + portparm.parity = 'N'; + portparm.databit = 8; + portparm.baudrate = B9600; + memset(portparm.stopbit, 0, sizeof(portparm.stopbit)); + sprintf(portparm.stopbit, "1"); +#endif + //itimecnt = (int)time(NULL); + + //for(;;) + weather_comm(portparm); + return 0; +} +#endif + +static speed_t getBaudrate(unsigned int baudrate) +{ + switch(baudrate) { + case 0: return B0; + case 50: return B50; + case 75: return B75; + case 110: return B110; + case 134: return B134; + case 150: return B150; + case 200: return B200; + case 300: return B300; + case 600: return B600; + case 1200: return B1200; + case 1800: return B1800; + case 2400: return B2400; + case 4800: return B4800; + case 9600: return B9600; + case 19200: return B19200; + case 38400: return B38400; + case 57600: return B57600; + case 115200: return B115200; + case 230400: return B230400; + case 460800: return B460800; + case 500000: return B500000; + case 576000: return B576000; + case 921600: return B921600; + case 1000000: return B1000000; + case 1152000: return B1152000; + case 1500000: return B1500000; + case 2000000: return B2000000; + case 2500000: return B2500000; + case 3000000: return B3000000; + case 3500000: return B3500000; + case 4000000: return B4000000; + default: return B9600; + } +} + +static LONG get_msec() +{ + struct timeval tv; + LONG time_in_msec=0; + + gettimeofday(&tv, NULL); + time_in_msec = tv.tv_sec; + time_in_msec *= 1000; + time_in_msec += tv.tv_usec/1000; + + return time_in_msec; +} + +/* +打开串口电源 +*/ +void Gm_OpenSerialPower() +{ + /*由传送的主站的地方来控制串口电源,这里不实现*/; +} + +// 关闭串口电源 +void Gm_CloseSerialPower() +{ +} + +// 关闭传感器电源 +void Gm_CloseSensorsPower() +{ + //char iIoNo; + //char szbuf[128]; + int igpio; + + //sprintf(szbuf, "Close Sensors port %d Power!", port); + + /* 关闭电源*/ + //switch(port) + /* 根据硬件具体布置最后调整,目前是微拍板子的来控制*/ + //set12VEnable(false); + //setCam3V3Enable(false); + //setRS485Enable(false); + +#if 0 + setInt(CMD_SET_WTH_POWER, 0); + setInt(CMD_SET_PULL_POWER, 0); + setInt(CMD_SET_ANGLE_POWER, 0); + setInt(CMD_SET_OTHER_POWER, 0); + setInt(CMD_SET_PIC1_POWER, 0); + + sleep(3); + igpio = getInt(CMD_SET_WTH_POWER); + igpio = getInt(CMD_SET_PULL_POWER); + igpio = getInt(CMD_SET_ANGLE_POWER); + igpio = getInt(CMD_SET_OTHER_POWER); + igpio = getInt(CMD_SET_PIC1_POWER); +#endif +#if 1 + setInt(CMD_SET_SPI_POWER, 1); + setInt(CMD_SET_485_en0, 1); + setInt(CMD_SET_485_en1, 1); + setInt(CMD_SET_485_en2, 1); + setInt(CMD_SET_485_en3, 1); + setInt(CMD_SET_485_en4, 1); +#else + setInt(CMD_SET_SPI_POWER, 0); + setInt(CMD_SET_485_en0, 0); + setInt(CMD_SET_485_en1, 0); + setInt(CMD_SET_485_en2, 0); + setInt(CMD_SET_485_en3, 0); + setInt(CMD_SET_485_en4, 0); + sleep(3); + igpio = getInt(CMD_SET_SPI_POWER); + igpio = getInt(CMD_SET_485_en0); + igpio = getInt(CMD_SET_485_en1); + igpio = getInt(CMD_SET_485_en2); + igpio = getInt(CMD_SET_485_en3); + igpio = getInt(CMD_SET_485_en4); +#endif + +} + +// 打开传感器电源 +void Gm_OpenSensorsPower() +{ + //char iIoNo; + int igpio; + char szbuf[128]; + + //if(0 == port) + // return; + //sprintf(szbuf, "Open Sensors port %d Power!", port); + + set12VEnable(true); + setCam3V3Enable(true); + setRS485Enable(true); + setInt(CMD_SET_485_ENABLE, 1); // 打开RS485电源 + setInt(CMD_SET_3V3_PWR_ENABLE, 1); // 打开3.3V电压 + setInt(CMD_SET_PTZ_PWR_ENABLE, 1); + +#if 0 + setInt(CMD_SET_WTH_POWER, 0); + setInt(CMD_SET_PULL_POWER, 0); + setInt(CMD_SET_ANGLE_POWER, 0); + setInt(CMD_SET_OTHER_POWER, 0); + setInt(CMD_SET_PIC1_POWER, 0); +#else + setInt(CMD_SET_WTH_POWER, 1); + setInt(CMD_SET_PULL_POWER, 1); + setInt(CMD_SET_ANGLE_POWER, 1); + setInt(CMD_SET_OTHER_POWER, 1); + setInt(CMD_SET_PIC1_POWER, 1); + //sleep(3); + igpio = getInt(CMD_SET_WTH_POWER); + igpio = getInt(CMD_SET_PULL_POWER); + igpio = getInt(CMD_SET_ANGLE_POWER); + igpio = getInt(CMD_SET_OTHER_POWER); + igpio = getInt(CMD_SET_PIC1_POWER); + +#endif +#if 1 + setInt(CMD_SET_SPI_POWER, 1); + setInt(CMD_SET_485_en0, 1); + setInt(CMD_SET_485_en1, 1); + setInt(CMD_SET_485_en2, 1); + setInt(CMD_SET_485_en3, 1); + setInt(CMD_SET_485_en4, 1); + + //sleep(3); + igpio = getInt(CMD_SET_SPI_POWER); + igpio = getInt(CMD_SET_485_en0); + igpio = getInt(CMD_SET_485_en1); + igpio = getInt(CMD_SET_485_en2); + igpio = getInt(CMD_SET_485_en3); + igpio = getInt(CMD_SET_485_en4); + +#else + setInt(CMD_SET_485_en0, 0); + setInt(CMD_SET_485_en1, 0); + setInt(CMD_SET_485_en2, 0); + setInt(CMD_SET_485_en3, 0); + setInt(CMD_SET_485_en4, 0); +#endif + + /* 打开电源*/ + //switch(port) + +} + +// 查询传感器电源状态 +char Gm_GetSensorsPowerState(int port) +{ + char iIoNo, cstate=0; + //char szbuf[128]; + + /* 查询电源状态*/ + //switch(port) + + + return cstate; +} + +void BytestreamLOG(int commid, char* describe, u_char* buf, int len, char flag) +{ + int i; + char szbuf[4096]; + + memset(szbuf, 0, sizeof(szbuf)); + if(NULL != describe) + strncpy(szbuf, describe, strlen(describe)); + for (i = 0; i < len; i++) + { + sprintf(szbuf, "%s %02X", szbuf, buf[i]); + } + SaveLogTofile(commid, szbuf); + switch (flag) + { + case 'E': + LOGE("%s", szbuf); + break; + case 'I': + LOGI("%s", szbuf); + break; + case 'D': + LOGD("%s", szbuf); + break; + case 'V': + LOGV("%s", szbuf); + break; + case 'W': + LOGW("%s", szbuf); + break; + default: + LOGI("%s", szbuf); + break; + } +} + +// 打开串口通讯 +void Gm_OpenSerialPort(int devidx) +{ + int fd = -1; + char szbuf[512]; + + if((devidx < 0) || (devidx >= MAX_SERIAL_DEV_NUM)) + return; + memset(szbuf, 0, sizeof(szbuf)); + if(serialport[devparam[devidx].commid].fd <= 0) + { + fd = open(devparam[devidx].pathname, O_RDWR | O_NDELAY); + if(fd < 0) + { + sprintf(szbuf, "装置%d 打开串口%d %s失败!fd=%d", devidx+1, devparam[devidx].pathname, devparam[devidx].commid+1, fd); + DebugLog(devparam[devidx].commid, szbuf, 'E'); + return; + } + sprintf(szbuf, "装置%d 打开串口%d %s成功!fd=%d", devidx+1, devparam[devidx].commid+1, devparam[devidx].pathname, fd ); + DebugLog(devparam[devidx].commid, szbuf, 'I'); + serialport[devparam[devidx].commid].fd = fd; + return; + } + sprintf(szbuf, "装置%d 串口%d %s已经打开!fd=%d", devidx+1, devparam[devidx].commid+1, devparam[devidx].pathname,serialport[devparam[devidx].commid].fd); + DebugLog(devparam[devidx].commid, szbuf, 'I'); +} + +// 关闭串口通讯 +void Gm_CloseSerialPort() +{ + int i; + + for(i=0; i 0) + { + close(serialport[i].fd); + serialport[i].fd = -1; + } + } + +} + +/******************************************************************************* +函数名称: int GM_SerialComSend(const BYTE * cSendBuf, DWORD nSendLen, int commid) +功能说明:串口发送数据 返回实际发送的字节数 +输入参数: +输出参数: +其它说明: +*********************************************************************************/ +int GM_SerialComSend(unsigned char * cSendBuf, LONG nSendLen, int commid) +{ + int i, len; + char szbuf[512]; + + memset(szbuf, 0, sizeof(szbuf)); + len = write(serialport[commid].fd, cSendBuf, (size_t)nSendLen);/* 向串囗发送字符串 */ + //serialport[commid].RevCmdFlag = 0; + //LOGE("发送命令时间差%ld毫秒", get_msec() - isendtime); + //isendtime = time(NULL); + //isendtime = get_msec(); + if (len < 0) + { + sprintf(szbuf, "write data error "); + DebugLog(commid, szbuf, 'E'); + return -1; + } + else if(len > 0) + { + ; + } + return len; +} + +int Gm_SetSerialPortParam(int commid) +{ + int ret; + char szbuf[128]; + SERIAL_PARAM *pPortParam=NULL; + + pPortParam = &devparam[srdt.curdevidx[commid]]; + ret= set_port_attr (serialport[commid].fd, pPortParam->baudrate,pPortParam->databit,pPortParam->stopbit,pPortParam->parity,0,0 );/*9600 8n1 */ + if(ret < 0) + { + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf,"串口%d 波特率等参数设置错误!", commid+1); + DebugLog(commid, szbuf, 'E'); + return -1; + } + return ret; +} + +void Gm_InitSerialComm_Test() +{ + int i, j; + SENSOR_PARAM sensorParam[MAX_SERIAL_DEV_NUM]; + +#if 0 + srdt.PtzCmdType = Cmd_Cancel; // 云台指令类型 + for(i=0; i*/ + //sprintf(devparam[i].pathname, "/dev/swk3"); + devparam[i].commid = 0; + break; + case SLANT_PROTOCOL: + //memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname)); + /* 目前还不确定具体串口分配,暂时默认使用串口1*/ + //sprintf(devparam[i].pathname, "/dev/swk2"); + devparam[i].commid = 2; + break; + case RALLY_PROTOCOL: + //memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname)); + /* 目前还不确定具体串口分配,暂时默认使用串口1*/ + //sprintf(devparam[i].pathname, "/dev/swk1"); + devparam[i].commid = 1; + break; + case PELCO_D_PROTOCOL: /* 摄像机协议*/ + case PELCO_P_PROTOCOL: /* 摄像机协议*/ + case SERIALCAMERA_PROTOCOL: /* 串口摄像机协议*/ + //memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname)); + /* 目前还不确定//具体串口分配,暂时默认使用串口1*/ + //sprintf(devparam[i].pathname, "/dev/ttyS1"); + devparam[i].commid = 1; + srdt.camerauseserial = 1; + break; + default: + devparam[i].IsNoInsta = 0; + break; + } + } +} + +void GM_StartSerialComm() +{ + int i, j, commid; + char szbuf[64], logbuf[128]; + //LONG polltime=0; + + // 此处不能对轮询设备标识清零,否则如果先起摄像机,就会导致poll乱掉 + //memset((void*)srdt.curdevidx, 0, sizeof(srdt.curdevidx)); + //Gm_OpenSerialPower(); /* 不在这使用*/ + //FindDevUseSerialCommNo(); + // 初始化串口使用状态(需要考虑不同时间启用了摄像机使用) + for (i = 0; i < MAX_SERIAL_PORT_NUM; i++) + { + if(i == srdt.camerauseserial) + continue; + serialport[i].Retry = 0; + serialport[i].RetryTime = 800; + serialport[i].WaitTime = 20; + serialport[i].m_iRevStatus = 0; + serialport[i].m_iRecvLen = 0; + serialport[i].m_iNeedRevLength = 0; + serialport[i].fd = -1; + memset(serialport[i].m_au8RecvBuf, 0, RECVDATA_MAXLENTH); // 接收数据缓存区 + ClearCmdFormPollCmdBuf(i); + } +#if 0/* 简化插入使用摄像机过程,摄像机使用单独的串口*/ + else + { + for (i = 0; i < MAX_SERIAL_PORT_NUM; i++) + { + for(j=0; j= MAX_SERIAL_PORT_NUM)) + return; + serialport[i].Retry = 0; + serialport[i].RetryTime = 1000; + serialport[i].WaitTime = 0; + serialport[i].m_iRevStatus = 0; + serialport[i].m_iRecvLen = 0; + serialport[i].m_iNeedRevLength = 0; + serialport[i].fd = -1; + memset(serialport[i].m_au8RecvBuf, 0, RECVDATA_MAXLENTH); // 接收数据缓存区 + ClearCmdFormPollCmdBuf(i); + + // 初始化串口使用状态 + for(i=0; idevparam[i].CameraChannel) || (devparam[i].CameraChannel >MAX_CHANNEL_NUM)) + { + srdt.ms_dev[i].IsNeedSerial = 0; + break; + } + if(channel == devparam[i].CameraChannel) + { + ; + } + else + break; + if(0 == srdt.ms_dev[i].IsNeedSerial) + srdt.iLastGetPhotoNo = -1; + else + srdt.iLastGetPhotoNo = srdt.ms_dev[i].SerialCmdidx; + srdt.ms_dev[i].IsNeedSerial = 1; + if(0 == cmdidx) + srdt.ms_dev[i].image.state = StartSample; + if((0 == cmdidx) && (srdt.presetno > 0 )) + { + srdt.ms_dev[i].SerialCmdidx = 10017; + srdt.iLastGetPhotoNo = cmdidx; + } + else + srdt.ms_dev[i].SerialCmdidx = cmdidx; + srdt.ms_dev[i].FirstCmdTimeCnt = get_msec(); + srdt.sendphotocmdcnt = 0; + sprintf(szbuf, "摄像机"); + flag = 1; + break; + default: + if(1 == srdt.ms_dev[i].IsNeedSerial) + break; + srdt.ms_dev[i].IsNeedSerial = 0; + break; + } + if(1 == srdt.ms_dev[i].IsNeedSerial) + { + sprintf(logbuf, "装置%d, IsNoInsta=%d, 类型:%s", i+1, devparam[i].IsNoInsta, szbuf); + DebugLog(8, logbuf, 'I'); + Gm_OpenSensorsPower(); + Gm_OpenSerialPort(i); + } + } + if(0x01 == flag) + { + sprintf(szbuf, "摄像机启动串口定时器!"); + DebugLog(8, szbuf, 'I'); + for(;;) + { + usleep(10); + //LOGW("polltime=%ldms", get_msec()-polltime); + //polltime = get_msec(); + if(GM_SerialTimer() < 0) + { + //LOGE("12V state=%d", getInt(CMD_SET_12V_EN_STATE)); + DebugLog(8, "退出拍照流程!", 'V'); + sleep(3); + break; + } + } + } + //return; +} +#endif + +int GM_SerialTimer(void) +{ + int flag = -1; + + GM_AllSerialComRecv(); + GM_IsCloseSensors(); + Gm_FindAllSensorsCommand(); + GM_AllSerialComRecv(); + flag = GM_CloseTimer(); + return flag; +} + +/******************************************************************************** +函数名称: void Gm_FindAllSensorsCommand() +功能说明:轮询所有串口和传感器是否需要生成下发命令 +输入参数: +输出参数: +其它说明: +*********************************************************************************/ +void Gm_FindAllSensorsCommand() +{ + int i, j,curidx,flag; + + //Gm_CheckSensorsPower(); /* 暂时不考虑电源控制*/ + for(j=0; j 0) + break; + //LOGE("12V state=%d", getInt(CMD_SET_12V_EN_STATE)); + //LOGE("3.3V state= %d", getInt(CMD_SET_CAM_3V3_EN_STATE)); + //LOGE("485 state=%d", getInt(CMD_SET_485_EN_STATE)); + + + flag = -1; + switch(devparam[curidx].ProtocolIdx) + { + case WEATHER_PROTOCOL: /* 温湿度气压*/ + case RALLY_PROTOCOL: /* 拉力*/ + case WIND_PROTOCOL: /* 风速风向*/ + case SLANT_PROTOCOL: /* 倾角*/ + flag = FindNextShxyProtocolCommand(curidx); + break; + case RESERVE2_PROTOCOL: + break; + case RESERVE5_PROTOCOL: + break; + case PELCO_D_PROTOCOL: /* 摄像机协议*/ + case PELCO_P_PROTOCOL: /* 摄像机协议*/ + case SERIALCAMERA_PROTOCOL: /* 串口摄像机协议*/ + flag = FindNextCameraPhotoCommand(curidx); + break; + break; + } + if(flag == -1) + continue; + srdt.curdevidx[j] = curidx; + break; + } + // 发送缓冲区中命令 生成了命令之后紧接着进行命令发送 + SendCmdFormPollCmdBuf(j); + } +} + +/******************************************************************************** +函数名称: void GM_IsCloseSensors() +功能说明:检查所有传感器是否采集完毕,采集完毕的关闭传感器电源 +输入参数: +输出参数: +其它说明: +*********************************************************************************/ +void GM_IsCloseSensors() +{ + int i, j; + char buf[256]; + LONG lctime; + + lctime = get_msec(); + for(i=0; i 50*1000) ||(lctime-srdt.ms_dev[i].FirstCmdTimeCnt < 0)) + { + srdt.ms_dev[i].FirstCmdTimeCnt = lctime; + break; + } + if(lctime - srdt.ms_dev[i].FirstCmdTimeCnt > 15*1000) + { + srdt.ms_dev[i].IsNeedSerial = 0; + // 关闭传感器电源 + sprintf(buf, "读取装置%d数据%0.3f秒,关闭装置%d电源!", i+1, (get_msec()-srdt.ms_dev[i].FirstCmdTimeCnt)/1000.0,i+1); + DebugLog(devparam[i].commid, buf, 'I'); + for(j=0;jdevparam[i].ProtocolIdx))) + break; + } + if(i < MAX_SERIAL_DEV_NUM) + { + return 1; // 寻找 + } + else // 关闭所有串口及电源 + { + Gm_CloseSerialPort(); + for(j=0; j< MAX_SERIAL_DEV_NUM; j++) + Gm_CloseSensorsPower(); + for(j=0; jimage.imagelen); + if(NULL == image) + return -1; + tempphoto = image; + for (i = 0; i < pPortParam->image.imagenum; ++i) { + memmove(tempphoto, &pPortParam->image.buf[i], (size_t)pPortParam->image.ilen[i]); + tempphoto += (size_t)pPortParam->image.ilen[i]; + } + + memset(szbuf, 0, sizeof(szbuf)); + //memset(filedir, 0, sizeof(filedir)); + //sprintf(filedir, "/sdcard/photo/"); + + if(access(srdt.filedir, 0)==0) + { + sprintf(szbuf,"文件路径%s已经存在!", srdt.filedir); + DebugLog(devparam[devno].commid, szbuf, 'I'); + } + else + { + status = mkdir(srdt.filedir, S_IRWXU | S_IRWXG | S_IRWXO); + if(status < 0) + return -1; + } + // 写入文件到sdcard + memset(pPortParam->image.photoname, 0, sizeof(pPortParam->image.photoname)); + sprintf(pPortParam->image.photoname, "%s%d-%d-%d.jpg", srdt.filedir,devparam[devno].CameraChannel, pPortParam->image.presetno, pPortParam->image.phototime); + fp = fopen(pPortParam->image.photoname, "wb+"); + if(NULL == fp) + return -1; + len = fwrite(image,1, pPortParam->image.imagelen, fp); + fclose(fp); + free(image); + image = NULL; + if(len < pPortParam->image.imagelen) + return -1; + else + { + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf,"写入图片文件%s成功!", pPortParam->image.photoname); + DebugLog(devparam[devno].commid, szbuf, 'I'); + return 1; + } +} + +/******************************************************************* +* 读 摄像机 数据 * +*******************************************************************/ +void CameraRecvData(int devno, u_char *buf, int len) +{ + int i; + SIO_PARAM_SERIAL_DEF *pPortParam; + + if((devno<0) || (devno > MAX_SERIAL_DEV_NUM)) + { + return; + } + pPortParam = &serialport[devparam[devno].commid]; + + for(i=0; im_iRevStatus) + { + case 0: // 0x68 + pPortParam->m_iRecvLen = 0; + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(0x68 == buf[i]) + pPortParam->m_iRevStatus++; + else + pPortParam->m_iRevStatus = 18; + break; + case 1: // len1 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iRevStatus++; + break; + case 2: // len2 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iRevStatus++; + pPortParam->m_iNeedRevLength = pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2]*256+buf[i]+5; + break; + case 3: // 0x68 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iNeedRevLength--; + if(0x68 == buf[i]) + pPortParam->m_iRevStatus++; + else + pPortParam->m_iRevStatus = 18; + break; + case 4: // 正确接收数据 + pPortParam->m_iNeedRevLength--; + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(pPortParam->m_iNeedRevLength > 0) + break; + if(buf[i] != 0x16) + { + pPortParam->m_iRevStatus=18; + break; + } + + if(pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2] == + CalLpc( &pPortParam->m_au8RecvBuf[4], pPortParam->m_iRecvLen-6 )) + { + CameraPhotoPortDataProcess(devno); + pPortParam->m_iRevStatus = 0; + pPortParam->RevCmdFlag = 1; + } + else + { + pPortParam->m_iRevStatus = 0; + } + pPortParam->m_iRecvLen = 0; + break; + case 255:// 错误接收数据 + default: + if(buf[i] == 0x68) + { + pPortParam->m_iRevStatus = 1; + pPortParam->m_iRecvLen = 1; + pPortParam->m_au8RecvBuf[0] = buf[i]; + } + else if(buf[i] == 0x16) + { + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iRevStatus = 0; + pPortParam->m_iRecvLen = 0; + } + else + { + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(pPortParam->m_iRecvLen > 200) + { + pPortParam->m_iRecvLen = 0; + } + } + break; + } + } +} + +/********************************************************************************* + CameraPhoto 端口数据处理 +**********************************************************************************/ +void CameraPhotoPortDataProcess( int devno) +{ + RTUMSG rtumsg; + SERIAL_DEV_DEF *pPortParam; + SIO_PARAM_SERIAL_DEF *curserial; + int img_file_size, packetnum, iNo, packsize, i=0, presetno, iphototime, pidx; + char szbuf[128]; + WORD uDevAddr; + BYTE cmdidx, recvend; + + pPortParam = &srdt.ms_dev[devno]; + curserial = &serialport[devparam[devno].commid]; + + memset((void*)rtumsg.MsgData, 0, sizeof(rtumsg.MsgData)); + memcpy((void*)rtumsg.MsgData, (void*)curserial->m_au8RecvBuf, curserial->m_iRecvLen); + rtumsg.MsgLen = curserial->m_iRecvLen; + rtumsg.PortIdx = devparam[devno].commid; + cmdidx = curserial->m_au8RecvBuf[5]; + uDevAddr = curserial->m_au8RecvBuf[4]; + + //sprintf(szbuf, "摄像机地址%d,命令%02X!", uDevAddr, cmdidx); + //DebugStringPrintf(szbuf, strlen(szbuf), 1); + if(uDevAddr != devparam[devno].devaddr) + return; + memset(szbuf, 0, sizeof(szbuf)); + switch(cmdidx) + { + case 0x10: /* 拍照应答*/ + if(0xFF == rtumsg.MsgData[6]) + { + srdt.RephotographCnt++; + if(srdt.RephotographCnt > 2) + { + pPortParam->SerialCmdidx = -1; + sprintf(szbuf, "因摄像机重拍%d次均未成功!结束拍照!",srdt.RephotographCnt); + DebugLog(devparam[devno].commid, szbuf, 'E'); + } + break; + } + i = 6; + memset(&pPortParam->image, 0, sizeof(pPortParam->image)); + iphototime = rtumsg.MsgData[i+3]+ (rtumsg.MsgData[i+2]<<8)+(rtumsg.MsgData[i+1]<<16)+(rtumsg.MsgData[i]<<24); + srdt.photographtime = iphototime; + pPortParam->image.phototime = iphototime; + i=10; + img_file_size = rtumsg.MsgData[i+3]+ (rtumsg.MsgData[i+2]<<8)+(rtumsg.MsgData[i+1]<<16)+(rtumsg.MsgData[i]<<24); + packetnum = rtumsg.MsgData[i+5]+(rtumsg.MsgData[i+4]<<8); + pPortParam->image.imagelen = img_file_size; + pPortParam->image.imagenum = packetnum; + srdt.imagepacketnum = packetnum; + srdt.historyimagenum[devparam[devno].CameraChannel-1] = rtumsg.MsgData[i+7]+(rtumsg.MsgData[i+6]<<8); + sprintf(szbuf, "有%d张历史图片!",srdt.historyimagenum[devparam[devno].CameraChannel-1]); + DebugLog(devparam[devno].commid, szbuf, 'V'); + presetno = (int)rtumsg.MsgData[i+8]; + pPortParam->image.presetno = presetno; + pPortParam->image.state = Sample; + curserial->RevCmdFlag = 1; + pPortParam->SerialCmdidx = 1; + srdt.sendphotocmdcnt = 0; + break; + case 0x11: /* 图片数据包*/ + i = 6; + iNo = rtumsg.MsgData[i+1]+rtumsg.MsgData[i]*256; + packsize = rtumsg.MsgData[i+3]+rtumsg.MsgData[i+2]*256; + memmove(&pPortParam->image.buf[iNo-1], &rtumsg.MsgData[i+4], packsize); + pPortParam->image.ilen[iNo-1] = packsize; + sprintf(szbuf, "收到第%d(总%d包)包长=%d", iNo, srdt.imagepacketnum, packsize); + DebugLog(devparam[devno].commid, szbuf, 'V'); + curserial->RevCmdFlag = 1; + pPortParam->FirstCmdTimeCnt = get_msec(); + if((iNo == pPortParam->SerialCmdidx) && (0xFF > rtumsg.MsgData[i+2])) + { + if(iNo == srdt.imagepacketnum) + { /* 检查是否有漏包*/ + for(pidx = 0; pidx < srdt.imagepacketnum; pidx++) + { + if(pPortParam->image.ilen[pidx] < 1) + break; + } + if(pidx < srdt.imagepacketnum) + { + iNo = pidx; + recvend = 0; + } + else + { + if((1 == SaveImageDataTofile(devno)) && (Sample == pPortParam->image.state)) + pPortParam->image.state = PHOTO_SAVE_SUCC; + recvend = 1; + } + } + else + recvend = 0; + + if(packsize > MAX_PHOTO_FRAME_LEN) + recvend = 0xFF; + + if(1 == recvend) + { + pPortParam->SerialCmdidx = 10002;/* 图片读取完成*/ + //pPortParam->image.lastlen = packsize; + } + else if(0xFF == recvend) + { + pPortParam->SerialCmdidx = -1; + } + else + { + if((iNo > srdt.imagepacketnum) || (0 >= srdt.imagepacketnum)) + { + pPortParam->SerialCmdidx = -1; + } + else + pPortParam->SerialCmdidx = iNo+1; + } + srdt.errorPhotoNoCnt = 0; + break; + } + srdt.errorPhotoNoCnt++; + sprintf(szbuf, "问询第%d包图片摄像机应答第%d包,连续错误%d次!", + pPortParam->SerialCmdidx, iNo, srdt.errorPhotoNoCnt); + DebugLog(devparam[devno].commid, szbuf, 'E'); + if(srdt.errorPhotoNoCnt > 5) + { + pPortParam->SerialCmdidx = 0; + srdt.RephotographCnt++; + if(srdt.RephotographCnt > 2) + { + pPortParam->SerialCmdidx = -1; + sprintf(szbuf, "因摄像机重拍%d次均未成功!结束拍照!",srdt.RephotographCnt); + DebugLog(devparam[devno].commid, szbuf, 'E'); + } + } + break; + case 0x03: + sprintf(szbuf, "设置波特率%d成功", devparam[devno].baudrate); + DebugLog(devparam[devno].commid, szbuf, 'D'); + pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + curserial->RevCmdFlag = 1; + pPortParam->FirstCmdTimeCnt = get_msec(); + break; + case 0x15: + if(0xFF == rtumsg.MsgData[6]) + { + pPortParam->SerialCmdidx = -1; + sprintf(szbuf, "没有历史图片!结束读取图片!"); + DebugLog(devparam[devno].commid, szbuf, 'I'); + break; + } + i = 6; + iphototime = rtumsg.MsgData[i+3]+ (rtumsg.MsgData[i+2]<<8)+(rtumsg.MsgData[i+1]<<16)+(rtumsg.MsgData[i]<<24); + srdt.photographtime = iphototime; + pPortParam->image.phototime = iphototime; + i=10; + img_file_size = rtumsg.MsgData[i+3]+ (rtumsg.MsgData[i+2]<<8)+(rtumsg.MsgData[i+1]<<16)+(rtumsg.MsgData[i]<<24); + packetnum = rtumsg.MsgData[i+5]+(rtumsg.MsgData[i+4]<<8); + pPortParam->image.imagelen = img_file_size; + pPortParam->image.imagenum = packetnum; + srdt.imagepacketnum = packetnum; + srdt.historyimagenum[devparam[devno].CameraChannel-1] = rtumsg.MsgData[i+7]+(rtumsg.MsgData[i+6]<<8); + presetno = rtumsg.MsgData[i+8]; + pPortParam->image.presetno = presetno; + sprintf(szbuf, "读取历史图片,还有%d张历史图片!",srdt.historyimagenum[devparam[devno].CameraChannel-1]); + DebugLog(devparam[devno].commid, szbuf, 'I'); + curserial->RevCmdFlag = 1; + pPortParam->SerialCmdidx = 1; + srdt.sendphotocmdcnt = 0; + break; + case 0x16: + if(0xFF == rtumsg.MsgData[10]) + { + pPortParam->SerialCmdidx = -1; + sprintf(szbuf, "摄像机图片保存失败!"); + DebugLog(devparam[devno].commid, szbuf, 'E'); + } + pPortParam->SerialCmdidx = -1; + if(0 == rtumsg.MsgData[10]) + { + if(0 == srdt.historyimagenum[devparam[devno].CameraChannel-1]) + { + ; + } + else + { + pPortParam->SerialCmdidx = 10003;/* 暂时不实现*/ + } + } + pPortParam->FirstCmdTimeCnt = get_msec(); + curserial->RevCmdFlag = 1; + break; + default: + curserial->RevCmdFlag = 1; + break; + } +} + +/********************************************************************************* + 发送命令 +**********************************************************************************/ +void SendCmdFormPollCmdBuf( int port ) +{ + char buf[128]; + int len, ret; + LONG lctime; + SIO_PARAM_SERIAL_DEF *pPortParam; + + pPortParam = &serialport[port]; + memset(buf, 0, sizeof(buf)); + lctime = get_msec(); + if(pPortParam->ForceWaitFlag && pPortParam->ForceWaitCnt) + { + pPortParam->ForceWaitCnt--; + return; + } + + if(pPortParam->SendCmdFlag && (pPortParam->RevCmdFlag == 0)) + { + //pPortParam->RetryTimeCnt++; + if((lctime - pPortParam->RetryTimeCnt > 3*pPortParam->RetryTime) || (lctime - pPortParam->RetryTimeCnt < 0)) + { + pPortParam->RetryTimeCnt = lctime; + return; + } + if(lctime - pPortParam->RetryTimeCnt < pPortParam->RetryTime) + //if(pPortParam->RetryTimeCnt < pPortParam->RetryTime) + { + return; + } + pPortParam->RetryTimeCnt = lctime; + pPortParam->RetryCnt++; + if(pPortParam->RetryCnt > pPortParam->Retry) + { + ClearCmdFormPollCmdBuf(port); + } + else + { + pPortParam->SendCmdFlag = 0; + pPortParam->RevCmdFlag = 0; + pPortParam->ReSendCmdFlag = 1; + } + } + + if ( pPortParam->SendCmdFlag && pPortParam->RevCmdFlag ) + { + // 清除当前命令 + ClearCmdFormPollCmdBuf(port); + } + + if(pPortParam->WaitTime > 0) + { + if((lctime - pPortParam->WaitTimeCnt > 30*pPortParam->WaitTime) || (lctime - pPortParam->WaitTimeCnt < 0)) + { + pPortParam->WaitTimeCnt = lctime; + return; + } + + if(lctime- pPortParam->WaitTimeCnt < pPortParam->WaitTime) + { + return; + } + } + pPortParam->WaitTimeCnt = lctime; + + if ( pPortParam->ReSendCmdFlag ) + len = pPortParam->cmdlen; + else + { + len = pPortParam->cmdlen; + pPortParam->RetryCnt = 0; + } + if ( len == 0 ) + return; + + serialport[devparam[srdt.curdevidx[port]].commid].m_iRecvLen = 0; // 当发送一条新指令时,清除接收状态 + serialport[devparam[srdt.curdevidx[port]].commid].m_iRevStatus = 0; + if(serialport[port].fd < 0) + return; + ret = Gm_SetSerialPortParam(port); + if(ret < 0) + return; + len = GM_SerialComSend(&pPortParam->PollCmd[2], pPortParam->cmdlen-2, port); + if(len < 1) + { + sprintf(buf, "串口%d, 发送命令失败!", port+1); + DebugLog(port, buf, 'E'); + } + else + { + + sprintf(buf, "发送串口%d 装置%d命令:", port+1, srdt.curdevidx[port]+1); + BytestreamLOG(port, buf, &pPortParam->PollCmd[2], len, 'D'); + sprintf(buf, "sendtimeconst= %lld", lctime-pPortParam->lsendtime); + DebugLog(port, buf, 'W'); + pPortParam->lsendtime = lctime; + } + pPortParam->SendCmdFlag = 1; + pPortParam->ReSendCmdFlag = 0; + pPortParam->RevCmdFlag = 0; + pPortParam->RetryTimeCnt = lctime; + + pPortParam->ForceWaitCnt = pPortParam->PollCmd[0]*256+pPortParam->PollCmd[1]+TIMER_CNT-1; + pPortParam->ForceWaitCnt /= TIMER_CNT; + if(pPortParam->ForceWaitCnt) + { + pPortParam->ForceWaitFlag = 1; + } +} + +void ClearCmdAllFlag(int commid) +{ + if((commid < 0) || (commid >= MAX_SERIAL_PORT_NUM)) + return; + + serialport[commid].RetryCnt = 0; + serialport[commid].RetryTimeCnt = get_msec(); + serialport[commid].WaitTimeCnt = get_msec(); + serialport[commid].ForceWaitFlag = 0; + serialport[commid].ForceWaitCnt = 0; + serialport[commid].SendCmdFlag = 0; + serialport[commid].RevCmdFlag = 0; + serialport[commid].ReSendCmdFlag = 0; +} + +void ClearCmdFormPollCmdBuf(int port) +{ + //int len, idx; + SIO_PARAM_SERIAL_DEF *pPortParam; + + if((port < 0) || (port >= MAX_SERIAL_PORT_NUM)) + return; + pPortParam = &serialport[port]; + + pPortParam->cmdlen = 0; + memset(pPortParam->PollCmd, 0, sizeof(pPortParam->PollCmd)); + srdt.serialstatus[port] = 0; + // 清除指令下发标识 + ClearCmdAllFlag(port); +} + +// 下发串口拍照指令控制 +int FindNextCameraPhotoCommand(int devidx) +{ + int imagesize=3, cmdno; + BYTE channel, imagequality=90, presetno; + WORD packetsize; + LONG lcurtime; + BYTE cmdidx=0x10; + char szbuf[128]; + + //如果命令缓冲区仍有命令,则退出本函数 + if((devparam[devidx].commid+1 < 1) || (devparam[devidx].commid+1 > MAX_SERIAL_PORT_NUM)) + return -1; + // if(serialport[devparam[devidx].commid].cmdlen > 0) + // return -1; + if(-1 == srdt.ms_dev[devidx].SerialCmdidx)/* 下发拍照指令*/ + return -1; + channel = devparam[devidx].CameraChannel; + if((1>channel) || (channel >MAX_CHANNEL_NUM)) + { + /* 通道号错误退出拍照流程*/; + srdt.ms_dev[devidx].SerialCmdidx = -1; + sprintf(szbuf, "装置配置中,通道号配置错误!结束拍照!"); + DebugLog(devparam[devidx].commid, szbuf, 'I'); + } + cmdno = srdt.ms_dev[devidx].SerialCmdidx; + lcurtime = get_msec(); + if((1 > cmdno) || (10000 <= cmdno)) { + if (lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt < 300) + return -1; + } + switch (cmdno) + { + case 0:/* 下发拍照指令*/ + if(lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt < 3800) + return -1; + if((lcurtime-srdt.ms_dev[devidx].FirstCmdTimeCnt > 3*35*1000) ||(lcurtime-srdt.ms_dev[devidx].FirstCmdTimeCnt < 0)) + { + srdt.ms_dev[devidx].FirstCmdTimeCnt = lcurtime; + return -1; + } + + if(lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt > 35*1000) + { + srdt.ms_dev[devidx].SerialCmdidx = -1; + sprintf(szbuf, "串口摄像机未接或故障!结束拍照!"); + DebugLog(devparam[devidx].commid, szbuf, 'I'); + return -1; + } + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf, "time=%lldms", lcurtime-srdt.ms_dev[devidx].FirstCmdTimeCnt); + DebugLog(devparam[devidx].commid, szbuf, 'I'); + packetsize = (WORD)MAX_PHOTO_FRAME_LEN; + srdt.sendphotocmdcnt++; + srdt.imagepacketnum = 0; + srdt.errorPhotoNoCnt = 0; + cmdidx = 0x10; + imagesize = srdt.bImageSize; + break; + + case 10000: /* 下发设置串口波特率命令*/ + switch(devparam[devidx].baudrate) + { + case B9600: + imagesize = 0x07; + break; + case B19200: + imagesize = 0x08; + break; + case B38400: + imagesize = 0x09; + break; + default: + sprintf(szbuf, "设置串口摄像机参数时,配置参数错误!退出设置!"); + DebugLog(devparam[devidx].commid, szbuf, 'I'); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + return -1; + } + + if(lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt > 15*1000) + { + srdt.ms_dev[devidx].SerialCmdidx = -1; + sprintf(szbuf, "设置串口摄像机参数时,15秒未收到摄像机应答!退出设置!"); + DebugLog(devparam[devidx].commid, szbuf, 'I'); + return -1; + } + cmdidx = 0x03; + packetsize = 0xFFFF; + break; + + case 10001: /* 通知摄像机图片读取完成或存储(16H)*/ + case 10002: + cmdidx = 0x16; + if(10001 == cmdno) + packetsize = 1; + else + packetsize = 0; + imagesize = srdt.photographtime; /* 需要保存或删除的图片拍摄时间*/ + break; + + case 10003: /* 读取历史图片(15H)*/ + cmdidx = 0x15; + packetsize = (WORD)MAX_PHOTO_FRAME_LEN; + break; + + case 10005: /* 关闭功能*/ + //Gm_CtrlPtzCmd(1, P_MOVE_LEFT); + //sleep(2); + Gm_CtrlPtzCmd(channel, Cmd_Cancel); + usleep(100000); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + //sleep(20); + return 1; + case 10006: /* 自动扫描功能控制(1/0 打开/关闭该功能)*/ + Gm_CtrlPtzCmd(channel, P_Auto_Scan); + usleep(100000); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + return 1; + case 10007: /* 光圈缩小(1 有效)*/ + Gm_CtrlPtzCmd(channel, P_IRIS_CLOSE); + usleep(100000); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + return 1; + case 10008: /* 光圈放大(1 有效)*/ + Gm_CtrlPtzCmd(channel, P_IRIS_OPEN); + usleep(100000); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + return 1; + case 10009: /* 近距离聚焦(1 有效)*/ + Gm_CtrlPtzCmd(channel, P_FOCUS_NEAR); + usleep(100000); + Gm_CtrlPtzCmd(channel, Cmd_Cancel); + usleep(100000); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + return 1; + case 10010: /* 远距离聚焦(1 有效)*/ + Gm_CtrlPtzCmd(channel, P_FOCUS_FAR); + usleep(100000); + Gm_CtrlPtzCmd(channel, Cmd_Cancel); + usleep(100000); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + return 1; + case 10011: /* 远离物体(1 有效)*/ + Gm_CtrlPtzCmd(channel, P_ZOOM_WIDE); + usleep(100000); + Gm_CtrlPtzCmd(channel, Cmd_Cancel); + usleep(100000); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + return 1; + case 10012: /* 接近物体(1 有效)*/ + Gm_CtrlPtzCmd(channel, P_ZOOM_TELE); + usleep(100000); + Gm_CtrlPtzCmd(channel, Cmd_Cancel); + usleep(100000); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + return 1; + case 10013: /* 向下移动镜头(1 有效)*/ + Gm_CtrlPtzCmd(channel, P_MOVE_DOWN); + sleep(1); + Gm_CtrlPtzCmd(channel, Cmd_Cancel); + usleep(100000); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + return 1; + case 10014: /* 向上移动镜头(1 有效)*/ + Gm_CtrlPtzCmd(channel, P_MOVE_UP); + sleep(1); + Gm_CtrlPtzCmd(channel, Cmd_Cancel); + usleep(100000); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + return 1; + case 10015: /* 向左移动镜头(1 有效)*/ + Gm_CtrlPtzCmd(channel, P_MOVE_LEFT); + sleep(1); + Gm_CtrlPtzCmd(channel, Cmd_Cancel); + usleep(100000); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + return 1; + case 10016: /* 向右移动镜头(1 有效)*/ + Gm_CtrlPtzCmd(channel, P_MOVE_RIGHT); + sleep(1); + Gm_CtrlPtzCmd(channel, Cmd_Cancel); + usleep(100000); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + return 1; + case 10017: /* 调用预置点*/ + //srdt.presetno = 2; + Gm_CtrlPtzCmd(channel, MOVE_TO_PRESETNO+srdt.presetno); + sleep(2); + if(0 == srdt.IsSleep) + { + srdt.ms_dev[devidx].SerialCmdidx = 10017; + srdt.IsSleep++; + return 1; + } + //if(srdt.presetno > 1) + // srdt.presetno = 1; + // else + // srdt.presetno++; + //srdt.ms_dev[devidx].SerialCmdidx = -1; + //Gm_CtrlPtzCmd(channel, MOVE_TO_PRESETNO+srdt.presetno); + //usleep(1000); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + srdt.IsSleep = 0; + return 1; + case 10018: /* 设置预置点*/ + Gm_CtrlPtzCmd(channel, SET_PRESETNO+srdt.presetno); + usleep(100000); + srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo; + srdt.iLastGetPhotoNo = -1; + return 1; + default: + imagesize = 0xFF; + packetsize = (WORD)srdt.ms_dev[devidx].SerialCmdidx; + cmdidx = 0x11; +#if 0 + if(0 == srdt.IsSleep) + { + srdt.IsSleep++; + testComm(); + } +#endif + if(lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt > 35*1000) + { + srdt.ms_dev[devidx].SerialCmdidx = -1; + sprintf(szbuf, "读取第%d包图片数据35秒未收到!结束拍照!",packetsize); + DebugLog(devparam[devidx].commid, szbuf, 'I'); + return -1; + } + break; + } + MakeCameraPhotoCommand(devidx, cmdidx, imagesize, packetsize, imagequality, srdt.sendphototime); + //MakeCameraPhotoCommand(devidx, 2, imagesize, packetsize, imagequality); + srdt.curdevidx[devparam[devidx].commid] = devidx; + return 1; +} + +/********************************************************************************* + 生成 CameraPhoto命令 +**********************************************************************************/ +void MakeCameraPhotoCommand( int portno, BYTE cmdidx, int OneParam, WORD TwoParam, BYTE Threep, int phototime ) +{ + int i, icurtime; + u_char *sendbuf; + //char szbuf[128]; + + sendbuf = serialport[devparam[portno].commid].PollCmd; + + icurtime = phototime; + i = 0; + sendbuf[i++] = 0x00; /* 强制等待时间*/ + sendbuf[i++] = 0x00; /* 强制等待时间*/ + sendbuf[i++] = 0x68; /* 起始字符*/ + sendbuf[i++] = (BYTE)0x00; /* length */ + sendbuf[i++] = (BYTE)0x00; /* length */ + sendbuf[i++] = 0x68; /* 起始字符*/ + sendbuf[i++] = (BYTE)devparam[portno].devaddr;/* 传感器地址*/ + sendbuf[i++] = cmdidx; /* 命令字*/ + switch(cmdidx) + { + case 0x02: /* */ + sendbuf[i-2] = 0xFF; + break; + case 0x03: /*设置传感器通讯参数(03H)*/ + sendbuf[i++] = 0x00; /* 波特率*/ + sendbuf[i++] = 0x00; + sendbuf[i++] = 0x00; + sendbuf[i++] = (BYTE)OneParam; + sendbuf[i++] = 0x08; /* 数据位*/ + sendbuf[i++] = 0x00; /* 校验位*/ + sendbuf[i++] = 0x01; /* 停止位*/ + break; + case 0x010: /* 拍摄图片并指定大小分包(10H)*/ + sendbuf[i++] = OneParam; /* 图片大小(Resolution)*/ + sendbuf[i++] = HIBYTE(TwoParam);/*包大小(PackageSize)*/ + sendbuf[i++] = LOBYTE(TwoParam); + sendbuf[i++] = HIBYTE(HIWORD(icurtime+8*60*60));/* 请求拍摄图片时间(PhotoTime)*/ + sendbuf[i++] = LOBYTE(HIWORD(icurtime+8*60*60)); + sendbuf[i++] = HIBYTE(LOWORD(icurtime+8*60*60)); + sendbuf[i++] = LOBYTE(LOWORD(icurtime+8*60*60)); + sendbuf[i++] = Threep;/*图像质量(ImageQuality)*/ + sendbuf[i++] = srdt.presetno;//netportparam.CurPresetno[srdt.ms_dev[portno].CameraChannel-1];/*拍照预置点(PresetNo)*/ + break; + case 0x11: /* 获取指定包数据(11H)*/ + sendbuf[i++] = HIBYTE(TwoParam);/*图片包号:(PackageNo)*/ + sendbuf[i++] = LOBYTE(TwoParam); + break; + case 0x15: /* 读取历史图片(15H)*/ + sendbuf[i++] = HIBYTE(TwoParam);/*包大小(PackageSize)*/ + sendbuf[i++] = LOBYTE(TwoParam); + break; + case 0x16: /* 通知摄像机图片读取完成或存储(16H)*/ + sendbuf[i++] = HIBYTE(HIWORD(OneParam));/* 需要保存或删除的图片拍摄时间*/ + sendbuf[i++] = LOBYTE(HIWORD(OneParam)); + sendbuf[i++] = HIBYTE(LOWORD(OneParam)); + sendbuf[i++] = LOBYTE(LOWORD(OneParam)); + sendbuf[i++] = (BYTE)TwoParam; /* 是否需要保存*/ + break; + } + sendbuf[i] = CalLpc((u_char *)&sendbuf[6],i-6); + i+= 1; + sendbuf[i++] = 0x16; /* 信息尾*/ + sendbuf[3] = (BYTE)((i-10)>>8); + sendbuf[4] = (BYTE)(i-10); + serialport[devparam[portno].commid].cmdlen = i; + //return; +} + +// 准备发送云台指令 +int Gm_CtrlPtzCmd(u_char channel, DWORD ptzcmd) +{ + int i; + char szbuf[64]; + + srdt.PtzCmdType = ptzcmd; + // 查找装置序号 + for(i=0; i srdt.ms_dev[i].UseSerialidx+1) ||(MAX_SERIAL_PORT_NUM < srdt.ms_dev[i].UseSerialidx+1)) + { + sprintf(szbuf, "通道%d摄像机错误的使用了串口%d", channel, srdt.ms_dev[i].UseSerialidx+1); + LOGI("%s", szbuf); + return 1; + } + else + { +#endif + sprintf(szbuf, "摄像机通道%d 使用串口%d", channel, devparam[i].commid+1); + DebugLog(devparam[i].commid, szbuf, 'I'); + //} + srdt.usecameradevidx = i; + // 查找串口序号 + // 1.打开串口电源 + //Gm_OpenSensorsPower(); + // 2.打开串口通讯 + //Gm_OpenSerialPort(i); + + srdt.SendStopPtzCmdTimeCnt = -1; + //return 1; + return Gm_Camera_Timer(); + //return 1; +} + +// 发送转动摄像机云台命令定时器 +int Gm_Camera_Timer() +{ + char szbuf[128]; + + if(PELCO_D_PROTOCOL == devparam[srdt.usecameradevidx].ProtocolIdx) + { + switch(srdt.PtzCmdType) + { + case P_Auto_Scan: + srdt.PtzCmdType = D_Auto_Scan; + break; + case P_IRIS_CLOSE: + srdt.PtzCmdType = D_IRIS_CLOSE; + break; + case P_IRIS_OPEN: + srdt.PtzCmdType = D_IRIS_OPEN; + break; + case P_FOCUS_NEAR: + srdt.PtzCmdType = D_FOCUS_NEAR; + break; + case P_FOCUS_FAR: + srdt.PtzCmdType = D_FOCUS_FAR; + break; + case P_ZOOM_WIDE: + srdt.PtzCmdType = D_ZOOM_WIDE; + break; + case P_ZOOM_TELE: + srdt.PtzCmdType = D_ZOOM_TELE; + break; + case P_MOVE_DOWN: + srdt.PtzCmdType = D_MOVE_DOWN; + break; + case P_MOVE_UP: + srdt.PtzCmdType = D_MOVE_UP; + break; + case P_MOVE_LEFT: + srdt.PtzCmdType = D_MOVE_LEFT; + break; + case P_MOVE_RIGHT: + srdt.PtzCmdType = D_MOVE_RIGHT; + break; + } + } + if(srdt.SendStopPtzCmdTimeCnt == -1) + { + if(serialport[srdt.camerauseserial].cmdlen > 0) + return -1; + if(PELCO_D_PROTOCOL == devparam[srdt.usecameradevidx].ProtocolIdx) + Gm_SendPelco_DCommand(srdt.PtzCmdType); + else + Gm_SendPelco_pCommand(srdt.PtzCmdType); + + if((SET_PRESETNO == (srdt.PtzCmdType & 0xFFFF0000)) + || (MOVE_TO_PRESETNO == (srdt.PtzCmdType & 0xFFFF0000))) + { + //srdt.sampling &= 0xFD; + return 1; + } + srdt.PtzCmdType = Cmd_Cancel; + srdt.SendStopPtzCmdTimeCnt = 0; + } + return 1; +#if 0 + //if(srdt.SendStopPtzCmdTimeCnt > PTZ_MOVETIME*1000/TIMER_CNT) + { + if(serialport[srdt.camerauseserial].cmdlen > 0) + return -1; + if(PELCO_D_PROTOCOL == devparam[srdt.usecameradevidx].ProtocolIdx) + Gm_SendPelco_DCommand(srdt.PtzCmdType); + else + Gm_SendPelco_pCommand(srdt.PtzCmdType); + srdt.SendStopPtzCmdTimeCnt = -1; + //srdt.sampling &= 0xFD; + return 1; + } + //else + // srdt.SendStopPtzCmdTimeCnt ++; + //return -1; +#endif +} + +/******************************************************************************** +* 生成 PELCO_P 命令 * +*********************************************************************************/ +void Gm_SendPelco_pCommand( DWORD cmdtype) +{ + int len; + BYTE commandbuf[32]; + char buf[128]; + + len = 0; + commandbuf[len++] = (BYTE)0xA0; + commandbuf[len++] = (BYTE)devparam[srdt.usecameradevidx].devaddr; + commandbuf[len++] = (BYTE)(cmdtype>>24); + commandbuf[len++] = (BYTE)(cmdtype>>16); + commandbuf[len++] = (BYTE)(cmdtype>>8); + commandbuf[len++] = (BYTE)(cmdtype); + commandbuf[len++] = (BYTE)0xAF; + commandbuf[len] = (BYTE)Gm_Pelco_pXORCheck(commandbuf, len); + len++; + serialport[srdt.camerauseserial].cmdlen = len; + Gm_SetSerialPortParam(srdt.camerauseserial); + //unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x0ff,0x02,0x01,0x16}; + //len = GM_SerialComSend(sendbuf, sizeof(sendbuf), srdt.camerauseserial); + + len = GM_SerialComSend(commandbuf, len, srdt.camerauseserial); + if(len < 1) + { + DebugLog(srdt.camerauseserial, "发送Pelco_p命令失败", 'E'); + } + else + { + sprintf(buf, "发送串口%d 像机通道%d Pelco_P命令:", + srdt.camerauseserial+1, devparam[srdt.usecameradevidx].CameraChannel); + BytestreamLOG(srdt.camerauseserial, buf, commandbuf, len, 'D'); + } + ClearCmdFormPollCmdBuf(srdt.camerauseserial); +} + +BYTE Gm_Pelco_pXORCheck( BYTE *msg, int len ) +{ + int i; + BYTE checkvalue=0; + + if(len <= 0) + return checkvalue; + checkvalue = msg[0]; + for(i=1; i>24); + commandbuf[len++] = (BYTE)(cmdtype>>16); + commandbuf[len++] = (BYTE)(cmdtype>>8); + commandbuf[len++] = (BYTE)(cmdtype); + commandbuf[len] = (BYTE)Gm_Pelco_DCheck(commandbuf, len); +#endif + len++; + serialport[srdt.camerauseserial].cmdlen = len; + Gm_SetSerialPortParam(srdt.camerauseserial); + len = GM_SerialComSend(commandbuf, len, srdt.camerauseserial); + if(len < 1) + { + DebugLog(srdt.camerauseserial, "发送Pelco_D命令失败", 'E'); + } + else + { + sprintf(buf, "发送串口%d 像机通道%d Pelco_D命令:", + srdt.camerauseserial+1, devparam[srdt.usecameradevidx].CameraChannel); + BytestreamLOG(srdt.camerauseserial, buf, commandbuf, len, 'D'); + } + ClearCmdFormPollCmdBuf(srdt.camerauseserial); + //serialport[srdt.camerauseserial].ForceWaitCnt = 10; + //serialport[srdt.camerauseserial].ForceWaitFlag = 1; +} + +// 计算Pelco_D校验 +BYTE Gm_Pelco_DCheck( BYTE *msg, int len ) +{ + int i; + BYTE checkvalue=0; + + if(len <= 0) + return checkvalue; + checkvalue = 0; + for(i=1; i MAX_SERIAL_PORT_NUM)) + return -1; + if(get_msec()-srdt.ms_dev[devidx].FirstCmdTimeCnt < 3*1000) + { + return -1; + } + //if(SLANT_PROTOCOL == devparam[devidx].ProtocolIdx) + // return -1; + switch (cmdno) + { + case 0: /* 正常采集数据*/ + MakeShxyProtocolPollCommand(devidx, 0x09); + srdt.curdevidx[devparam[devidx].commid] = devidx; + return 1; + case 1: /* 测试读取地址*/ + MakeShxyProtocolPollCommand(devidx, 0x02); + srdt.curdevidx[devparam[devidx].commid] = devidx; + return 1; + default: + break; + } + return -1; +} + +/********************************************************************************* + 生成下发命令 +**********************************************************************************/ +void MakeShxyProtocolPollCommand(int portno, BYTE cmdidx) +{ + int i, length=0; + int newaddr = 9, baud = 9600, stopbit = 1, parity=0; + //char buf[128]; + u_char *sendbuf; + + sendbuf = serialport[devparam[portno].commid].PollCmd; + + /* 测试变量*/ + cmdidx =cmdidx; + + i = 0; + sendbuf[i++] = 0x00; // 强制等待时间 + sendbuf[i++] = 0x00; // + sendbuf[i++] = 0x68; // 起始字符 + sendbuf[i++] = (BYTE)0x00; // length + sendbuf[i++] = (BYTE)0x00; // length + sendbuf[i++] = 0x68; + sendbuf[i++] = (BYTE)devparam[portno].devaddr; // 传感器地址 + sendbuf[i++] = cmdidx; // 命令信息0x06 + switch (cmdidx) + { + case 1: /* 设置传感器新地址*/ + sendbuf[i++] = newaddr; + length = 1; + break; + case 2: /* 广播读地址*/ + sendbuf[6] = 0xFF; + break; + case 3: /* 设置串口参数*/ + sendbuf[i++] = (u_char)(baud >> 24); + sendbuf[i++] = (u_char)(baud >> 16); + sendbuf[i++] = (u_char)(baud >> 8); + sendbuf[i++] = (u_char)baud; + sendbuf[i++] = 8; + sendbuf[i++] = parity; + sendbuf[i++] = stopbit; + length = 7; + break; + default: + break; + } + sendbuf[i] = CalLpc((u_char *)&sendbuf[6],i-6); + i+= 1; + sendbuf[3] = length; + sendbuf[4] = length; + sendbuf[i++] = 0x16; // 信息尾 + serialport[devparam[portno].commid].cmdlen = i; +} + +unsigned char CalLpc(unsigned char *msg, int len) +{ + int i; + u_char retval = 0; + + for (i = 0 ; i < len; i++) + retval += msg[i]; + return retval; +} + +/*************************************************************** +* 读上海欣影传感器协议数据 * +***************************************************************/ +void ShxyProtocolRecvData(int devno, u_char *buf, int len)// 规约读数据处理 +{ + int i, ictime; + //WORD crc, check; + //SERIAL_DEV_DEF *pPortParam; + SIO_PARAM_SERIAL_DEF *pPortParam; + + if((devno<0) || (devno > MAX_SERIAL_DEV_NUM)) + { + return; + } + pPortParam = &serialport[devparam[devno].commid]; + + for(i=0; im_iRevStatus) + { + case 0: // 0x68 + pPortParam->m_iRecvLen = 0; + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(0x68 == buf[i]) + pPortParam->m_iRevStatus++; + else + pPortParam->m_iRevStatus = 18; + break; + case 1: // len1 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iRevStatus++; + break; + case 2: // len2 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(buf[i] == pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2]) + { + pPortParam->m_iRevStatus++; + pPortParam->m_iNeedRevLength = buf[i]+5; + } + else + pPortParam->m_iRevStatus = 18; + break; + case 3: // 0x68 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iNeedRevLength--; + if(0x68 == buf[i]) + pPortParam->m_iRevStatus++; + else + pPortParam->m_iRevStatus = 18; + break; + case 4: // 正确接收数据 + pPortParam->m_iNeedRevLength--; + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(pPortParam->m_iNeedRevLength > 0) + break; + if(buf[i] != 0x16) + { + pPortParam->m_iRevStatus=18; + break; + } + + if(CheckShxyProtocolLpcError(pPortParam->m_au8RecvBuf, pPortParam->m_iRecvLen) == TRUE) + { + ShxyProtocolDataProcess(devno); + pPortParam->m_iRevStatus = 0; + pPortParam->RevCmdFlag = 1; + } + else + { + pPortParam->m_iRevStatus = 0; + } + pPortParam->m_iRecvLen = 0; + break; + case 255:// 错误接收数据 + default: + if(buf[i] == 0x68) + { + pPortParam->m_iRevStatus = 1; + pPortParam->m_iRecvLen = 1; + pPortParam->m_au8RecvBuf[0] = buf[i]; + } + else if(buf[i] == 0x16) + { + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iRevStatus = 0; + pPortParam->m_iRecvLen = 0; + } + else + { + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(pPortParam->m_iRecvLen > 200) + { + pPortParam->m_iRecvLen = 0; + } + } + break; + } + } +} + +//******************************************************************************** +// 检查检验和是否正确 +//******************************************************************************** +int CheckShxyProtocolLpcError( u_char* msg, int len ) +{ + int bRetval = FALSE; + int iCheckLen; + + if(0x68 == msg[0]) + { + if ( msg[0] != msg[3] ) + return bRetval; + if ( msg[len-1] != 0x16 ) + return bRetval; + if ( msg[1] != msg[2] ) + return bRetval; + iCheckLen = msg[1]; + if ( CalLpc( &msg[4], iCheckLen+2 ) != msg[len-2] ) + return bRetval; + bRetval = TRUE; + } + return bRetval; +} + +/********************************************************************************* + 上海欣影传感器协议数据处理 +**********************************************************************************/ +void ShxyProtocolDataProcess( int devno) +{ + float fvalue, fcorvalue, *fvalua, frnb/*, fwind*/; + WORD uDevAddr; + BYTE cmdidx; + int i, j, aipnt, datanum; + SERIAL_DEV_DEF *pPortParam; + SIO_PARAM_SERIAL_DEF *curserial; + char szbuf[64]; + + pPortParam = &srdt.ms_dev[devno]; + curserial = &serialport[devparam[devno].commid]; + + //取出装置地址,开始处理地址+++ + if(0x02 == curserial->m_au8RecvBuf[5]) + { + devparam[devno].devaddr = curserial->m_au8RecvBuf[4]; + return; + } + + cmdidx = curserial->m_au8RecvBuf[5]; + aipnt = pPortParam->SameTypeDevIdx; + uDevAddr = curserial->m_au8RecvBuf[4]; + + fvalua = &fvalue; + memset(szbuf, 0, sizeof(szbuf)); + if(0x06 == cmdidx) + { + if(0x08 !=curserial->m_au8RecvBuf[1]) + return; + pPortParam->recvdatacnt++; + if(pPortParam->recvdatacnt < 2) + return; + // ++++++++++++++++++++++++++++ + //g_SelfTest.SensorsFault |= (0x800<m_au8RecvBuf[9]; + *((BYTE*)fvalua+1) = curserial->m_au8RecvBuf[8]; + *((BYTE*)fvalua+2) = curserial->m_au8RecvBuf[7]; + *((BYTE*)fvalua+3) = curserial->m_au8RecvBuf[6]; + if((fvalue < -59) ||(fvalue > 59)) + { + frnb = (GeneratingRandomNumber()%101-50)/1000.0; + pPortParam->aiValue[0].EuValue *= (1+frnb); + } + else + pPortParam->aiValue[0].EuValue = fvalue; + pPortParam->aiValue[0].AiState = Sample; + //slantpntmsg[aipnt][0].EuValue = fvalue*slantpntmsg[aipnt][0].AiParam.fFactor\ + // +slantpntmsg[aipnt][0].AiParam.EuValueDelta; + //slantpntmsg[aipnt][0].AiState = 1; + //if ((gDisSunRain & 0x20) == 0x20) + { + sprintf(szbuf, "倾角ID:%d slantangle X=%0.3f ", devparam[devno].devaddr, fvalue); + //DebugLog(devparam[devno].commid, szbuf, 'V'); + } + //XslantSec[aipnt][srdt.SectimesamplingCnt[0]] = (short)slantpntmsg[aipnt][0].EuValue; + //srdt.SectimesamplingCnt[0] += 1; + + *(BYTE*)fvalua = curserial->m_au8RecvBuf[13]; + *((BYTE*)fvalua+1) = curserial->m_au8RecvBuf[12]; + *((BYTE*)fvalua+2) = curserial->m_au8RecvBuf[11]; + *((BYTE*)fvalua+3) = curserial->m_au8RecvBuf[10]; + //if ((gDisSunRain & 0x20) == 0x20) + { + sprintf(szbuf, "%sY =%0.3f ", szbuf, fvalue); + DebugLog(devparam[devno].commid, szbuf, 'V'); + } + if((fvalue < -59) ||(fvalue > 59)) + { + frnb = (GeneratingRandomNumber()%101-50)/1000.0; + pPortParam->aiValue[1].EuValue *= (1+frnb); + //slantpntmsg[aipnt][1].EuValue *= (1+frnb); + } + else + pPortParam->aiValue[1].EuValue = fvalue; + pPortParam->aiValue[1].AiState = Sample; + /*slantpntmsg[aipnt][1].EuValue = fvalue*slantpntmsg[aipnt][1].AiParam.fFactor\ + +slantpntmsg[aipnt][1].AiParam.EuValueDelta; + slantpntmsg[aipnt][1].AiState = 1;*/ + //YslantSec[aipnt][srdt.SectimesamplingCnt[1]] = (short)slantpntmsg[aipnt][1].EuValue; + srdt.SectimesamplingCnt[1] += 1; + } + datanum = curserial->m_au8RecvBuf[6]; + if((0x08 != cmdidx) && (0x09 != cmdidx)) + return; + + for(i = 0, j=7; (im_au8RecvBuf[1]); i++, j+=5 ) + { + if(0x08 == cmdidx) + fvalue = (curserial->m_au8RecvBuf[j+1]<<24)+(curserial->m_au8RecvBuf[j+2]<<16) + +(curserial->m_au8RecvBuf[j+3]<<8)+curserial->m_au8RecvBuf[j+4]; + else + { + *(BYTE*)fvalua = curserial->m_au8RecvBuf[j+4]; + *((BYTE*)fvalua+1) = curserial->m_au8RecvBuf[j+3]; + *((BYTE*)fvalua+2) = curserial->m_au8RecvBuf[j+2]; + *((BYTE*)fvalua+3) = curserial->m_au8RecvBuf[j+1]; + } + switch(curserial->m_au8RecvBuf[j]) + { + case 1: /*温度*/ + if((fvalue < -40) ||(fvalue > 85)) + { + frnb = (GeneratingRandomNumber()%101-50)/1000.0; + pPortParam->aiValue[AirTempNo].EuValue *= (1+frnb); + weatherpntmsg[AirTempNo].EuValue *= (1+frnb); + //weatherpntmsg[AirTempNo].AiState = Sample; + } + else + { + pPortParam->aiValue[AirTempNo].EuValue = fvalue;/*pPortParam->aiValue[0].AiParam.fFactor + pPortParam->aiValue[0].AiParam.EuValueDelta;*/ + weatherpntmsg[AirTempNo].EuValue = fvalue;/*weatherpntmsg[AirTempNo].AiParam.fFactor + weatherpntmsg[AirTempNo].AiParam.EuValueDelta;*/ + } + pPortParam->aiValue[AirTempNo].AiState = Sample; + weatherpntmsg[AirTempNo].AiState = Sample; + //g_SelfTest.SensorsFault |= (0x01); + //if ((gDisSunRain & 0x80) == 0x80) + { + sprintf(szbuf, "ID:%d 温度:%0.3f ", devparam[devno].devaddr, fvalue); + //DebugLog(devparam[devno].commid, szbuf, 'V'); + } + break; + case 2: /*气压*/ + if((fvalue < 550) ||(fvalue > 1060)) + { + frnb = (GeneratingRandomNumber()%41-20)/10000.0; + pPortParam->aiValue[AtmosNo].EuValue *= (1+frnb); + weatherpntmsg[AtmosNo].EuValue *= (1+frnb); + } + else + { + pPortParam->aiValue[AtmosNo].EuValue = fvalue;/*pPortParam->aiValue[5].AiParam.fFactor + pPortParam->aiValue[5].AiParam.EuValueDelta;*/ + weatherpntmsg[AtmosNo].EuValue = fvalue;/*weatherpntmsg[AtmosNo].AiParam.fFactor + weatherpntmsg[AtmosNo].AiParam.EuValueDelta;*/ + } + pPortParam->aiValue[AtmosNo].AiState = Sample; + weatherpntmsg[AtmosNo].AiState = Sample; + //g_SelfTest.SensorsFault |= (0x10); + //if ((gDisSunRain & 0x80) == 0x80) + { + sprintf(szbuf, "气压:%0.3f ", fvalue); + DebugLog(devparam[devno].commid, szbuf, 'V'); + } + break; + case 3: /*湿度*/ + if((fvalue < 0) ||(fvalue > 100)) + { + frnb = (GeneratingRandomNumber()%41-20)/1000.0; + pPortParam->aiValue[HumidityNo].EuValue *= (1+frnb); + weatherpntmsg[HumidityNo].EuValue *= (1+frnb); + } + else + { + pPortParam->aiValue[HumidityNo].EuValue = fvalue;/*pPortParam->aiValue[1].AiParam.fFactor + pPortParam->aiValue[1].AiParam.EuValueDelta;*/ + weatherpntmsg[HumidityNo].EuValue = fvalue;/*weatherpntmsg[HumidityNo].AiParam.fFactor + weatherpntmsg[HumidityNo].AiParam.EuValueDelta;*/ + } + pPortParam->aiValue[HumidityNo].AiState = Sample; + weatherpntmsg[HumidityNo].AiState = Sample; + //g_SelfTest.SensorsFault |= (0x02); + //if ((gDisSunRain & 0x80) == 0x80) + { + sprintf(szbuf, "%s湿度:%0.3f ", szbuf, fvalue); + DebugLog(devparam[devno].commid, szbuf, 'V'); + } + break; + case 4: /*雨量*/ + break; + case 5: /*日照*/ + break; + case 6: /*风速*/ + if((fvalue < 0) ||(fvalue > 80)) + { + frnb = (GeneratingRandomNumber()%41-20)/1000.0; + pPortParam->aiValue[WindSpeedNo].EuValue *= (1+frnb); + weatherpntmsg[WindSpeedNo].EuValue *= (1+frnb); + } + else + { + pPortParam->aiValue[WindSpeedNo].EuValue = fvalue;/*pPortParam->aiValue[2].AiParam.fFactor + pPortParam->aiValue[2].AiParam.EuValueDelta;*/ + weatherpntmsg[WindSpeedNo].EuValue = fvalue;/*weatherpntmsg[WindSpeedNo].AiParam.fFactor + weatherpntmsg[WindSpeedNo].AiParam.EuValueDelta;*/ + } + pPortParam->aiValue[WindSpeedNo].AiState = Sample; + weatherpntmsg[WindSpeedNo].AiState = Sample; + //g_SelfTest.SensorsFault |= (0x04); + //if ((gDisSunRain & 0x10) == 0x10) + { + //fwind = fvalue/1000*0.95; + //if(fvalue/1000 > 25) + // fwind -= 1.2; + //sprintf(szbuf, "风速:%0.3f ", fwind); + sprintf(szbuf, "ID:%d 风速:%0.3f ", devparam[devno].devaddr, fvalue); + } + break; + case 7: /*风向*/ + if((fvalue/1000 < 0) ||(fvalue/1000 > 359.99)) + { + frnb = (GeneratingRandomNumber()%41-20)/1000.0; + pPortParam->aiValue[WindDirectionNo].EuValue *= (1+frnb); + weatherpntmsg[WindDirectionNo].EuValue *= (1+frnb); + } + else + { + pPortParam->aiValue[WindDirectionNo].EuValue = fvalue;/*pPortParam->aiValue[3].AiParam.fFactor + pPortParam->aiValue[3].AiParam.EuValueDelta;*/ + weatherpntmsg[WindDirectionNo].EuValue = fvalue;/*weatherpntmsg[WindDirectionNo].AiParam.fFactor + weatherpntmsg[WindDirectionNo].AiParam.EuValueDelta;*/ + } + pPortParam->aiValue[WindDirectionNo].AiState = Sample; + weatherpntmsg[WindDirectionNo].AiState = Sample; + //g_SelfTest.SensorsFault |= (0x08); + //if ((gDisSunRain & 0x10) == 0x10) + { + sprintf(szbuf, "%s 风向:%0.3f ", szbuf, fvalue); + DebugLog(devparam[devno].commid, szbuf, 'V'); + } + break; + case 8: /*拉力*/ + pPortParam->recvdatacnt++; + if(pPortParam->recvdatacnt < 2) + break; + + pPortParam->aiValue[0].EuValue = fvalue;/*pPortParam->aiValue[0].AiParam.fFactor\ + +pPortParam->aiValue[0].AiParam.EuValueDelta;*/ + //rallypntmsg[aipnt][0].EuValue = fvalue*rallypntmsg[aipnt][0].AiParam.fFactor\ + // +rallypntmsg[aipnt][0].AiParam.EuValueDelta; + pPortParam->aiValue[0].AiState = Sample; + //rallypntmsg[aipnt][0].AiState = 1; + sprintf(szbuf, "地址%d拉力:%0.3fKg ", devparam[devno].devaddr, fvalue); + DebugLog(devparam[devno].commid, szbuf, 'V'); + //} + break; + case 9: /*倾角传感器X轴倾角*/ + if((fvalue < -59) ||(fvalue > 59)) + { + frnb = (GeneratingRandomNumber()%101-50)/1000.0; + pPortParam->aiValue[0].EuValue *= (1+frnb); + //slantpntmsg[aipnt][0].EuValue *= (1+frnb); + } + else + { + pPortParam->aiValue[0].EuValue = fvalue;/*pPortParam->aiValue[0].AiParam.fFactor\ + +pPortParam->aiValue[0].AiParam.EuValueDelta;*/ + //slantpntmsg[aipnt][0].EuValue = fvalue*slantpntmsg[aipnt][0].AiParam.fFactor\ + //+slantpntmsg[aipnt][0].AiParam.EuValueDelta; + } + pPortParam->aiValue[0].AiState = Sample; + //slantpntmsg[aipnt][0].AiState = 1; + sprintf(szbuf, "倾角ID:%d slantangle X=%0.3f ", devparam[devno].devaddr, fvalue); + break; + case 10: /*倾角传感器Y轴倾角*/ + sprintf(szbuf, "%s Y =%0.3f ", szbuf, fvalue); + DebugLog(devparam[devno].commid, szbuf, 'V'); + + if((fvalue < -59) ||(fvalue > 59)) + { + frnb = (GeneratingRandomNumber()%101-50)/1000.0; + pPortParam->aiValue[1].EuValue *= (1+frnb); + } + else + { + pPortParam->aiValue[1].EuValue = fvalue;/*pPortParam->aiValue[1].AiParam.fFactor\ + +pPortParam->aiValue[1].AiParam.EuValueDelta;*/ + } + pPortParam->aiValue[1].AiState = Sample; + //slantpntmsg[aipnt][1].AiState = 1; + break; + + } + } +} + +void delete_old_files(const char *path, int days) +{ + struct stat file_stat; + struct tm *file_tm; + time_t now = time(NULL); + DIR *dir = opendir(path); + struct dirent *entry; + char szbuf[1024]; + char fullpath[256]; + + memset(szbuf, 0, sizeof(szbuf)); + if (!dir) + { + sprintf(szbuf, "delete_old_files opendir %s error ", path); + DebugLog(8, szbuf, 'E'); + return; + } + + while ((entry = readdir(dir))) + { + memset(szbuf, 0, sizeof(szbuf)); + if (entry->d_type == DT_REG) + { // 只处理普通文件 + snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name); + + if (stat(fullpath, &file_stat) == -1) + { + perror("stat"); + sprintf(szbuf, "stat"); + DebugLog(8, szbuf, 'E'); + continue; + } + + localtime_r(&(file_stat.st_mtime), file_tm); + //file_tm = localtime(&(file_stat.st_mtime)); + + if (difftime(now, mktime(file_tm)) > days * 24 * 60 * 60) + { + if (unlink(fullpath) == -1) + { // 删除文件 + perror("unlink"); + } + } + } + } + + closedir(dir); +} +/********************************************************************************* + 把16进制和10进制ASCII字符串转换成int整数 +*********************************************************************************/ +int ATOI(char *buf) +{ + int i, ilen, iRetVal; + + if(NULL == buf) + return 0; + ilen = strlen(buf); + if(ilen > 2) + { + if((buf[0]=='0') && ((buf[1]=='x') || (buf[1]=='X'))) + { + iRetVal = 0; + for(i=2; i MAX_SERIAL_DEV_NUM-1)) + return; + srdt.ms_dev[devidx].uOpenPowerFlag = CLOSEPOWER; +} + + +// 检查传感器电源是否应该关闭或打开 +void Gm_CheckSensorsPower(void) +{ + int i, j; + + for(i=0; i srdt.ms_dev[i].ProtocolIdx) ||(INVALID_PROTOCOL<=srdt.ms_dev[i].ProtocolIdx)) + continue; + if((PELCO_P_PROTOCOL == srdt.ms_dev[i].ProtocolIdx) ||(PELCO_D_PROTOCOL == srdt.ms_dev[i].ProtocolIdx) + ||( SERIALCAMERA_PROTOCOL == srdt.ms_dev[i].ProtocolIdx)) + continue; + // 需要传感器处于上电状态 + for(j=0; j rand()%(m-n+1)+n*/ + ictime = (int)time(NULL); + srand((DWORD)ictime); + randomdate = rand(); + return randomdate; +} + +/* 串口启动接口函数 开始*/ +void Collect_sensor_data() +{ +#if 0 + int i; + + for(i=0; i datano) || (datano > OpticalRadiationNo)) + return -1; + data->EuValue = weatherpntmsg[datano].EuValue; + data->AiState = weatherpntmsg[datano].AiState; + if((SampleFail == data->AiState) || (SamplingSuccess == data->AiState)) + { + weatherpntmsg[datano].AiState = Idle; + return 2; + } + return 1; +} + +int GetAirTempData(Data_DEF *airt) +{ + if(NULL == airt) + return -1; + airt->EuValue = weatherpntmsg[AirTempNo].EuValue; + airt->AiState = weatherpntmsg[AirTempNo].AiState; + if((SampleFail == airt->AiState) || (SamplingSuccess == airt->AiState)) + { + weatherpntmsg[AirTempNo].AiState = Idle; + return 2; + } + return 1; +} + +int GetHumidityData(Data_DEF *airt) +{ + if(NULL == airt) + return -1; + airt->EuValue = weatherpntmsg[HumidityNo].EuValue; + airt->AiState = weatherpntmsg[HumidityNo].AiState; + if((SampleFail == airt->AiState) || (SamplingSuccess == airt->AiState)) + { + weatherpntmsg[HumidityNo].AiState = Idle; + return 2; + } + return 1; +} + +int GetWindSpeedData(Data_DEF *airt) +{ + if(NULL == airt) + return -1; + airt->EuValue = weatherpntmsg[WindSpeedNo].EuValue; + airt->AiState = weatherpntmsg[WindSpeedNo].AiState; + if((SampleFail == airt->AiState) || (SamplingSuccess == airt->AiState)) + { + weatherpntmsg[WindSpeedNo].AiState = Idle; + return 2; + } + return 1; +} + +int GetWindDirectionData(Data_DEF *airt) +{ + if(NULL == airt) + return -1; + airt->EuValue = weatherpntmsg[WindDirectionNo].EuValue; + airt->AiState = weatherpntmsg[WindDirectionNo].AiState; + if((SampleFail == airt->AiState) || (SamplingSuccess == airt->AiState)) + { + weatherpntmsg[WindDirectionNo].AiState = Idle; + return 2; + } + return 1; +} + +int GetRainfallData(Data_DEF *airt) +{ + if(NULL == airt) + return -1; + airt->EuValue = weatherpntmsg[RainfallNo].EuValue; + airt->AiState = weatherpntmsg[RainfallNo].AiState; + if((SampleFail == airt->AiState) || (SamplingSuccess == airt->AiState)) + { + weatherpntmsg[RainfallNo].AiState = Idle; + return 2; + } + return 1; +} + +int GetAtmosData(Data_DEF *airt) +{ + if(NULL == airt) + return -1; + airt->EuValue = weatherpntmsg[AtmosNo].EuValue; + airt->AiState = weatherpntmsg[AtmosNo].AiState; + if((SampleFail == airt->AiState) || (SamplingSuccess == airt->AiState)) + { + weatherpntmsg[AtmosNo].AiState = Idle; + return 2; + } + return 1; +} + +int GetOpticalRadiationData(Data_DEF *airt) +{ + if(NULL == airt) + return -1; + airt->EuValue = weatherpntmsg[OpticalRadiationNo].EuValue; + airt->AiState = weatherpntmsg[OpticalRadiationNo].AiState; + if((SampleFail == airt->AiState) || (SamplingSuccess == airt->AiState)) + { + weatherpntmsg[OpticalRadiationNo].AiState = Idle; + return 2; + } + return 1; +} + +int GetPullValue(int devno, Data_DEF *data) +{ + if(NULL == data) + return -1; + if((0>devno)||(MAX_SERIAL_DEV_NUM < devno)) + return -1; + if(RALLY_PROTOCOL != devparam[devno].ProtocolIdx) + return -1; + data->EuValue = srdt.ms_dev[devno].aiValue[0].EuValue; + data->AiState = srdt.ms_dev[devno].aiValue[0].AiState; + if((SampleFail == data->AiState) || (SamplingSuccess == data->AiState)) + { + srdt.ms_dev[devno].aiValue[0].AiState = Idle; + return 2; + } + return 1; +} + +int GetAngleValue(int devno, Data_DEF *data, int Xy) +{ + if(NULL == data) + return -1; + if((0>devno)||(MAX_SERIAL_DEV_NUM < devno)) + return -1; + if(SLANT_PROTOCOL != devparam[devno].ProtocolIdx) + return -1; + if((0 > Xy) || (1 < Xy)) + return -1; + + data->EuValue = srdt.ms_dev[devno].aiValue[Xy].EuValue; + data->AiState = srdt.ms_dev[devno].aiValue[Xy].AiState; + if((SampleFail == data->AiState) || (SamplingSuccess == data->AiState)) + { + srdt.ms_dev[devno].aiValue[Xy].AiState = Idle; + return 2; + } + return 1; +} + +int GetImage(int devno, IMAGE_DEF *photo) +{ + if(NULL == photo) + return -1; + if((0>devno)||(MAX_SERIAL_DEV_NUM < devno)) + return -1; + if((PELCO_D_PROTOCOL != devparam[devno].ProtocolIdx) && (PELCO_P_PROTOCOL != devparam[devno].ProtocolIdx) &&(SERIALCAMERA_PROTOCOL != devparam[devno].ProtocolIdx)) + return -1; + photo->presetno = srdt.ms_dev[devno].image.presetno; + photo->phototime = srdt.ms_dev[devno].image.phototime; + memset(photo->photoname, 0, sizeof(photo->photoname)); + memmove(photo->photoname, srdt.ms_dev[devno].image.photoname, sizeof(photo->photoname)); + photo->imagelen = srdt.ms_dev[devno].image.imagelen; + photo->state = srdt.ms_dev[devno].image.state; + if((SampleFail == photo->state) || (SamplingSuccess == photo->state)) + { + srdt.ms_dev[devno].image.state = Idle; + return 2; + } + return 1; +} +/* 数据和图片采集数据返回函数 结束*/ \ No newline at end of file diff --git a/app/src/main/cpp/SensorsProtocol.h b/app/src/main/cpp/SensorsProtocol.h new file mode 100644 index 0000000..6472fe3 --- /dev/null +++ b/app/src/main/cpp/SensorsProtocol.h @@ -0,0 +1,467 @@ +// +// Created by hyz on 2024/6/5. +// + +#ifndef WEATHERCOMM_H +#define WEATHERCOMM_H + +#include +#include "GPIOControl.h" +#include "termios.h" + +#ifndef DWORD +typedef unsigned int DWORD; +#endif +#ifndef WORD +typedef unsigned short WORD; +#endif +#ifndef BYTE +typedef unsigned char BYTE; +#endif +#ifndef LONG +typedef long long LONG; +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#define LOBYTE(w) ((unsigned char)(w)) +#define HIBYTE(w) ((unsigned char)(((unsigned short)(w) >> 8) & 0xFF)) + +#define LOWORD(l) ((WORD)(l)) +#define HIWORD(l) ((WORD)((DWORD)(l) >> 16)) + +#define min(a, b) ((a) < (b) ? (a) : (b)) +#define MAX_STRING_LEN 32 +#define IOT_PARAM_WRITE 0xAE +#define IOT_PARAM_READ 0xAF + +#define MAX_SERIAL_DEV_NUM 25 /* 最大接串口传感器数量*/ +#define MAX_SERIAL_PORT_NUM 5 +#define MAX_DEV_VALUE_NUM 12 /* 一台装置最大的采样值数量*/ + +#define WEATHER_PROTOCOL 1 /* 温湿度协议序号*/ +#define WIND_PROTOCOL 2 /* 风速风向协议序号*/ +#define SLANT_PROTOCOL 3 /* 倾斜角协议序号*/ +#define RALLY_PROTOCOL 4 /* 拉力协议序号*/ +#define PELCO_P_PROTOCOL 5 /* 摄像机Pelco_P协议序号*/ +#define PELCO_D_PROTOCOL 6 /* 摄像机Pelco_D协议序号*/ +#define SERIALCAMERA_PROTOCOL 8 /* 串口摄像机协议序号*/ +#define RESERVE2_PROTOCOL 17 /* 备用2协议序号*/ +#define RESERVE4_PROTOCOL 19 /* 备用4协议序号*/ +#define RESERVE5_PROTOCOL 20 /* 备用5协议序号*/ +#define INVALID_PROTOCOL 21 /* 无效协议序号*/ + +#define AirTempNo 0 /* 空气温度数据存储序号*/ +#define HumidityNo 1 /* 相对湿度数据存储序号*/ +#define WindSpeedNo 2 /* 风速数据存储序号*/ +#define WindDirectionNo 3 /* 风向数据存储序号*/ +#define RainfallNo 4 /* 雨量数据存储序号*/ +#define AtmosNo 5 /* 大气压数据存储序号*/ +#define OpticalRadiationNo 6 /* 日照(光辐射)数据存储序号*/ + +#define Idle 0 /* 传感器处于空闲状态,未启动采样*/ +#define Sample 1 /* 正在采样过程中*/ +#define SamplingSuccess 2 /* 采样结束,正常读取到数据*/ +#define StartSample 3 /* 启动采样*/ +#define SampleFail -1 /* 采样失败,未采集到数据,传感器故障或未接*/ +#define PHOTO_SAVE_SUCC 5 /* 图片保存成功*/ + +#define WEATHER_DATA_NUM 8 /* 气象数据最大数量(一般最多是6要素)*/ +#define RALLY_DATA_NUM 2 /* 拉力数据最大数量(一般是1个)*/ +#define SLANTANGLE_DATA_NUM 3 /* 倾角数据最大数量(一般只有X轴和Y轴值)*/ + +#define PTZ_MOVETIME 1 // 云台移动等待时间为1秒 +#define MAX_CHANNEL_NUM 2 /* 视频通道最大通道*/ +#define MAX_PHOTO_FRAME_LEN 1024 /* 图片数据一包最大长度*/ +#define MAX_PHOTO_PACKET_NUM 1024 /* 图片最大包数(图片最大定为1MB)*/ + +#define RECVDATA_MAXLENTH 2048 /* 接收数据缓冲区最大值*/ +#define TIMER_CNT 50 // Poll命令定时器时间 5 ms +#define SENDDATA_MAXLENTH RECVDATA_MAXLENTH /* 正常发送数据缓冲区最大值*/ + +// 摄像机控制命令宏定义 +#define Cmd_Cancel 0x00000000 // 关闭功能 +#define SET_PRESETNO 0x00030000 // 设置预置点 +#define MOVE_TO_PRESETNO 0x00070000 // 调用预置点 + +/* 摄像机PELCO-P控制命令宏定义*/ +#define P_Auto_Scan 0x20000000 /* 自动扫描功能控制(1/0 打开/关闭该功能)*/ +#define P_IRIS_CLOSE 0x08000000 /* 光圈缩小(1 有效)*/ +#define P_IRIS_OPEN 0x04000000 /* 光圈放大(1 有效)*/ +#define P_FOCUS_NEAR 0x02000000 /* 近距离聚焦(1 有效)*/ +#define P_FOCUS_FAR 0x01000000 /* 远距离聚焦(1 有效)*/ +#define P_ZOOM_WIDE 0x00400000 /* 远离物体(1 有效)*/ +#define P_ZOOM_TELE 0x00200000 /* 接近物体(1 有效)*/ +#define P_MOVE_DOWN 0x0010001f /* 向下移动镜头(1 有效)*/ +#define P_MOVE_UP 0x0008001f /* 向上移动镜头(1 有效)*/ +#define P_MOVE_LEFT 0x00041f00 /* 向左移动镜头(1 有效)*/ +#define P_MOVE_RIGHT 0x00021f00 /* 向右移动镜头(1 有效)*/ + +// 摄像机PELCO-D控制命令宏定义 +#define D_Auto_Scan 0x10000000 /* 自动扫描功能控制(1/0 打开/关闭该功能)*/ +#define D_IRIS_CLOSE 0x04000000 /* 光圈缩小(1 有效)*/ +#define D_IRIS_OPEN 0x02000000 /* 光圈放大(1 有效)*/ +#define D_FOCUS_NEAR 0x01000000 /* 近距离聚焦(1 有效)*/ +#define D_FOCUS_FAR 0x00800000 /* 远距离聚焦(1 有效)*/ +#define D_ZOOM_WIDE 0x00400000 /* 远离物体(1 有效)*/ +#define D_ZOOM_TELE 0x00200000 /* 接近物体(1 有效)*/ +#define D_MOVE_DOWN 0x0010002d /* 向下移动镜头(1 有效)*/ +#define D_MOVE_UP 0x0008002d /* 向上移动镜头(1 有效)*/ +#define D_MOVE_LEFT 0x00042d00 /* 向左移动镜头(1 有效)*/ +#define D_MOVE_RIGHT 0x00022d00 /* 向右移动镜头(1 有效)*/ + +/* 摄像机下发命令宏定义*/ +#define Take_Photo 0 /* 拍照*/ +#define Stop_Baud 10000 /* 设置球机波特率*/ +#define Stop_Cmd 10005 /* 取消或停止指令*/ +#define Auto_Scan 10006 /* 自动扫描功能控制(1/0 打开/关闭该功能)*/ +#define IRIS_CLOSE 10007 /* 光圈缩小(1 有效)*/ +#define IRIS_OPEN 10008 /* 光圈放大(1 有效)*/ +#define FOCUS_NEAR 10009 /* 近距离聚焦(1 有效)*/ +#define FOCUS_FAR 10010 /* 远距离聚焦(1 有效)*/ +#define ZOOM_WIDE 10011 /* 远离物体(1 有效)*/ +#define ZOOM_TELE 10012 /* 接近物体(1 有效)*/ +#define MOVE_DOWN 10013 /* 向下移动镜头(1 有效)*/ +#define MOVE_UP 10014 /* 向上移动镜头(1 有效)*/ +#define MOVE_LEFT 10015 /* 向左移动镜头(1 有效)*/ +#define MOVE_RIGHT 10016 /* 向右移动镜头(1 有效)*/ +#define MOVE_PRESETNO 10017 // 调用预置点 +#define SAVE_PRESETNO 10018 // 设置预置点 +#define SPEED_DOME_CAMERA 0 /* 球机摄像机*/ +#define SERIAL_CAMERA 2 /* 串口摄像机a*/ + +#define COLLECT_DATA 1 /* 调试使用*/ + +#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "serial_port_comm", fmt, ##args) /* 红色*/ +#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, "Sensors_Protocol", fmt, ##args) /* 草绿色*/ +#define LOGV(fmt, args...) __android_log_print(ANDROID_LOG_VERBOSE, "serial_port_comm", fmt, ##args)/* 白色*/ +#define LOGW(fmt, args...) __android_log_print(ANDROID_LOG_WARN, "Sensors_Protocol", fmt, ##args) /* 黄色*/ +#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, "Sensors_Protocol", fmt, ##args) /* 蓝色*/ +#define HexCharToInt( c ) (((c) >= '0') && ((c) <= '9') ? (c) - '0' : ((c) >= 'a') && ((c) <= 'f') ? (c) - 'a' + 10 :((c) >= 'A') && ((c) <= 'F') ? (c) - 'A' + 10 : 0 ) + +typedef struct +{ + int cmd; + int value; + int result; + LONG value2; + char str[MAX_STRING_LEN]; +}IOT_PARAM; + +//SDS包类型结构 +typedef struct +{ + BYTE PortIdx; // 信息类型 + WORD MsgType; // 信息类型 + int MsgLen; // 信息长度 + u_char MsgData[RECVDATA_MAXLENTH]; +} RTUMSG; + +typedef struct +{ + float fFactor; // 数据系数 + float EuValueDelta; // 数据工程值偏移 +} AI_PARAM; + +typedef struct +{ + AI_PARAM AiParam; // 数据点配置参数 + int AiState; // 数据标识(-1:采样失败;0:没有采样;1:正在采样;2:采样结束;3:启动采样;) + float EuValue; // 数据工程值 +} AI_DEF; + +typedef struct +{ + BYTE AiState; // 数据标识(-1:采样失败;0:没有采样;1:正在采样;2:采样结束;3:启动采样;) + float EuValue; // 数据工程值 +} Data_DEF; + +typedef struct +{ + int imagelen; // 整个图片大小 + int phototime; // 拍照时间 + u_char presetno; // 拍照预置点 + char photoname[512]; // 图片存储名称和路径 + int state;// 标识(-1:拍照失败;0:没有拍照;1:正在取图;2:拍照成功;3:启动拍照;) +} IMAGE_DEF; + +typedef struct +{ + int imagelen; // 整个图片大小 + int imagenum; // 整个图片的总包数 + int phototime; // 拍照时间 + u_char presetno; // 拍照预置点 + char photoname[512]; // 图片存储名称和路径 + u_char buf[MAX_PHOTO_PACKET_NUM][MAX_PHOTO_FRAME_LEN]; // 图片数据缓存 + int ilen[MAX_PHOTO_PACKET_NUM]; // 相对应的每包图片数据的长度 + int state;// 标识(-1:拍照失败;0:没有拍照;1:正在取图;2:拍照成功;3:启动拍照;) +} PHOTO_DEF; + +// 上层调用采集传感器参数 +typedef struct +{ + unsigned int baudrate; /* 波特率*/ + int databit; /* 数据位*/ + float stopbit; /* 停止位*/ + char parity; /* 校验位*/ + char pathname[64]; /* 串口文件名及路径*/ + //int commNo; /* 约定的串口序号,例如我们PC机上显示的COM1。。。*/ + u_char SensorsType; /* 传感器类型索引,大于 0*/ + int devaddr; /* 装置(传感器)使用的地址*/ + u_char IsNoInsta; /* 装置没有安装或者已经坏了(1:正常, 0:无效,坏了或没有安装)*/ + u_char CameraChannel; /* 像机的通道号*/ + u_char Phase; /* 传感器所安装相别,指拉力和倾角11表示A1....*/ +} SENSOR_PARAM; + +// 需要配置的串口装置参数 +typedef struct +{ + unsigned int baudrate; /* 波特率*/ + int databit; /* 数据位*/ + int stopbit; /* 停止位*/ + char parity; /* 校验位*/ + char pathname[64]; /* 串口文件名及路径*/ + int commid; /* 串口序号 注意:从0开始*/ + u_char ProtocolIdx; /* 规约索引,大于 0*/ + int devaddr; /* 装置使用的地址*/ + u_char IsNoInsta; /* 装置没有安装或者已经坏了(1:正常, 0:无效,坏了或没有安装)*/ + u_char CameraChannel; /* 像机的通道号*/ + u_char Phase; /* 传感器所安装相别,指拉力和倾角11表示A1....*/ +} SERIAL_PARAM; + +typedef struct +{ + int m_iRevStatus; /* */ + int m_iRecvLen; /* */ + int m_iNeedRevLength; /* */ + int iRecvTime; /* */ + u_char m_au8RecvBuf[RECVDATA_MAXLENTH];/* */ + int fd; /* 串口打开的文件句柄*/ + u_char PollCmd[SENDDATA_MAXLENTH]; + int cmdlen; // 发送缓冲区命令长度 + //******************** Poll Cmd **************************** + u_char Retry; /* 重试命令次数 */ + u_char RetryCnt; /* 重试命令计数*/ + LONG RetryTime; /* 重试命令时间 */ + LONG RetryTimeCnt; /* 重试命令时间计数*/ + LONG WaitTime; /* 命令间隔时间 */ + LONG WaitTimeCnt; /* 命令间隔时间计数*/ + u_char ForceWaitFlag; /* 强制等待标志*/ + u_short ForceWaitCnt; /* 强制等待计数*/ + u_char ReSendCmdFlag; /* 重发命令标志 */ + u_char SendCmdFlag; /* 命令发送标志 */ + u_char RevCmdFlag; /* 命令正常接收标志*/ + //********************************************************** + LONG lsendtime; /* 命令发送绝对时间计时(毫秒)*/ +} SIO_PARAM_SERIAL_DEF; + +//串口相关装置所有参数集中定义 +typedef struct +{ + //******************** 端口基本信息 ************************ + u_char IsNeedSerial; /* 是否需要使用串口通讯*/ + int CmdWaitTime; /* 没有使用*/ + u_char UseSerialidx; /* 使用的串口序号*/ + int SerialCmdidx; /* 正在使用的串口发送命令的命令序号(-1:表示没有命令发送) + 摄像机使用命令序号存储*/ + int enrecvtime; /* 发送加密命令后接收到应答计时*/ + LONG FirstCmdTimeCnt; /* 串口读取数据起始时间*/ + u_char nextcmd; /* 第二次发送读取气象雨量命令 */ + u_char SameTypeDevIdx; /* 相同类型装置顺序排列序号(从0开始)*/ + u_char uOpenPowerFlag; /* 传感器上电标志(0:不需要打开; 1:需要打开)*/ + int recvdatacnt; /* 接收到有效数据*/ + PHOTO_DEF image; /* 临时存储图片数据*/ + AI_DEF aiValue[MAX_DEV_VALUE_NUM]; /* 传感器采样值*/ +} SERIAL_DEV_DEF; + +//串口相关装置所有参数集中定义 +typedef struct +{ + u_char clcyesampling; /* 正在进行采样(0:没有进行采样;1:正在进行采样;)*/ + u_char camerauseserial; /* 摄像机使用那个串口*/ + DWORD PtzCmdType; /* 云台指令类型*/ + int usecameradevidx; /* 有像机指令需要执行*/ + /* 执行指令的装置序号(-1:表示没有需要执行的指令;)*/ + int SendStopPtzCmdTimeCnt; /* 发送云台停止指令*/ + u_char serialstatus[MAX_SERIAL_PORT_NUM]; /* 串口是否可以使用状态分别对应串口1、2、3*/ + SERIAL_DEV_DEF ms_dev[MAX_SERIAL_DEV_NUM]; /* 装置所接传感器数量*/ + int UseingSerialdev[MAX_SERIAL_PORT_NUM]; /* 正在使用串口通讯的装置序号(-1,表示串口空闲)*/ + int curdevidx[MAX_SERIAL_PORT_NUM]; /* 当前正在通讯的装置序号(-1表示没有装置需要通讯)*/ + u_char IsReadWireTem; /* 是否在开始读取测温数据(0:表示没有;1:是)*/ + //int proruntime; /* 程序运行时间*/ + int IsSleep; /* 是否使程序休眠(1:不休眠;2:休眠)*/ + int tempsamplingstartime; /* 测温启动距离采样启动时间间隔*/ + int tempsamplingsucctime; /* 测温启动距离采样成功时间间隔*/ + int samplingtimeSec; /* 高速采样数据秒级时间控制*/ + int SectimesamplingCnt[3]; /* 高速采样数据秒级采样数*/ + int SunshineSensorsFault; /* 控制日照传感器故障发送*/ + int TempSensorsFault; /* 控制测温传感器故障发送*/ + int FirstSensorsFault; /* 第一次检测传感器故障发送*/ + int SensorsIsUse; /* 传感器是否启用与自检位置匹配*/ + int sequsampling; /* 顺序采样控制序号-1:无采样;其他对应相应装置序号*/ + + int imagepacketnum; /* 串口摄像机拍照图片总包数*/ + int historyimagenum[MAX_CHANNEL_NUM]; /* 球机保存的历史图片数量*/ +#if 1 + //int sendflag; /* 临时上送泄露电流值标志*/ + int sendphototime; /* 临时上送图片数据统计*/ + int sendphotocmdcnt; /* 一次拍照过程中发送拍照指令计数*/ + int photographtime; /* 图片拍摄的时间*/ + int iLastGetPhotoNo; /* 设置串口摄像机参数时暂存拍照命令序号*/ + u_char bImageSize; /* 用于临时存储接收上层命令的图片大小*/ + u_char presetno; /* 用于临时存储接收上层命令的预置点*/ + char filedir[512]; /* 用于摄像机拍照之后暂时存放的路径*/ +#endif + u_char errorPhotoNoCnt; /* 串口摄像机拍照时回应错误包号计数(如:召第6包回应第3包)*/ + u_char RephotographCnt; /* 串口摄像机重拍计数(只在读照片数据应答出错时才重拍)*/ +} SRDT_DEF; + +static void PortDataProcess( void ); +static LONG get_msec(); +int serial_port_comm(); +static int weather_comm(SERIAL_PARAM weatherport); + +static void setRS485Enable(bool z); +static void set485WriteMode(); +static void set485ReadMode(); +static void set12VEnable(bool z); +static void setCam3V3Enable(bool enabled); + +// 串口相关的所有函数定义 +/* 打开串口电源*/ +void Gm_OpenSerialPower(); + +// 打开传感器电源 +void Gm_OpenSensorsPower(); +// 关闭传感器电源 +void Gm_CloseSensorsPower(int port); + +// 打开串口通讯 +void Gm_OpenSerialPort(int devidx); + +// 关闭串口通讯 +void Gm_CloseSerialPort(); +void DebugLog(int commid, char *szbuf, char flag); +int SaveLogTofile(int commid, char *szbuf); +// 功能说明:串口发送数据 返回实际发送的字节数 +int GM_SerialComSend(const unsigned char * cSendBuf, LONG nSendLen, int commid); +void Gm_InitSerialComm(SENSOR_PARAM *sensorParam, char *filedir); +// 启动串口通讯 +void GM_StartSerialComm(); +// 启动使用串口拍照 +void GM_StartSerialCameraPhoto(BYTE channel, int cmdidx); +void delete_old_files(const char *path, int days); + +// 串口轮询通讯定时器 +int GM_SerialTimer(); +//轮询所有串口和传感器是否需要生成下发命令 +void Gm_FindAllSensorsCommand(); +//检查所有传感器是否采集完毕,采集完毕的关闭传感器电源 +void GM_IsCloseSensors(); +//检查所有串口是否有数据接收,有则启动接收 +void GM_AllSerialComRecv(); +//判断是否需要关闭定时器 +int GM_CloseTimer(); +void testComm(); +void Gm_InitSerialComm_Test(); +// 串口接收数据处理 +void SerialDataProcess(int devidx, u_char *buf, int len); + +void CameraRecvData(int commid, u_char *buf, int len); + +// 串口摄像机数据处理 +void CameraPhotoPortDataProcess( int port); + +// 发送命令 +void SendCmdFormPollCmdBuf( int port ); + +// 清除发送命令的所有标识 +void ClearCmdAllFlag(int commid); + +// 下发串口拍照指令控制 +int FindNextCameraPhotoCommand(int devidx); +// 生成 CameraPhoto命令 +void MakeCameraPhotoCommand( int portno, BYTE cmdidx, int OneParam, WORD TwoParam, BYTE Threep, int phototime); + +// 清除命令缓冲区 +void ClearCmdFormPollCmdBuf(int port); + +// 准备发送云台指令 +int Gm_CtrlPtzCmd(u_char channel, DWORD ptzcmd); + +// 发送转动摄像机云台命令定时器 +int Gm_Camera_Timer(); + +// 生成 PELCO_P 命令 * +void Gm_SendPelco_pCommand( DWORD cmdtype); + +// 计算Pelco_p校验 +BYTE Gm_Pelco_pXORCheck( BYTE *msg, int len ); +// 生成 PELCO_D 命令 * +void Gm_SendPelco_DCommand( DWORD cmdtype); + +// 计算Pelco_D校验 +BYTE Gm_Pelco_DCheck( BYTE *msg, int len ); +// 查询传感器电源状态 +char Gm_GetSensorsPowerState(int port); + +// 通过传感器使用的航空头查找传感器使用的串口序号 +void FindDevUseSerialCommNo(); + +// 寻找并生成下一条倾角命令 +int FindNextShxyProtocolCommand( int devidx ); +// 倾角命令校验码计算 +unsigned char CalLpc(unsigned char *msg, int len); +// 读上海欣影传感器协议数据 +void ShxyProtocolRecvData(int commid, u_char *buf, int len); +// 检查检验和是否正确 +int CheckShxyProtocolLpcError( u_char* msg, int len ); + +// 把16进制和10进制ASCII字符串转换成int整数 +int ATOI(char *buf); + +//生成倾角命令 +void MakeShxyProtocolPollCommand(int portno, BYTE cmdidx); +// 上海欣影传感器协议数据处理 +void ShxyProtocolDataProcess( int commid); +// 控制关闭传感器电源 +//void Gm_CtrlCloseSensorsPower(int devidx); +// 检查传感器电源是否应该关闭或打开 +//void Gm_CheckSensorsPower(void); +int SaveImageDataTofile(int devno); +void Collect_sensor_data(); + +void CameraPhotoCmd(int phototime, u_char channel, int cmdidx, u_char bImageSize, u_char presetno); + + +/* 数据和图片采集数据返回函数 开始*/ +int GetWeatherData(Data_DEF *data, int datano); + +int GetAirTempData(Data_DEF *airt); + +int GetHumidityData(Data_DEF *airt); + +int GetWindSpeedData(Data_DEF *airt); + +int GetWindDirectionData(Data_DEF *airt); + +int GetRainfallData(Data_DEF *airt); + +int GetAtmosData(Data_DEF *airt); + +int GetOpticalRadiationData(Data_DEF *airt); + +int GetPullValue(int devno, Data_DEF *data); + +int GetAngleValue(int devno, Data_DEF *data, int Xy); + +int GetImage(int devno, IMAGE_DEF *photo); +/* 数据和图片采集数据返回函数 结束*/ +// 生成一个随机整数 +int GeneratingRandomNumber(); + +#endif //WEATHERCOMM_H diff --git a/app/src/main/cpp/SerialPort.cpp b/app/src/main/cpp/SerialPort.cpp new file mode 100644 index 0000000..e035c8d --- /dev/null +++ b/app/src/main/cpp/SerialPort.cpp @@ -0,0 +1,142 @@ +/* + * Copyright 2009-2011 Cedric Priscal + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "SerialPort.h" + +#include "android/log.h" +static const char *TAG="serial_port"; +#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##args) +#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args) +#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args) + +static speed_t getBaudrate(int baudrate) +{ + switch(baudrate) { + case 0: return B0; + case 50: return B50; + case 75: return B75; + case 110: return B110; + case 134: return B134; + case 150: return B150; + case 200: return B200; + case 300: return B300; + case 600: return B600; + case 1200: return B1200; + case 1800: return B1800; + case 2400: return B2400; + case 4800: return B4800; + case 9600: return B9600; + case 19200: return B19200; + case 38400: return B38400; + case 57600: return B57600; + case 115200: return B115200; + case 230400: return B230400; + case 460800: return B460800; + case 500000: return B500000; + case 576000: return B576000; + case 921600: return B921600; + case 1000000: return B1000000; + case 1152000: return B1152000; + case 1500000: return B1500000; + case 2000000: return B2000000; + case 2500000: return B2500000; + case 3000000: return B3000000; + case 3500000: return B3500000; + case 4000000: return B4000000; + default: return -1; + } +} + +/* + * Class: android_serialport_SerialPort + * Method: open + * Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor; + */ +bool SerialPort::Open(std::string path, int baudrate, int flags) +{ + speed_t speed; + + /* Check arguments */ + { + speed = getBaudrate(baudrate); + if (speed == -1) { + /* TODO: throw an exception */ + LOGE("Invalid baudrate"); + return false; + } + } + + /* Opening device */ + { + + m_fd = open(path.c_str(), O_RDWR | flags); + LOGD("open() m_fd = %d", m_fd); + if (m_fd == -1) + { + /* Throw an exception */ + LOGE("Cannot open port"); + /* TODO: throw an exception */ + return false; + } + } + + /* Configure device */ + { + struct termios cfg; + LOGD("Configuring serial port"); + if (tcgetattr(m_fd, &cfg)) + { + LOGE("tcgetattr() failed"); + close(m_fd); + /* TODO: throw an exception */ + return false; + } + + cfmakeraw(&cfg); + cfsetispeed(&cfg, speed); + cfsetospeed(&cfg, speed); + + if (tcsetattr(m_fd, TCSANOW, &cfg)) + { + LOGE("tcsetattr() failed"); + close(m_fd); + /* TODO: throw an exception */ + return false; + } + } + + return true; +} + +/* + * Class: cedric_serial_SerialPort + * Method: close + * Signature: ()V + */ +bool SerialPort::Close() +{ + LOGD("close(m_fd = %d)", m_fd); + close(m_fd); +} + diff --git a/app/src/main/cpp/SerialPort.h b/app/src/main/cpp/SerialPort.h new file mode 100644 index 0000000..28f603a --- /dev/null +++ b/app/src/main/cpp/SerialPort.h @@ -0,0 +1,18 @@ +#ifndef __SERIALPORT_H__ +#define __SERIALPORT_H__ + +#include + +class SerialPort +{ +public: + + bool Open(std::string path, int, int); + + bool Close(); + +protected: + int m_fd; +}; + +#endif // __SERIALPORT_H__ diff --git a/app/src/main/cpp/SpiLib.cpp b/app/src/main/cpp/SpiLib.cpp new file mode 100644 index 0000000..1934b92 --- /dev/null +++ b/app/src/main/cpp/SpiLib.cpp @@ -0,0 +1,1290 @@ +#include "SpiLib.h" + +//typedef unsigned char u8; + +#define RE_SUC 0x01 +#define RE_ERROR 0x00 + + + +int SpiLIb::spi_transfer(int fd, unsigned char *txbuf, unsigned char *rxbuf, int bytes) +{ + struct spi_ioc_transfer xfer[2]; + int status; + + memset(xfer, 0, sizeof(xfer)); + + xfer[0].tx_buf = (__u64)txbuf; + xfer[0].rx_buf = (__u64)rxbuf; + xfer[0].len = bytes; + + status = ioctl(fd, SPI_IOC_MESSAGE(1), xfer); + if (status < 0) + { + perror("SPI_IOC_MESSAGE"); + return -1; + } + + return status; + +} + +void SpiLIb::spi_master_init(const char *name, int fd) +{ + __u8 mode = 3; + __u8 lsb, bits; + //__u32 speed = 30000000; + __u32 speed = 2000000; + //__u32 speed = 2000000; + //__u32 speed = 33000000; + + // SPI_IOC_WR_MODE + + ioctl(fd, SPI_IOC_WR_MODE, &mode); + ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); + + if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0) + { + perror("SPI rd_mode"); + return; + } + + if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) + { + perror("SPI rd_lsb_fist"); + return; + } + + if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) + { + perror("SPI rd bits_per_word"); + return; + } + + if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) + { + perror("SPI rd max_speed_hz"); + return; + } + + __android_log_print(ANDROID_LOG_INFO, "SPi", "%s: spi mode %d, %d bits %sper word, %d Hz max\n", name, mode, bits, lsb ? "(lsb first) " : "", speed); + //printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n", + // name, mode, bits, lsb ? "(lsb first) " : "", speed); +} + +unsigned char SpiLIb::get_crc7(const unsigned char *buff, int len) +{ + unsigned char crc7_accum = 0; + int i; + + for (i=0; i < len; i++) { + crc7_accum = + crc7_table[(crc7_accum << 1) ^ buff[i]]; + } + return crc7_accum; +} + +int SpiLIb::delay(int x) +{ + // while (--x); + // std::this_thread::sleep_for(std::chrono::milliseconds(50)); + usleep(50000); + return 0; +} + + +void SpiLIb::SendCmdHeader(int fd,u8 *cmd, u8 *rxbuf) +{ + int i=0; + int retval; + +#if defined (CONFIG_ATMEL_SPI_DEBUG) + printf("tx %1d bytes: ", CMD_HEAD_SIZE); + for (i = 0; i < CMD_HEAD_SIZE; i++) + { + printf(" %02x", cmd[i]); + } + printf("\n"); +#endif + + /* send five command header */ + for (i=0; i< CMD_HEAD_SIZE; i++) + { + retval = spi_transfer(fd, cmd+i, rxbuf+i, 1); + __android_log_print(ANDROID_LOG_INFO, "SPiCMD", "cmd[%d]=%x,rxbuf[%d]=%x",i,*(cmd+i),i, *(rxbuf+i)); + delay(20); + } + + cmd[0]=0xaa; //for response + +} + +void SpiLIb::RcvINS(int fd, u8 *txbuf, u8 *buf, u8 ins) +{ + int retval; + int cnt = 1000; + int count=0; + /* receive ins */ + INS: + txbuf[0] = 0xaa; + delay(20); + while(cnt--) + { + retval = spi_transfer(fd, txbuf, buf, 1); + __android_log_print(ANDROID_LOG_INFO, "SPiINS", "txbuf=%x,buf=%x", *txbuf,*buf); + if(*buf == ins) + { + return; + break; + } + else + goto INS; + } +} + +void SpiLIb::RcvLEN(int fd, u8 *txbuf, u8 *buf, u8 len) +{ + + int retval; + /* receive length */ + LEN: + for(int i=0;i>= 8; + memset(Z, entl & 0xFF, 1); + memcpy(Z + 2, pucID, idl); + memcpy(Z + 2 + idl, abxy, 32 *4); + memcpy(Z + 2 + idl + 4 * 32, pubkey, 32); + memcpy(Z + 2 + idl + 5 * 32, pubkey+32, 32); + nRet = SM3Hash(Z,l,tmpm); + if (nRet != 0) + goto quit; + free(Z); + l = inl + 32; + Z = (unsigned char *)malloc(l); + if (!Z) { + nRet = -1; + goto quit; + } + memcpy(Z,tmpm,32); + memcpy(Z+32, in, inl); + nRet = SM3Hash(Z,l,out); + quit: + if (Z) + free(Z); + return nRet; +}//用于签名的处理哈希值,用户标识01*16 + +int SpiLIb::SM2Sign(int index,const unsigned char *to_sign,unsigned char *out_sign)//SM2签名 所使用的哈希值应该来源于sm3hash_tosm2 +{ + int i; + int cnt; + unsigned char txbuf[256]; + unsigned char rxbuf[256]; + + int retval; + int msglen; + int fd; + const char *devname = "/dev/spidevSE"; + //const char *devname = "/dev/spidev0.0"; + //const char *devname = "/dev/mtkgpioctrl"; + + // NrsecSpiPort spi("/dev/spidevSE"); + // + // // NrsecSpiPort spi("/dev/spidev0.0") + fd = open(devname, O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + spi_master_init(devname, fd); + + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + SM2Sign_CMD[3]=index; + + CMD_RESEND: + + memcpy(txbuf, (const void *) SM2Sign_CMD, sizeof(SM2Sign_CMD)); + + SendCmdHeader(fd, txbuf, rxbuf); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); + + SendId(fd,txbuf,rxbuf, 0x55); + + memcpy(txbuf, to_sign, 32); + + SendData(fd, txbuf, rxbuf,32); + + SendEnd(fd,txbuf,rxbuf); + + memcpy(txbuf, (const void *) SM2Sign_CMD, sizeof(SM2Sign_CMD)); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); + + RcvLEN(fd,txbuf,rxbuf+1, 1); + + RcvData(fd, txbuf, rxbuf+2); + + RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90); + + __android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + for (i = 2; i < rxbuf[1]+2; i++) { + //sprintf(output, " %02x ", rxbuf[i]); + out_sign[i-2]= rxbuf[i]; + } + + close(fd); + return 0; +} + +int SpiLIb::SM2VerifySign(int index, unsigned char *hash,unsigned char *vs)//SM2验签 +{ + unsigned char txbuf[256]; + unsigned char rxbuf[256]; + + int retval; + int msglen; + int fd; + const char *devname = "/dev/spidevSE"; + //const char *devname = "/dev/spidev0.0"; + //const char *devname = "/dev/mtkgpioctrl"; + + // NrsecSpiPort spi("/dev/spidevSE"); + // + // // NrsecSpiPort spi("/dev/spidev0.0") + fd = open(devname, O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + spi_master_init(devname, fd); + + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + SM2VerifySign_CMD[3]=index; + + CMD_RESEND: + + memcpy(txbuf, (const void *) SM2VerifySign_CMD, sizeof(SM2VerifySign_CMD)); + + SendCmdHeader(fd, txbuf, rxbuf); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); + + SendId(fd,txbuf,rxbuf, 0x55); + + memcpy(txbuf, hash, 32); + memcpy(txbuf+32,vs,64); + + SendData(fd, txbuf, rxbuf,96); + + SendEnd(fd,txbuf,rxbuf); + + RcvSW(fd, txbuf, rxbuf, 0x90); + + __android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + + + close(fd); + return 0; +} + +int SpiLIb::SM2encrypt(int index,unsigned char *to_encrypt ,unsigned char *out_encrypt)//加密 +{ + int i; + int cnt; + unsigned char txbuf[512]; + unsigned char rxbuf[512]; + + int retval; + int msglen; + int fd; + const char *devname = "/dev/spidevSE"; + //const char *devname = "/dev/spidev0.0"; + //const char *devname = "/dev/mtkgpioctrl"; + + // NrsecSpiPort spi("/dev/spidevSE"); + // + // // NrsecSpiPort spi("/dev/spidev0.0") + fd = open(devname, O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + spi_master_init(devname, fd); + + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + SM2encrypt_CMD[3]=index; + + CMD_RESEND: + + memcpy(txbuf, (const void *) SM2encrypt_CMD, sizeof(SM2encrypt_CMD)); + + SendCmdHeader(fd, txbuf, rxbuf); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); + + SendId(fd,txbuf,rxbuf, 0x55); + + memcpy(txbuf, to_encrypt, 32); + + SendData(fd, txbuf, rxbuf,32); + + SendEnd(fd,txbuf,rxbuf); + + memcpy(txbuf, (const void *) SM2encrypt_CMD, sizeof(SM2encrypt_CMD)); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); + + RcvLEN(fd,txbuf,rxbuf+1, 1); + + RcvData(fd, txbuf, rxbuf+2); + + RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90); + + //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + for (i = 2; i < rxbuf[1]+2; i++) { + //sprintf(output, " %02x ", rxbuf[i]); + out_encrypt[i-2]= rxbuf[i]; + } + + close(fd); + return 0; +} +int SpiLIb::SM2decoder(int index,unsigned char *to_decoder ,unsigned char *out_decoder)//解密 +{ + int i; + int cnt; + unsigned char txbuf[512]; + unsigned char rxbuf[512]; + + int retval; + int msglen; + int fd; + const char *devname = "/dev/spidevSE"; + //const char *devname = "/dev/spidev0.0"; + //const char *devname = "/dev/mtkgpioctrl"; + + // NrsecSpiPort spi("/dev/spidevSE"); + // + // // NrsecSpiPort spi("/dev/spidev0.0") + fd = open(devname, O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + spi_master_init(devname, fd); + + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + SM2decoder_CMD[3]=index; + + CMD_RESEND: + + memcpy(txbuf, (const void *) SM2decoder_CMD, sizeof(SM2decoder_CMD)); + + SendCmdHeader(fd, txbuf, rxbuf); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); + + SendId(fd,txbuf,rxbuf, 0x55); + + memcpy(txbuf, to_decoder, 128); + + SendData(fd, txbuf, rxbuf,128); + + SendEnd(fd,txbuf,rxbuf); + + memcpy(txbuf, (const void *) SM2decoder_CMD, sizeof(SM2decoder_CMD)); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); + + RcvLEN(fd,txbuf,rxbuf+1, 1); + + RcvData(fd, txbuf, rxbuf+2); + + RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90); + + //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + for (i = 2; i < rxbuf[1]+2; i++) { + //sprintf(output, " %02x ", rxbuf[i]); + out_decoder[i-2]= rxbuf[i]; + } + + close(fd); + return 0; +} + +int SpiLIb::SM2cert(int type,int index,string cert,unsigned char *out_cert)//证书 +{ + int i; + int cnt; + unsigned char txbuf[512]; + unsigned char rxbuf[1024]; + + int retval; + int msglen; + int fd; + const char *devname = "/dev/spidevSE"; + //const char *devname = "/dev/spidev0.0"; + //const char *devname = "/dev/mtkgpioctrl"; + + // NrsecSpiPort spi("/dev/spidevSE"); + // + // // NrsecSpiPort spi("/dev/spidev0.0") + fd = open(devname, O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + spi_master_init(devname, fd); + + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + + int certlen=cert.length(); + unsigned char to_cert[certlen]; + for(int x=0;x +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +using namespace std; + +#define CMD_HEAD_SIZE 5 +using namespace std; +typedef unsigned char u8; + +class SpiLIb{ +public: + int Spirandom(); + int Version(); + int Indentify(unsigned char *to_idt,unsigned char *out_idt); + int SM2keypair(int index); + int SM2OutPub(int index,unsigned char result[]); + int SM2OutPri(int index,unsigned char result[]); + int SM2InPub(int index,const unsigned char new_key[]); + int SM2InPri(int index,const unsigned char new_key[]); + int SM3Hash(unsigned char *to_hash ,int len,unsigned char *out_hash); + int sm3hash_tosm2(unsigned char *in,int inl,unsigned char *out, unsigned char *pubkey, unsigned char + *pucID, int idl); + int SM2Sign(int index,const unsigned char *to_sign,unsigned char *out_sign); + int SM2VerifySign(int index,unsigned char *hash,unsigned char *vs); + int SM2encrypt(int index,unsigned char *to_encrypt ,unsigned char *out_encrypt); + int SM2decoder(int index,unsigned char *to_decoder ,unsigned char *out_decoder); + int SM2cert(int type,int index,string cert,unsigned char *out_cert); + + + + +private: + const unsigned char crc7_table[256]= { + 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, + 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, + 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, + 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e, + 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, + 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45, + 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, + 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c, + 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, + 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13, + 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, + 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a, + 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, + 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21, + 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, + 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38, + 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, + 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36, + 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, + 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f, + 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, + 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, + 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, + 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d, + 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, + 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52, + 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, + 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b, + 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, + 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60, + 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, + 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79 + }; + const unsigned char EK_CMD[5]={0x80,0xd4,0x01,0x00,0x10}; + const unsigned char AK_CMD[5]={0x80,0xd4,0x02,0x00,0x10}; + const unsigned char IV_CMD[5]={0x80,0xd4,0x04,0x00,0x10}; + volatile unsigned char SM1encrpt_CMD[5]={0xa0,0xe0,0x80,0xff,0xff}; + volatile unsigned char SM1decoder_CMD[5]={0xa0,0xe0,0x81,0xff,0xff}; + volatile unsigned char SM2Keypair_CMD[5]={0x80,0xb2,0x00,0xff,0x00}; + volatile unsigned char SM2OutPub_CMD[5]={0x80,0xb8,0x01,0xff,0x40}; + volatile unsigned char SM2OutPri_CMD[5]={0x80,0xb8,0x02,0xff,0x20}; + volatile unsigned char SM2InPub_CMD[5]={0x80,0xba,0x01,0xff,0x40}; + volatile unsigned char SM2InPri_CMD[5]={0x80,0xba,0x02,0xff,0x20}; + volatile unsigned char SM3Hash_CMD[5]={0x80,0xb5,0x00,0xff,0xff}; + volatile unsigned char SM2Sign_CMD[5]={0x80,0xb4,0x00,0xff,0x20}; + volatile unsigned char SM2VerifySign_CMD[5]={0x80,0xb6,0x00,0xff,0x60}; + volatile unsigned char SM2encrypt_CMD[5]={0x80,0xb3,0x01,0xff,0x20}; + volatile unsigned char SM2decoder_CMD[5]={0x80,0xb3,0x81,0xff,0x80}; + volatile unsigned char SM2cert_CMD[5]={0x80,0xb7,0xff,0xff,0xff}; + volatile unsigned char Random_CMD[5]={0x00,0x84,0x00,0x00,0xff}; + const unsigned char Version_CMD[5]={0x00,0x5b,0x00,0x00,0x40}; + const unsigned char Indentify_CMD[5]={0x80,0xb3,0x01,0x04,0x20}; + + int spi_transfer(int fd, unsigned char *txbuf, unsigned char *rxbuf, int bytes); + void spi_master_init(const char *name, int fd); + unsigned char get_crc7(const unsigned char *buff, int len); + void SendCmdHeader(int fd,u8 *cmd, u8 *rxbuf); + int delay(int x); + void RcvINS(int fd, u8 *txbuf, u8 *buf, u8 ins); + void RcvLEN(int fd, u8 *txbuf, u8 *buf, u8 len); + void RcvData(int fd, u8 *txbuf, u8 *buf); + void RcvData(int fd, u8 *txbuf, u8 *buf, int len); + void RcvSW(int fd, u8 *txbuf, u8 *buf, u8 sw); + void SendEnd(int fd, u8 *txbuf, u8 *buf); + void SendId(int fd, u8 *txbuf, u8 *buf, u8 id); + void SendData(int fd,u8 *data, u8 *rxbuf,int data_size); + + + +}; + + + + +#endif //TESTCOMM_SPILIB_H diff --git a/app/src/main/cpp/SpiPort.cpp b/app/src/main/cpp/SpiPort.cpp new file mode 100644 index 0000000..44e1afb --- /dev/null +++ b/app/src/main/cpp/SpiPort.cpp @@ -0,0 +1,62 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SpiPort.h" + +SpiPort::SpiPort(const std::string& path) : m_path(path), m_fd(0) +{ +} + +SpiPort::~SpiPort() +{ + if (m_fd > 0) + { + close(m_fd); + } +} + +bool SpiPort::Open() +{ + if(m_fd <= 0) m_fd = open(m_path.c_str(), O_RDWR/*|O_NDELAY|O_NOCTTY*/); + if(m_fd <= 0 ) { + int err = errno; + m_log = "open spi Error errno=" + std::to_string(err); + __android_log_print(ANDROID_LOG_INFO, "SPi", "open spi Error errno=%d", err); + return false; + } + else __android_log_print(ANDROID_LOG_INFO, "SPi", "open spi Success m_fd=%d",m_fd); + + return true; +} + +// write +int SpiPort::Write(unsigned char *buf, int len) +{ + return write(m_fd, buf, len); +} + +// read +int SpiPort::Read(unsigned char *buf, int len) +{ + return read(m_fd, buf, len); +} + +//close +bool SpiPort::Close() +{ + if(m_fd > 0) + { + close(m_fd); + m_fd = 0; + } + + return true; +} \ No newline at end of file diff --git a/app/src/main/cpp/SpiPort.h b/app/src/main/cpp/SpiPort.h new file mode 100644 index 0000000..a4d8269 --- /dev/null +++ b/app/src/main/cpp/SpiPort.h @@ -0,0 +1,30 @@ +#ifndef _SPIPORT_H_ +#define _SPIPORT_H_ + +#include + +class SpiPort +{ +public: + + SpiPort(const std::string& path); + ~SpiPort(); + + bool Open(); + int Write(unsigned char *buf, int len); + int Read(unsigned char *buf, int len); + + bool Close(); + + std::string GetLog() const + { + return m_log; + } + +protected: + std::string m_path; + std::string m_log; + int m_fd; +}; + +#endif \ No newline at end of file diff --git a/app/src/main/cpp/WeatherComm.cpp b/app/src/main/cpp/WeatherComm.cpp new file mode 100644 index 0000000..b0b2630 --- /dev/null +++ b/app/src/main/cpp/WeatherComm.cpp @@ -0,0 +1,595 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GPIOControl.h" +#include "WeatherComm.h" +#include + +SIO_PARAM_SERIAL_DEF serialport; +float weatherpntmsg[10]; + +static void set_baudrate (struct termios *opt, unsigned int baudrate) +{ + cfsetispeed(opt, baudrate); + cfsetospeed(opt, baudrate); +} + +static void set_data_bit (struct termios *opt, unsigned int databit) +{ + opt->c_cflag &= ~CSIZE; + switch (databit) + { + case 8: + opt->c_cflag |= CS8; + break; + case 7: + opt->c_cflag |= CS7; + break; + case 6: + opt->c_cflag |= CS6; + break; + case 5: + opt->c_cflag |= CS5; + break; + default: + opt->c_cflag |= CS8; + break; + } +} + +static void set_parity (struct termios *opt, char parity) +{ + switch (parity) + { + case'N':/* 无校验 */ + case 'n': + opt->c_cflag &= ~PARENB; + break; + case'E':/*偶校验*/ + case 'e': + opt->c_cflag |= PARENB; + opt->c_cflag &= ~PARODD; + break; + case'O':/* 奇校验 */ + case 'o': + opt->c_cflag |= PARENB; + opt->c_cflag |= ~PARODD; + break; + default: /*其它选择为无校验 */ + opt->c_cflag &= ~PARENB; + break; + } +} + +static void set_stopbit (struct termios *opt, const char *stopbit) +{ + if (strcmp(stopbit, "1") == 0) + { + opt->c_cflag &= ~CSTOPB;/*1 位停止位 t */ + } + else if(0 == strcmp(stopbit, "1.5")) + { + opt->c_cflag &= ~CSTOPB;/*1.5 位停止位 */ + } + else if(0 == strcmp (stopbit,"2")) + { + opt->c_cflag |= CSTOPB; /*2 位停止位 */ + } + else + { + opt->c_cflag &= ~CSTOPB; /*1 位停止位 */ + } +} + +int set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin ) +{ + struct termios opt; + tcgetattr(fd, &opt); + set_baudrate(&opt, baudrate); + //opt.c_cflag |= CLOCAL|CREAD; /*|CRTSCTS */ + opt.c_lflag &= ~(ICANON | ECHO |ECHOE |ISIG); + set_data_bit(&opt, databit); + set_parity(&opt, parity); + set_stopbit(&opt, stopbit); + opt.c_iflag &=~(INLCR|ICRNL); + opt.c_iflag &=~(IXON);/* 流控*/ + opt.c_oflag = 0; + //opt.c_lflag |= 0; + opt.c_oflag &= ~OPOST; + opt.c_cc[VTIME] = vtime; + opt.c_cc[VMIN] = vmin; + tcflush (fd, TCIFLUSH); + return (tcsetattr (fd, TCSANOW, &opt)); +} + +static void setInt(int cmd, int value) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + IOT_PARAM param; + param.cmd = cmd; + param.value = value; + // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value); + if( fd > 0 ) + { + int res = ioctl(fd, IOT_PARAM_WRITE, ¶m); + // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result); + close(fd); + } + return; +} +static void setRS485Enable(bool z) { + setInt(CMD_SET_485_EN_STATE, z ? 1 : 0); +} + +static void set485WriteMode() { + setInt(CMD_SET_485_STATE, 1); +} + +static void set485ReadMode() { + setInt(CMD_SET_485_STATE, 0); +} +static void set12VEnable(bool z) { + setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0); +} + +static void setCam3V3Enable(bool enabled) +{ + setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0); +} + + +/********************************************************************************* +* 气象数据处理 * +**********************************************************************************/ +void PortDataProcess( ) +{ + float fvalue, fcorvalue, *fvalua, frnb/*, fwind*/; + //WORD uDevAddr; + unsigned char cmdidx; + int i, j, aipnt, datanum; + SIO_PARAM_SERIAL_DEF *pPortParam; + char szbuf[64]; + + pPortParam = &serialport; + //取出装置地址,开始处理地址+++ + if(0x02 == pPortParam->m_au8RecvBuf[5]) + { + //pPortParam->devaddr = pPortParam->m_au8RecvBuf[4]; + return; + } + cmdidx = pPortParam->m_au8RecvBuf[5]; +#if 0 + aipnt = pPortParam->SameTypeDevIdx; + uDevAddr = serialport->m_au8RecvBuf[4]; + if(0 == srdt.IsReadWireTem) + { + if(uDevAddr != pPortParam->devaddr) + return; + } +#endif + fvalua = &fvalue; + datanum = pPortParam->m_au8RecvBuf[6]; + if((0x08 != cmdidx) && (0x09 != cmdidx)) + return; + + for(i = 0, j=7; (im_au8RecvBuf[1]); i++, j+=5 ) + { + if(0x08 == cmdidx) + fvalue = (pPortParam->m_au8RecvBuf[j+1]<<24)+(pPortParam->m_au8RecvBuf[j+2]<<16) + +(pPortParam->m_au8RecvBuf[j+3]<<8)+pPortParam->m_au8RecvBuf[j+4]; + else + { + *(u_char *)fvalua = pPortParam->m_au8RecvBuf[j+4]; + *((u_char *)fvalua+1) = pPortParam->m_au8RecvBuf[j+3]; + *((u_char *)fvalua+2) = pPortParam->m_au8RecvBuf[j+2]; + *((u_char *)fvalua+3) = pPortParam->m_au8RecvBuf[j+1]; + } + switch(pPortParam->m_au8RecvBuf[j]) + { + case 1: /*温度*/ + weatherpntmsg[0] = fvalue; + LOGE("温度:%0.3f ", fvalue); + break; + case 2: /*气压*/ + weatherpntmsg[5] = fvalue; + LOGE("气压:%0.3f ", fvalue); + break; + case 3: /*湿度*/ + weatherpntmsg[1] = fvalue; + LOGE("湿度:%0.3f ", fvalue); + break; + case 4: /*雨量*/ + break; + case 5: /*日照*/ + break; + case 6: /*风速*/ + weatherpntmsg[2] = fvalue; + LOGE("风速:%0.3f ", fvalue); + break; + case 7: /*风向*/ + weatherpntmsg[3] = fvalue; + LOGE("风向:%0.3f ", fvalue); + break; + case 8: /*拉力*/ + LOGE("拉力:%0.3f ", fvalue); + break; + case 9: /*倾角传感器X轴倾角*/ + LOGE("X:%0.3f ", fvalue); + break; + case 10: /*倾角传感器Y轴倾角*/ + LOGE("Y:%0.3f ", fvalue); + break; + case 11: /*测温球导线温度*/ + case 12: /*测温球内部温度*/ + break; + case 13: /*测温球导线X轴倾角*/ + break; + case 14: /*测温球导线Y轴倾角*/ + break; + case 15: /*测温球导线电流*/ + break; + case 16: /*测温球电池电压*/ + break; + case 17: /*A相泄漏电流平均值;*/ + break; + case 18: /*A相泄漏电流最大值;*/ + break; + case 19: /*A相超过3mA的脉冲频次*/ + break; + case 20: /*A相超过10mA的脉冲频次*/ + break; + case 21: /*B相泄漏电流平均值;*/ + break; + case 22: /*B相泄漏电流最大值;*/ + break; + case 23: /*B相超过3mA的脉冲频次*/ + break; + case 24: /*B相超过10mA的脉冲频次*/ + case 25: /*C相泄漏电流平均值;*/ + case 26: /*C相泄漏电流最大值;*/ + case 27: /*C相超过3mA的脉冲频次*/ + case 28: /*C相超过10mA的脉冲频次*/ + break; + } + } +} + +//*************************************************************** +//* 按照协议格式化接收数据 * +//*************************************************************** +static void RecvData(u_char *buf, int len)// 规约读数据处理 +{ + int i, ictime; + //WORD crc, check; + SIO_PARAM_SERIAL_DEF *pPortParam; + + pPortParam = &serialport; + ictime = (int)time(NULL); + + if(pPortParam->m_iRecvLen == 0) + { + pPortParam->iRecvTime = ictime; + } + else + { + if((ictime-pPortParam->iRecvTime > 6) || (ictime - pPortParam->iRecvTime < 0)) + pPortParam->iRecvTime = ictime; + else if(ictime - pPortParam->iRecvTime > 2) + { + pPortParam->m_iRecvLen = 0; + pPortParam->m_iRevStatus = 0; + } + } + + for(i=0; im_iRevStatus) + { + case 0: // 0x68 + pPortParam->m_iRecvLen = 0; + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(0x68 == buf[i]) + pPortParam->m_iRevStatus++; + else + pPortParam->m_iRevStatus = 18; + break; + case 1: // len1 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iRevStatus++; + break; + case 2: // len2 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + //if(buf[i] == pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2]) + { + pPortParam->m_iRevStatus++; + pPortParam->m_iNeedRevLength = buf[i]+5; + } + //else + // pPortParam->m_iRevStatus = 18; + break; + case 3: // 0x68 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iNeedRevLength--; + if(0x68 == buf[i]) + pPortParam->m_iRevStatus++; + else + pPortParam->m_iRevStatus = 18; + break; + case 4: // 正确接收数据 + pPortParam->m_iNeedRevLength--; + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(pPortParam->m_iNeedRevLength > 0) + break; + if(buf[i] != 0x16) + { + pPortParam->m_iRevStatus=18; + break; + } + + //if(CheckLpcError(serialport->m_au8RecvBuf, pPortParam->m_iRecvLen) == TRUE) + { + PortDataProcess(); + pPortParam->m_iRevStatus = 0; + pPortParam->RevCmdFlag = 1; + } + pPortParam->m_iRecvLen = 0; + break; + case 255:// 错误接收数据 + default: + if(buf[i] == 0x68) + { + pPortParam->m_iRevStatus = 1; + pPortParam->m_iRecvLen = 1; + pPortParam->m_au8RecvBuf[0] = buf[i]; + } + else if(buf[i] == 0x16) + { + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iRevStatus = 0; + pPortParam->m_iRecvLen = 0; + } + else + { + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(pPortParam->m_iRecvLen > 200) + { + pPortParam->m_iRecvLen = 0; + } + } + break; + } + } +} + +static long get_msec(void ) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + long time_in_msec = tv.tv_sec * 1000 + tv.tv_usec/1000; + + return time_in_msec; +} +//int inum =0; +//int itimecnt=0; +static int weather_comm(SERIAL_PARAM weatherport) +{ + int fd = -1; + int len, i,ret, icnt=0; + long ictime, iruntime, isendtime, irecvtime; + //unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x0D,0x09,0x16,0x16}; + unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x01,0x09,0x0A,0x16}; + //unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x0ff,0x02,0x01,0x16}; + //unsigned char sendbuf[] = {0x68,0x01,0x01,0x68,0x02,0x01,0x01,0x04, 0x16}; + char recvbuf[256], szbuf[512]; + //char serial_description[] = "/dev/ttyS0"; + +#if 0 + DIR *dir = opendir("/dev"); + if (dir == NULL) { + LOGE("_test_ opendir"); + return -1; + } + + // 读取目录项 + struct dirent *entry; + while ((entry = readdir(dir)) != NULL) { + // 过滤出串口设备,通常以"ttyS"或"ttyUSB"开头 + if ((strncmp(entry->d_name, "ttyS2", 5) == 0) || + (strncmp(entry->d_name, "ttyS0", 5) == 0)) { + LOGE("_test_ Found serial port: %s\n", entry->d_name); + } + } + + // 关闭目录 + closedir(dir); +#endif + serialport.RevCmdFlag = 1; + serialport.m_iRecvLen = 0; + serialport.m_iRevStatus = 0; + + set12VEnable(true); + setCam3V3Enable(true); + setRS485Enable(true); + setInt(CMD_SET_WTH_POWER, 1); + setInt(CMD_SET_PULL_POWER, 1); + setInt(CMD_SET_ANGLE_POWER, 1); + setInt(CMD_SET_OTHER_POWER, 1); + setInt(CMD_SET_PIC1_POWER, 1); +#if 1 + setInt(CMD_SET_485_en0, 1); + setInt(CMD_SET_485_en1, 1); + setInt(CMD_SET_485_en2, 1); + setInt(CMD_SET_485_en3, 1); + setInt(CMD_SET_485_en4, 1); +#else + setInt(CMD_SET_485_en0, 0); + setInt(CMD_SET_485_en1, 0); + setInt(CMD_SET_485_en2, 0); + setInt(CMD_SET_485_en3, 0); + setInt(CMD_SET_485_en4, 0); +#endif + sleep(3); + //ictime = (int)time(NULL); + ictime = get_msec(); + for(;;) + { + if(fd < 0) + { + fd = open(weatherport.pathname, O_RDWR | O_NDELAY); + //fd = open(weatherport.pathname, O_RDWR | O_NOCTTY); + if(fd < 0) + { + LOGE("open serial %s fail!", weatherport.pathname); + //perror(weatherport.pathname); + return -1; + } else + LOGE("open serial %s success!", weatherport.pathname); + + + ret= set_port_attr (fd, weatherport.baudrate,weatherport.databit,weatherport.stopbit,weatherport.parity,0,0 );/*9600 8n1 */ + if(ret < 0) + { + LOGE("_test_ set uart arrt faile \n"); + return -1; + } + } + //tcdrain(fd); + //sleep(2); + usleep(100); + //iruntime = (int)time(NULL); + iruntime = get_msec(); + if((iruntime - ictime > 120000) || (iruntime - ictime < 0)) + ictime = iruntime; + if(iruntime - ictime > 20000) + { + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf, "气象采样时间=%0.3f秒,停止采样!", (iruntime-ictime)/1000.0); + LOGE("%s", szbuf); + break; + } + + if(1 == serialport.RevCmdFlag) + { + //set485WriteMode(); + + len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */ + serialport.RevCmdFlag = 0; + LOGE("发送命令时间差%ld毫秒", get_msec()-isendtime); + //isendtime = time(NULL); + isendtime = get_msec(); + if (len < 0) { + LOGE("write data error \n"); + return -1; + } else { + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf, "Send:"); + for (i = 0; i < len; i++) { + sprintf(szbuf, "%s %02X", szbuf, sendbuf[i]); + } + LOGE("%s", szbuf); + //icnt = 0; + //inum++; + } + //tcdrain(fd); + //usleep(50000); + } + else + { + //irecvtime = time(NULL); + irecvtime = get_msec(); + if((irecvtime-isendtime > 6000) ||(irecvtime - isendtime < 0)) + isendtime = irecvtime; + if (irecvtime-isendtime > 500) + { + LOGE("传感器超过%ld毫秒未应答", irecvtime-isendtime); + serialport.RevCmdFlag = 1; + serialport.m_iRecvLen = 0; + serialport.m_iRevStatus = 0; + //close(fd); + //set12VEnable(false); + //setCam3V3Enable(false); + //setRS485Enable(false); + //fd = -1; + continue; + } + } + //set485ReadMode(); + memset(recvbuf, 0, sizeof(recvbuf)); + len = read(fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */ + if (len < 0) { + LOGE("serial read error \n"); + continue; + } + if(0 == len) + { + //icnt++; + continue; + } + + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf, "Recv:"); + for (i = 0; i < len; i++) { + sprintf(szbuf, "%s %02X", szbuf, recvbuf[i]); + } + __android_log_print(ANDROID_LOG_INFO, "serial", "%s", szbuf); + RecvData((u_char*)recvbuf, len); + //LOGE("一周期空循环次数%d, 读取次数%d, 时间:%d %d", icnt, inum, (int)time(NULL), itimecnt); + icnt = 0; + //serialport.RevCmdFlag =1; + } + + close(fd); + set12VEnable(false); + setCam3V3Enable(false); + setRS485Enable(false); + + //exit(-1); + return(0); +} + +int serial_port_comm() +{ + SERIAL_PARAM portparm; + + //struct timeval tv; + + //gettimeofday(&tv, NULL); + //long time_in_microseconds = tv.tv_sec * 1000000 + tv.tv_usec; + + //LOGE("Current time in microseconds: %ld\n", time_in_microseconds); + +#if 1 + memset(portparm.pathname, 0, sizeof(portparm.pathname)); + //sprintf(portparm.pathname, "/dev/ttyS1"); + sprintf(portparm.pathname, "/dev/ttysWK3"); + portparm.parity = 'N'; + portparm.databit = 8; + portparm.baudrate = B9600; + memset(portparm.stopbit, 0, sizeof(portparm.stopbit)); + sprintf(portparm.stopbit, "1"); +#endif + //itimecnt = (int)time(NULL); + + for(;;) + { + sleep(3); + weather_comm(portparm); + } + + return 0; +} + diff --git a/app/src/main/cpp/WeatherComm.h b/app/src/main/cpp/WeatherComm.h new file mode 100644 index 0000000..3a9d311 --- /dev/null +++ b/app/src/main/cpp/WeatherComm.h @@ -0,0 +1,51 @@ +// +// Created by hyz on 2024/6/5. +// + +#ifndef WEATHERCOMM_H +#define WEATHERCOMM_H + +#include +#include "GPIOControl.h" + +#define MAX_STRING_LEN 32 +#define IOT_PARAM_WRITE 0xAE +#define IOT_PARAM_READ 0xAF + +#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "serial_port_comm", fmt, ##args) + +// 串口参数 +typedef struct +{ + int baudrate; /* 波特率*/ + int databit; /* 数据位*/ + char stopbit[8]; /* 停止位*/ + char parity; /* 校验位*/ + char pathname[128];/* 串口文件名及路径*/ +} SERIAL_PARAM; + +typedef struct +{ + int m_iRevStatus; /* */ + int m_iRecvLen; /* */ + int m_iNeedRevLength; /* */ + int iRecvTime; /* */ + int RevCmdFlag; + unsigned char m_au8RecvBuf[128];/* */ +} SIO_PARAM_SERIAL_DEF; + +typedef struct +{ + int cmd; + int value; + int result; + long value2; + char str[MAX_STRING_LEN]; +}IOT_PARAM; + +void PortDataProcess( ); +int serial_port_comm(); +static int weather_comm(SERIAL_PARAM weatherport); +int set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin ); + +#endif //WEATHERCOMM_H diff --git a/app/src/main/cpp/native-lib.cpp b/app/src/main/cpp/native-lib.cpp new file mode 100644 index 0000000..ed200d8 --- /dev/null +++ b/app/src/main/cpp/native-lib.cpp @@ -0,0 +1,1028 @@ +#include +#include + +#include "SpiPort.h" +#include "SpiLib.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GPIOControl.h" +#include "serialComm.h" +#include "SensorsProtocol.h" +#include "WeatherComm.h" + +#if 0 +#define BYTE u_char; +// 串口参数 +typedef struct +{ + int baudrate; /* 波特率*/ + int databit; /* 数据位*/ + char stopbit[8]; /* 停止位*/ + char parity; /* 校验位*/ + char pathname[128];/* 串口文件名及路径*/ + } SERIAL_PARAM; + +typedef struct +{ + int m_iRevStatus; /* */ + int m_iRecvLen; /* */ + int m_iNeedRevLength; /* */ + int iRecvTime; /* */ + int RevCmdFlag; + unsigned char m_au8RecvBuf[128];/* */ +} SIO_PARAM_SERIAL_DEF; + +extern SIO_PARAM_SERIAL_DEF serialport; +extern float weatherpntmsg[10]; +#endif + +int istop=1; +//set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin ) +class NrsecSpiPort : public SpiPort { +public: + NrsecSpiPort(const std::string& path) : SpiPort(path) { + + } + + bool Open() + { + if (!SpiPort::Open()) + { + return false; + } + + uint8_t mode = SPI_MODE_3; + uint8_t bits = 8; + uint32_t speed = 33000000; + uint8_t lsb = 1; + // const char *device = "/dev/spidev32766.1"; + + if (ioctl(m_fd, SPI_IOC_WR_MODE, &mode) == -1 || + ioctl(m_fd, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1 || + ioctl(m_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1 || + ioctl(m_fd, SPI_IOC_WR_LSB_FIRST, &lsb) == -1) + { + Close(); + return false; + } + + return true; + } + bool GenKeyPair(int keyIdx) { + unsigned char header[] = {0x80, 0xb2, 0x00, (unsigned char)keyIdx, 0x00 }; + + int bytesWriten = Write(header, sizeof(header)); + unsigned char buffer[2] = { 0 }; + int bytesRead = Read(buffer, sizeof(buffer)); + if (bytesRead > 0) { + int aa = 0; + } else { + int bb = 0; + } + + return true; + } +}; + +#if 0 +static void set_baudrate (struct termios *opt, unsigned int baudrate) +{ + cfsetispeed(opt, baudrate); + cfsetospeed(opt, baudrate); +} + +static void set_data_bit (struct termios *opt, unsigned int databit) +{ + opt->c_cflag &= ~CSIZE; + switch (databit) + { + case 8: + opt->c_cflag |= CS8; + break; + case 7: + opt->c_cflag |= CS7; + break; + case 6: + opt->c_cflag |= CS6; + break; + case 5: + opt->c_cflag |= CS5; + break; + default: + opt->c_cflag |= CS8; + break; + } +} + +static void set_parity (struct termios *opt, char parity) +{ + switch (parity) + { + case'N':/* 无校验 */ + case 'n': + opt->c_cflag &= ~PARENB; + break; + case'E':/*偶校验*/ + case 'e': + opt->c_cflag |= PARENB; + opt->c_cflag &= ~PARODD; + break; + case'O':/* 奇校验 */ + case 'o': + opt->c_cflag |= PARENB; + opt->c_cflag |= ~PARODD; + break; + default: /*其它选择为无校验 */ + opt->c_cflag &= ~PARENB; + break; + } +} + +static void set_stopbit (struct termios *opt, const char *stopbit) +{ + if (strcmp(stopbit, "1") == 0) + { + opt->c_cflag &= ~CSTOPB;/*1 位停止位 t */ + } + else if(0 == strcmp(stopbit, "1.5")) + { + opt->c_cflag &= ~CSTOPB;/*1.5 位停止位 */ + } + else if(0 == strcmp (stopbit,"2")) + { + opt->c_cflag |= CSTOPB; /*2 位停止位 */ + } + else + { + opt->c_cflag &= ~CSTOPB; /*1 位停止位 */ + } +} + +int set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin ) +{ + struct termios opt; + tcgetattr(fd, &opt); + set_baudrate(&opt, baudrate); + //opt.c_cflag |= CLOCAL|CREAD; /*|CRTSCTS */ + opt.c_lflag &= ~(ICANON | ECHO |ECHOE |ISIG); + set_data_bit(&opt, databit); + set_parity(&opt, parity); + set_stopbit(&opt, stopbit); + opt.c_oflag = 0; + //opt.c_lflag |= 0; + opt.c_oflag &= ~OPOST; + opt.c_cc[VTIME] = vtime; + opt.c_cc[VMIN] = vmin; + tcflush (fd, TCIFLUSH); + return (tcsetattr (fd, TCSANOW, &opt)); +} +#define MAX_STRING_LEN 32 +#define IOT_PARAM_WRITE 0xAE +#define IOT_PARAM_READ 0xAF + +typedef struct +{ + int cmd; + int value; + int result; + long value2; + char str[MAX_STRING_LEN]; +}IOT_PARAM; + +#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "serial_port_comm", fmt, ##args) +#endif +void setInt(int cmd, int value) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + IOT_PARAM param; + param.cmd = cmd; + param.value = value; + // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value); + if( fd > 0 ) + { + int res = ioctl(fd, IOT_PARAM_WRITE, ¶m); + // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result); + close(fd); + } + return; +} +static void setRS485Enable(bool z) { + setInt(CMD_SET_485_EN_STATE, z ? 1 : 0); +} + +static void set485WriteMode() { + setInt(CMD_SET_485_STATE, 1); +} + + +static void set485ReadMode() { + setInt(CMD_SET_485_STATE, 0); +} +static void set12VEnable(bool z) { + setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0); +} +#if 0 +static void setCam3V3Enable(bool enabled) +{ + setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0); +} + +/********************************************************************************* +* 气象数据处理 * +**********************************************************************************/ +void PortDataProcess( void ) +{ + float fvalue, fcorvalue, *fvalua, frnb/*, fwind*/; + //WORD uDevAddr; + unsigned char cmdidx; + int i, j, aipnt, datanum; + SIO_PARAM_SERIAL_DEF *pPortParam; + char szbuf[64]; + + pPortParam = &serialport; + //取出装置地址,开始处理地址+++ + if(0x02 == pPortParam->m_au8RecvBuf[5]) + { + //pPortParam->devaddr = pPortParam->m_au8RecvBuf[4]; + return; + } + cmdidx = pPortParam->m_au8RecvBuf[5]; +#if 0 + aipnt = pPortParam->SameTypeDevIdx; + uDevAddr = serialport->m_au8RecvBuf[4]; + if(0 == srdt.IsReadWireTem) + { + if(uDevAddr != pPortParam->devaddr) + return; + } +#endif + fvalua = &fvalue; + datanum = pPortParam->m_au8RecvBuf[6]; + if((0x08 != cmdidx) && (0x09 != cmdidx)) + return; + + for(i = 0, j=7; (im_au8RecvBuf[1]); i++, j+=5 ) + { + if(0x08 == cmdidx) + fvalue = (pPortParam->m_au8RecvBuf[j+1]<<24)+(pPortParam->m_au8RecvBuf[j+2]<<16) + +(pPortParam->m_au8RecvBuf[j+3]<<8)+pPortParam->m_au8RecvBuf[j+4]; + else + { + *(u_char *)fvalua = pPortParam->m_au8RecvBuf[j+4]; + *((u_char *)fvalua+1) = pPortParam->m_au8RecvBuf[j+3]; + *((u_char *)fvalua+2) = pPortParam->m_au8RecvBuf[j+2]; + *((u_char *)fvalua+3) = pPortParam->m_au8RecvBuf[j+1]; + } + switch(pPortParam->m_au8RecvBuf[j]) + { + case 1: /*温度*/ + weatherpntmsg[0] = fvalue; + LOGE("温度:%0.3f ", fvalue); + break; + case 2: /*气压*/ + weatherpntmsg[5] = fvalue; + LOGE("气压:%0.3f ", fvalue); + break; + case 3: /*湿度*/ + weatherpntmsg[1] = fvalue; + LOGE("湿度:%0.3f ", fvalue); + break; + case 4: /*雨量*/ + break; + case 5: /*日照*/ + break; + case 6: /*风速*/ + weatherpntmsg[2] = fvalue; + LOGE("风速:%0.3f ", fvalue); + break; + case 7: /*风向*/ + weatherpntmsg[3] = fvalue; + LOGE("风向:%0.3f ", fvalue); + break; + case 8: /*拉力*/ + case 9: /*倾角传感器X轴倾角*/ + case 10: /*倾角传感器Y轴倾角*/ + case 11: /*测温球导线温度*/ + case 12: /*测温球内部温度*/ + break; + case 13: /*测温球导线X轴倾角*/ + break; + case 14: /*测温球导线Y轴倾角*/ + break; + case 15: /*测温球导线电流*/ + break; + case 16: /*测温球电池电压*/ + break; + case 17: /*A相泄漏电流平均值;*/ + break; + case 18: /*A相泄漏电流最大值;*/ + break; + case 19: /*A相超过3mA的脉冲频次*/ + break; + case 20: /*A相超过10mA的脉冲频次*/ + break; + case 21: /*B相泄漏电流平均值;*/ + break; + case 22: /*B相泄漏电流最大值;*/ + break; + case 23: /*B相超过3mA的脉冲频次*/ + break; + case 24: /*B相超过10mA的脉冲频次*/ + case 25: /*C相泄漏电流平均值;*/ + case 26: /*C相泄漏电流最大值;*/ + case 27: /*C相超过3mA的脉冲频次*/ + case 28: /*C相超过10mA的脉冲频次*/ + break; + } + } +} + +//*************************************************************** +//* 按照协议格式化接收数据 * +//*************************************************************** +void RecvData(u_char *buf, int len)// 规约读数据处理 +{ + int i, ictime; + //WORD crc, check; + SIO_PARAM_SERIAL_DEF *pPortParam; + + pPortParam = &serialport; + ictime = (int)time(NULL); + + if(pPortParam->m_iRecvLen == 0) + { + pPortParam->iRecvTime = ictime; + } + else + { + if((ictime-pPortParam->iRecvTime > 6) || (ictime - pPortParam->iRecvTime < 0)) + pPortParam->iRecvTime = ictime; + else if(ictime - pPortParam->iRecvTime > 2) + { + pPortParam->m_iRecvLen = 0; + pPortParam->m_iRevStatus = 0; + } + } + + for(i=0; im_iRevStatus) + { + case 0: // 0x68 + pPortParam->m_iRecvLen = 0; + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(0x68 == buf[i]) + pPortParam->m_iRevStatus++; + else + pPortParam->m_iRevStatus = 18; + break; + case 1: // len1 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iRevStatus++; + break; + case 2: // len2 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(buf[i] == pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2]) + { + pPortParam->m_iRevStatus++; + pPortParam->m_iNeedRevLength = buf[i]+5; + } + else + pPortParam->m_iRevStatus = 18; + break; + case 3: // 0x68 + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iNeedRevLength--; + if(0x68 == buf[i]) + pPortParam->m_iRevStatus++; + else + pPortParam->m_iRevStatus = 18; + break; + case 4: // 正确接收数据 + pPortParam->m_iNeedRevLength--; + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(pPortParam->m_iNeedRevLength > 0) + break; + if(buf[i] != 0x16) + { + pPortParam->m_iRevStatus=18; + break; + } + + //if(CheckLpcError(serialport->m_au8RecvBuf, pPortParam->m_iRecvLen) == TRUE) + { + PortDataProcess(); + pPortParam->m_iRevStatus = 0; + pPortParam->RevCmdFlag = 1; + } + pPortParam->m_iRecvLen = 0; + break; + case 255:// 错误接收数据 + default: + if(buf[i] == 0x68) + { + pPortParam->m_iRevStatus = 1; + pPortParam->m_iRecvLen = 1; + pPortParam->m_au8RecvBuf[0] = buf[i]; + } + else if(buf[i] == 0x16) + { + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iRevStatus = 0; + pPortParam->m_iRecvLen = 0; + } + else + { + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if(pPortParam->m_iRecvLen > 200) + { + pPortParam->m_iRecvLen = 0; + } + } + break; + } + } +} + +//int inum =0; +//int itimecnt=0; +int weather_comm(SERIAL_PARAM weatherport) +{ + int fd = -1; + int len, i,ret, ictime, iruntime, isendtime, irecvtime, icnt=0; + unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x01,0x09,0x0a,0x16}; + char recvbuf[256], szbuf[512]; + //char serial_description[] = "/dev/ttyS0"; + +#if 0 + DIR *dir = opendir("/dev"); + if (dir == NULL) { + LOGE("_test_ opendir"); + return -1; + } + + // 读取目录项 + struct dirent *entry; + while ((entry = readdir(dir)) != NULL) { + // 过滤出串口设备,通常以"ttyS"或"ttyUSB"开头 + if ((strncmp(entry->d_name, "ttyS2", 5) == 0) || + (strncmp(entry->d_name, "ttyS0", 5) == 0)) { + LOGE("_test_ Found serial port: %s\n", entry->d_name); + } + } + + // 关闭目录 + closedir(dir); +#endif + serialport.RevCmdFlag = 1; + serialport.m_iRecvLen = 0; + serialport.m_iRevStatus = 0; + + set12VEnable(true); + setCam3V3Enable(true); + setRS485Enable(true); + + ictime = (int)time(NULL); + for(;;) + { + if(fd < 0) + { + fd = open(weatherport.pathname, O_RDWR | O_NDELAY); + //fd = open(weatherport.pathname, O_RDWR | O_NOCTTY); + if(fd < 0) + { + LOGE("_test_ open serial error \n"); + perror(weatherport.pathname); + return -1; + } + + ret= set_port_attr (fd, weatherport.baudrate,weatherport.databit,weatherport.stopbit,weatherport.parity,0,0 );/*9600 8n1 */ + if(ret < 0) + { + LOGE("_test_ set uart arrt faile \n"); + return -1; + } + } + + usleep(10000); + iruntime = (int)time(NULL); + if((iruntime - ictime > 120) || (iruntime - ictime < 0)) + ictime = iruntime; + if(iruntime - ictime > 19) + { + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf, "气象采样时间=%d,停止采样!", iruntime-ictime); + LOGE("%s", szbuf); + break; + } + + if(1 == serialport.RevCmdFlag) + { + set485WriteMode(); + + len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */ + serialport.RevCmdFlag = 0; + isendtime = time(NULL); + if (len < 0) { + LOGE("write data error \n"); + return -1; + } else { + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf, "Send:"); + for (i = 0; i < len; i++) { + sprintf(szbuf, "%s %02X", szbuf, sendbuf[i]); + } + LOGE("%s", szbuf); + //icnt = 0; + //inum++; + } + tcdrain(fd); + //usleep(50000); + } + else + { + irecvtime = time(NULL); + if((irecvtime-isendtime > 6) ||(irecvtime - isendtime < 0)) + isendtime = irecvtime; + if (irecvtime-isendtime > 1) + { + LOGE("传感器超过%d秒未应答", irecvtime-isendtime); + serialport.RevCmdFlag = 1; + serialport.m_iRecvLen = 0; + serialport.m_iRevStatus = 0; + close(fd); + //set12VEnable(false); + //setCam3V3Enable(false); + //setRS485Enable(false); + fd = -1; + continue; + } + } + set485ReadMode(); + memset(recvbuf, 0, sizeof(recvbuf)); + len = read(fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */ + if (len < 0) { + LOGE("serial read error \n"); + continue; + } + if(0 == len) + { + //icnt++; + continue; + } + + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf, "Recv:"); + for (i = 0; i < len; i++) { + sprintf(szbuf, "%s %02X", szbuf, recvbuf[i]); + } + __android_log_print(ANDROID_LOG_INFO, "serial", "%s", szbuf); + RecvData((u_char*)recvbuf, len); + //LOGE("一周期空循环次数%d, 读取次数%d, 时间:%d %d", icnt, inum, (int)time(NULL), itimecnt); + icnt = 0; + //serialport.RevCmdFlag =1; + } + + close(fd); + set12VEnable(false); + setCam3V3Enable(false); + setRS485Enable(false); + + //exit(-1); + return(0); +} + +int serial_port_comm() +{ + SERIAL_PARAM portparm; +#if 1 + memset(portparm.pathname, 0, sizeof(portparm.pathname)); + sprintf(portparm.pathname, "/dev/ttyS0"); + portparm.parity = 'N'; + portparm.databit = 8; + portparm.baudrate = B9600; + memset(portparm.stopbit, 0, sizeof(portparm.stopbit)); + sprintf(portparm.stopbit, "1"); +#endif + //itimecnt = (int)time(NULL); + + for(;;) + weather_comm(portparm); + return 0; +} +#endif +extern "C" JNIEXPORT jstring JNICALL +Java_com_xinyingpower_testcomm_MainActivity_stringFromJNI( + JNIEnv* env, + jobject /* this */) { + std::string hello = "Hello from C++"; + return env->NewStringUTF(hello.c_str()); +} + +extern "C" JNIEXPORT jstring JNICALL +Java_com_xinyingpower_testcomm_MainActivity_testSpi( + JNIEnv* env, + jobject /*this*/, jint port) { + //testSpi(); + SpiLIb a; + unsigned char newkey[32]={0xaf,0x0c,0xa9,0x40,0x1f,0xe6,0xee,0x0f,0x4c, + 0xfb,0xf7,0x17,0x71,0xde,0x61,0x59 + ,0x0a,0x05,0x77, + 0xfa,0xe7,0xd1,0x8d,0x10,0x3a,0x79,0x23,0xf2,0xb3, + 0x6d,0xea,0x8e +// ,0xe0,0x64,0xe7,0x5d,0x49,0x84,0xe4, +// 0x5f,0xc9,0x07,0x03,0x52,0x33,0x79,0x87,0xd4,0x62, +// 0x62,0xc0,0xcc,0xf0,0xd6,0x85,0x20,0x7f,0x7a,0xe8, +// 0xc8,0xed,0x12,0xdb,0xdc + }; + unsigned char outpub[32],outsign[64], *outen = new unsigned char [256]; + unsigned char pucid[16]={0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}; + string b="C=CN,ST=jiangsu,L=nanjing,O=GDD,OU=nari,CN=test001"; + //a.SM2keypair(0x00); + //a.SM3Hash(newkey,16, outpub); + //a.sm3hash_tosm2(newkey,16,outpub,newkey,pucid,16); + //a.SM2Sign(0x00,outpub,outsign); + //a.SM2VerifySign(0x00,outpub,outsign); + //if(i < wen, i++) + //lxy modify modify + //LOGE("_test_ setRS485Enable true"); + //setRS485Enable(true); + + //set12VEnable(true); + //serial_port_comm(); + //GM_StartSerialComm(); + testComm(); + //GM_StartSerialCameraPhoto(1, 0); + //lxy modify modify + //LOGE("_test_ setRS485Enable false"); + //setRS485Enable(false); + return env->NewStringUTF(""); + +#if 0 + DIR *dir = opendir("/dev"); + if (dir == NULL) { + perror("opendir"); + //return env->NewStringUTF("error"); + //return -1; + } + + // 读取目录项 + struct dirent *entry; + while ((entry = readdir(dir)) != NULL) { + // 过滤出串口设备,通常以"ttyS"或"ttyUSB"开头 + if ((strncmp(entry->d_name, "ttyS2", 5) == 0) || + (strncmp(entry->d_name, "ttyS0", 5) == 0)) { + printf("Found serial port: %s\n", entry->d_name); + } + } + + // 关闭目录 + closedir(dir); +#endif + a.SM2cert(0x00,0x00,b,outen); + for (int i = 0; i < 32; i++) { + //sprintf(output, " %02x ", rxbuf[i]); + __android_log_print(ANDROID_LOG_INFO, "SPi", "%02x", outen[i]); + } +// a.SM2decoder(0x00,outen,outpub); +// +// for (int i = 0; i < 64; i++) { +// //sprintf(output, " %02x ", rxbuf[i]); +// __android_log_print(ANDROID_LOG_INFO, "SPi", "%02x", outpub[i]); +// } + + //a.SM3Hash(0x00,0x10,newkey); + //testVersion(); + + return env->NewStringUTF("End"); + + // NrsecSpiPort spi("/dev/mtkgpioctrl"); + NrsecSpiPort spi("/dev/spidevSE"); + + // NrsecSpiPort spi("/dev/spidev0.0"); + + if (!spi.Open()) { + return env->NewStringUTF(spi.GetLog().c_str()); + } + + spi.GenKeyPair(0); + + unsigned char header[] = { 0x00, 0x5b, 0x00, 0x00, 0x40 }; + + int bytesWriten = spi.Write(header, sizeof(header)); + unsigned char buffer[1024] = { 0 }; + int bytesRead = spi.Read(buffer, 1); + if (bytesRead > 0) { + int aa = 0; + } else { + int bb = 0; + } + int len = buffer[0]; + bytesRead += spi.Read(&buffer[1], len); + + spi.Close(); + + std::string result; + char buf[32] = { 0 }; + for (int idx = 0; idx < 32; idx++) + { + sprintf(buf, "%X ", buffer[idx]); + result += buf; + } + + + + return env->NewStringUTF(result.c_str()); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_turnOn( + JNIEnv* env, + jobject /*this*/) { + +} + + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_turnOff( + JNIEnv* env, + jobject /*this*/) { + +} + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_turnLeft( + JNIEnv* env, + jobject /*this*/) { + +} + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_turnRight( + JNIEnv* env, + jobject /*this*/) { + +} + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_turnUp( + JNIEnv* env, + jobject /*this*/) { + +} + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_turnDown( + JNIEnv* env, + jobject /*this*/) { + +} + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_zoomIn( + JNIEnv* env, + jobject /*this*/) { + +} + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_zoomOut( + JNIEnv* env, + jobject /*this*/) { + +} + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_setSpeed( + JNIEnv* env, + jobject /*this*/, jint speed) { + +} + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_setPreset( + JNIEnv* env, + jobject /*this*/, jint preset) { + +} + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_gotoPreset( + JNIEnv* env, + jobject /*this*/, jint preset) { + +} + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_turnOnWipers( + JNIEnv* env, + jobject /*this*/) { + +} + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_turnOffWipers( + JNIEnv* env, + jobject /*this*/) { + +} + + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_turnOnLight( + JNIEnv* env, + jobject /*this*/) { + +} + +extern "C" JNIEXPORT void JNICALL +Java_com_xinyingpower_testcomm_MainActivity_turnOffLight( + JNIEnv* env, + jobject /*this*/) { + +} + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//// lxy add +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#if 0 +static speed_t getBaudrate(jint baudrate) +{ + switch(baudrate) { + case 0: return B0; + case 50: return B50; + case 75: return B75; + case 110: return B110; + case 134: return B134; + case 150: return B150; + case 200: return B200; + case 300: return B300; + case 600: return B600; + case 1200: return B1200; + case 1800: return B1800; + case 2400: return B2400; + case 4800: return B4800; + case 9600: return B9600; + case 19200: return B19200; + case 38400: return B38400; + case 57600: return B57600; + case 115200: return B115200; + case 230400: return B230400; + case 460800: return B460800; + case 500000: return B500000; + case 576000: return B576000; + case 921600: return B921600; + case 1000000: return B1000000; + case 1152000: return B1152000; + case 1500000: return B1500000; + case 2000000: return B2000000; + case 2500000: return B2500000; + case 3000000: return B3000000; + case 3500000: return B3500000; + case 4000000: return B4000000; + default: return -1; + } +} +char* jstring2str(JNIEnv* env, jstring jstr) +{ + char* rtn = NULL; + jclass clsstring = env->FindClass("java/lang/String"); + jstring strencode = env->NewStringUTF("UTF-8"); + jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); + jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr,mid,strencode); + jsize alen = env->GetArrayLength(barr); + jbyte* ba = env->GetByteArrayElements(barr,JNI_FALSE); + + if(alen > 0) + { + rtn = (char*)malloc(alen+1); //new char[alen+1]; + memcpy(rtn,ba,alen); + rtn[alen] = 0; + } + + env->ReleaseByteArrayElements(barr,ba,0); + return (char*)rtn; +} + + +int g_fd = -1; +int serial_open(char *devPath, speed_t baudrate ) { + int ret = 0; + setRS485Enable(true); + int fd = open("/dev/ttyS0", O_RDWR |O_NOCTTY |O_NONBLOCK); + LOGE("_test_ serial_open fd=%d \n",fd); + if(fd < 0) + { + LOGE("_test_ open serial error \n"); + return 0; + } + //ret= set_port_attr (fd, baudrate,8,"1",'N',150,0 );/*9600 8n1 */ + ret= set_port_attr (fd, baudrate,8,"1",'N',150,0 );/*9600 8n1 */ + if(ret < 0) + { + LOGE("_test_ set serial param fail \n"); + return 0; + } + g_fd = fd; + return 1; +} + +void serial_close() +{ + LOGE("_test_ serial_close fd=%d \n",g_fd); + if(g_fd != -1) + { + close(g_fd); + setRS485Enable(false); + } + g_fd = -1; +} + +int serial_write(char *sendbuf, int length) +{ + int len = 0; + if(g_fd < 0) + return 0; + set485WriteMode(); + len = write(g_fd, sendbuf, length);/* 向串囗发送字符串 */ + LOGE("_test_ serial_write len=%d \n",len); + if (len < 0) + { + LOGE("_test_ write data error \n"); + return 0; + } + return len; +} + +int serial_read(char *readbuf,int length) +{ + int len = 0; + if(g_fd < 0) + return 0; + set485ReadMode(); + memset(readbuf, 0, length); + len = read(g_fd, readbuf, length);/* 在串口读取字符串 */ + LOGE("_test_ serial_read len=%d \n",len); + if (len < 0) + { + //LOGE("_test_ read error \n"); + return 0; + } + return len; +} + +extern "C" JNIEXPORT jboolean JNICALL Java_com_xinyingpower_testcomm_MainActivity_openSerial +(JNIEnv* env, jobject, jstring dev, jint baudrate) { + char *devPath = jstring2str(env, dev); + LOGE("_test open serial path=%s, baudrate=%d\n", devPath, baudrate); + speed_t speed = getBaudrate(baudrate); + int res = serial_open(devPath, speed); + return res == 1 ? JNI_TRUE: JNI_FALSE; +} + +extern "C" JNIEXPORT void JNICALL Java_com_xinyingpower_testcomm_MainActivity_closeSerial + (JNIEnv* env, jobject) { + serial_close(); +} + +extern "C" JNIEXPORT jint JNICALL Java_com_xinyingpower_testcomm_MainActivity_writeSerial + (JNIEnv *env, jobject , jbyteArray jstr) { + jsize len = env->GetArrayLength(jstr); + if (len <= 0) + return 0; + jbyte *jdata = env->GetByteArrayElements(jstr, 0); + int res = serial_write((char*)jdata, len); + env->ReleaseByteArrayElements(jstr, jdata, 0); + return res; +} + +extern "C" JNIEXPORT jint JNICALL Java_com_xinyingpower_testcomm_MainActivity_readSerial + (JNIEnv *env, jobject, jbyteArray out) +{ + jsize outlen = env->GetArrayLength(out); + //LOGE("_test readSerial outlen=%d\n", outlen); + if(outlen <= 0) + return 0; + jbyte* outData = env->GetByteArrayElements(out, 0); + char* outbuf = (char*)outData; + int res = serial_read(outbuf, outlen); + //LOGE("_test serial_read res=%d\n", res); + env->ReleaseByteArrayElements(out, outData, 0); + return res; +} +#endif \ No newline at end of file diff --git a/app/src/main/cpp/serialComm.cpp b/app/src/main/cpp/serialComm.cpp new file mode 100644 index 0000000..b300d1c --- /dev/null +++ b/app/src/main/cpp/serialComm.cpp @@ -0,0 +1,116 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GPIOControl.h" +#include "serialComm.h" + + +static void set_baudrate (struct termios *opt, unsigned int baudrate) +{ + cfsetispeed(opt, baudrate); + cfsetospeed(opt, baudrate); +} + +static void set_data_bit (struct termios *opt, unsigned int databit) +{ + opt->c_cflag &= ~CSIZE; + switch (databit) + { + case 8: + opt->c_cflag |= CS8; + break; + case 7: + opt->c_cflag |= CS7; + break; + case 6: + opt->c_cflag |= CS6; + break; + case 5: + opt->c_cflag |= CS5; + break; + default: + opt->c_cflag |= CS8; + break; + } +} + +static void set_parity (struct termios *opt, char parity) +{ + switch (parity) + { + case'N':/* 无校验 */ + case 'n': + opt->c_cflag &= ~PARENB; + break; + case'E':/*偶校验*/ + case 'e': + opt->c_cflag |= PARENB; + opt->c_cflag &= ~PARODD; + break; + case'O':/* 奇校验 */ + case 'o': + opt->c_cflag |= PARENB; + opt->c_cflag |= ~PARODD; + break; + default: /*其它选择为无校验 */ + opt->c_cflag &= ~PARENB; + break; + } +} + +static void set_stopbit (struct termios *opt, const int stopbit) +{ + switch (stopbit) + { + case 10: + opt->c_cflag &= ~CSTOPB;/*1 位停止位 t */ + break; + case 15: + opt->c_cflag &= ~CSTOPB;/*1.5 位停止位 */ + break; + case 20: + opt->c_cflag |= CSTOPB; /*2 位停止位 */ + break; + default: + opt->c_cflag &= ~CSTOPB; /*1 位停止位 */ + break; + } +} + +int set_port_attr (int fd, unsigned int baudrate, int databit, const int stopbit, char parity, int vtime, int vmin ) +{ + struct termios opt; + tcgetattr(fd, &opt); + set_baudrate(&opt, baudrate); + //opt.c_cflag |= CLOCAL|CREAD; /*|CRTSCTS */ + opt.c_lflag &= ~(ICANON | ECHO |ECHOE |ISIG); + set_data_bit(&opt, databit); + set_parity(&opt, parity); + set_stopbit(&opt, stopbit); + opt.c_iflag &=~(INLCR|ICRNL); + opt.c_iflag &=~(IXON);/* 流控*/ + opt.c_oflag = 0; + //opt.c_lflag |= 0; + opt.c_oflag &= ~OPOST; + opt.c_cc[VTIME] = vtime; + opt.c_cc[VMIN] = vmin; + tcflush (fd, TCIFLUSH); + return (tcsetattr (fd, TCSANOW, &opt)); +} + + + + diff --git a/app/src/main/cpp/serialComm.h b/app/src/main/cpp/serialComm.h new file mode 100644 index 0000000..a882522 --- /dev/null +++ b/app/src/main/cpp/serialComm.h @@ -0,0 +1,19 @@ +// +// Created by hyz on 2024/6/5. +// + +#ifndef SERIAL_COMM_BASE89656_H +#define SERIAL_COMM_BASE89656_H + +#include +#include "GPIOControl.h" + +#define MAX_STRING_LEN 32 +#define IOT_PARAM_WRITE 0xAE +#define IOT_PARAM_READ 0xAF + +//#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "serial_port_comm", fmt, ##args) + +int set_port_attr (int fd, unsigned int baudrate, int databit, const int stopbit, char parity, int vtime, int vmin ); + +#endif //SERIAL_COMM_BASE89656_H diff --git a/app/src/main/cpp/spi-test-random.cpp b/app/src/main/cpp/spi-test-random.cpp new file mode 100644 index 0000000..e519010 --- /dev/null +++ b/app/src/main/cpp/spi-test-random.cpp @@ -0,0 +1,426 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define CMD_HEAD_SIZE 5 +typedef unsigned char u8; + +#define RE_SUC 0x01 +#define RE_ERROR 0x00 + +const unsigned char crc7_table[256] = { + 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, + 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, + 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, + 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e, + 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, + 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45, + 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, + 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c, + 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, + 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13, + 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, + 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a, + 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, + 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21, + 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, + 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38, + 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, + 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36, + 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, + 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f, + 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, + 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, + 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, + 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d, + 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, + 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52, + 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, + 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b, + 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, + 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60, + 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, + 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79 +}; + +const unsigned char EK_CMD[5]={0x80,0xd4,0x01,0x00,0x10}; +const unsigned char AK_CMD[5]={0x80,0xd4,0x02,0x00,0x10}; +const unsigned char IV_CMD[5]={0x80,0xd4,0x04,0x00,0x10}; +volatile unsigned char SM1encrpt_CMD[5]={0xa0,0xe0,0x80,0xff,0xff}; +volatile unsigned char SM1decoder_CMD[5]={0xa0,0xe0,0x81,0xff,0xff}; +volatile unsigned char SM2Keypair_CMD[5]={0x80,0xb2,0x00,0xff,0x00}; +volatile unsigned char SM2OutPub_CMD[5]={0x80,0xb8,0x01,0xff,0x40}; +volatile unsigned char SM2OutPri_CMD[5]={0x80,0xb8,0x02,0xff,0x20}; +volatile unsigned char SM2InPub_CMD[5]={0x80,0xba,0x01,0xff,0x40}; +volatile unsigned char SM2InPri_CMD[5]={0x80,0xba,0x02,0xff,0x20}; +volatile unsigned char SM3Hash_CMD[5]={0x80,0xb5,0x00,0xff,0xff}; +volatile unsigned char SM2Sign_CMD[5]={0x80,0xb4,0x00,0xff,0x20}; +volatile unsigned char SM2VerifySign_CMD[5]={0x80,0xb6,0x00,0xff,0x60}; +volatile unsigned char SM2encrypt_CMD[5]={0x80,0xb3,0x01,0xff,0x20}; +volatile unsigned char SM2decoder_CMD[5]={0x80,0xb3,0x81,0xff,0x80}; +volatile unsigned char SM2cert_CMD[5]={0x80,0xb7,0xff,0xff,0xff}; +volatile unsigned char Random_CMD[5]={0x00,0x84,0x00,0x00,0xff}; +const unsigned char Version_CMD[5]={0x00,0x5b,0x00,0x00,0x40}; +const unsigned char Indentify_CMD[5]={0x80,0xb3,0x01,0x04,0x20}; + +int spi_transfer(int fd, unsigned char *txbuf, unsigned char *rxbuf, int bytes) +{ + struct spi_ioc_transfer xfer[2]; + int status; + + memset(xfer, 0, sizeof(xfer)); + + xfer[0].tx_buf = (__u64)txbuf; + xfer[0].rx_buf = (__u64)rxbuf; + xfer[0].len = bytes; + + status = ioctl(fd, SPI_IOC_MESSAGE(1), xfer); + if (status < 0) + { + perror("SPI_IOC_MESSAGE"); + return -1; + } + + return status; + +} + +void spi_master_init(const char *name, int fd) +{ + __u8 mode = 3; + __u8 lsb, bits; + //__u32 speed = 30000000; + __u32 speed = 2000000; + //__u32 speed = 2000000; + //__u32 speed = 33000000; + + // SPI_IOC_WR_MODE + + ioctl(fd, SPI_IOC_WR_MODE, &mode); + ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); + + if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0) + { + perror("SPI rd_mode"); + return; + } + + if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) + { + perror("SPI rd_lsb_fist"); + return; + } + + if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) + { + perror("SPI rd bits_per_word"); + return; + } + + if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) + { + perror("SPI rd max_speed_hz"); + return; + } + + __android_log_print(ANDROID_LOG_INFO, "SPi", "%s: spi mode %d, %d bits %sper word, %d Hz max\n", name, mode, bits, lsb ? "(lsb first) " : "", speed); + //printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n", + // name, mode, bits, lsb ? "(lsb first) " : "", speed); +} + +unsigned char get_crc7(const unsigned char *buff, int len) +{ + unsigned char crc7_accum = 0; + int i; + + for (i=0; i < len; i++) { + crc7_accum = + crc7_table[(crc7_accum << 1) ^ buff[i]]; + } + return crc7_accum; +} + +int delay(int x) +{ + // while (--x); + // std::this_thread::sleep_for(std::chrono::milliseconds(50)); + usleep(50000); + return 0; +} + +void delay_us(int x) +{ + usleep(x); +}; + +void SendCmdHeader(int fd,u8 *cmd, u8 *rxbuf) +{ + int i=0; + int retval; + +#if defined (CONFIG_ATMEL_SPI_DEBUG) + printf("tx %1d bytes: ", CMD_HEAD_SIZE); + for (i = 0; i < CMD_HEAD_SIZE; i++) + { + printf(" %02x", cmd[i]); + } + printf("\n"); +#endif + + /* send five command header */ + for (i=0; i< CMD_HEAD_SIZE; i++) + { + retval = spi_transfer(fd, cmd+i, rxbuf+i, 1); + __android_log_print(ANDROID_LOG_INFO, "SPiCMD", "cmd[%d]=%x,rxbuf[%d]=%x",i,*(cmd+i),i, *(rxbuf+i)); + delay(20); + } + + cmd[0]=0xaa; //for response + +} + +void RcvINS(int fd, u8 *txbuf, u8 *buf, u8 ins) +{ + int retval; + int cnt = 1000; + int count=0; + /* receive ins */ +INS: + txbuf[0] = 0xaa; + delay(20); + while(cnt--) + { + retval = spi_transfer(fd, txbuf, buf, 1); + __android_log_print(ANDROID_LOG_INFO, "SPiINS", "txbuf=%x,buf=%x", *txbuf,*buf); + if(*buf == ins) + { + return; + break; + } + else + goto INS; + } +} + +void RcvLEN(int fd, u8 *txbuf, u8 *buf, u8 len) +{ + + int retval; + /* receive length */ +LEN: + retval = spi_transfer(fd, txbuf, buf, 1); + __android_log_print(ANDROID_LOG_INFO, "SPiLEN", "txbuf=%x,rxbuf=%hhu", *txbuf,*buf); +} + +//Rcvdata +void RcvData(int fd, u8 *txbuf, u8 *buf) +{ + int i; + int retval; + + /* receive data and crc */ + for(i=0; i<*(buf-1); i++) + { + + retval = spi_transfer(fd, txbuf, buf+i, 1); + __android_log_print(ANDROID_LOG_INFO, "SPiDATA", "data[%d]=%x",i, *(buf+i)); + } +} + + +//RcvSW +void RcvSW(int fd, u8 *txbuf, u8 *buf, u8 sw) +{ + int i; + int retval; + +SW90: + /* receive state word */ + delay(20); + while(1) + { + retval = spi_transfer(fd, txbuf, buf, 1); + if(*buf != sw) + { + goto SW90; + } + break; + } + retval = spi_transfer(fd, txbuf, buf+1, 1); +} + + +int testSpi() +{ + int i; + int cnt; + unsigned char txbuf[256]; + unsigned char rxbuf[256]; + + int retval; + int msglen; + int fd; + const char *devname = "/dev/spidevSE"; + + + // NrsecSpiPort spi("/dev/spidevSE"); + // + // // NrsecSpiPort spi("/dev/spidev0.0"); + // devname = "/dev/spidevSE"; + + fd = open(devname, O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + spi_master_init(devname, fd); + + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + printf("tx %1d bytes: ", msglen); + +CMD_RESEND: + txbuf[0] = 0x00; + txbuf[1] = 0x84; + txbuf[2] = 0x00; + txbuf[3] = 0x00; + txbuf[4] = 0x08; + + SendCmdHeader(fd, txbuf, rxbuf); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); // 指令 + + RcvLEN(fd, txbuf,rxbuf+1, txbuf[4]+1); //长度 多加一个字节的 CRC + + RcvData(fd, txbuf, rxbuf+2); + + RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90); + + //计算接收到数据的CRC + if(get_crc7(rxbuf+2, rxbuf[1]-1) != rxbuf[rxbuf[1]+1]) + { + //CRC Error 命令重发,超过3次,结束 + if(cnt<3) + { + cnt++; + goto CMD_RESEND; + printf("cnt over\n"); + } + else + { + printf("ERROR\n"); + } + } + + printf("rx %1d bytes: ", rxbuf[1]+4); + __android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + close(fd); + + std::string result = "Random: "; + char output[16] = { 0 }; + for (i = 0; i < rxbuf[1]+4; i++) { + sprintf(output, " %02x ", rxbuf[i]); + result += output; + } + __android_log_print(ANDROID_LOG_INFO, "SPi", "%s", result.c_str()); + // printf("\n"); + + return 0; +} + +int testVersion() +{ + int i; + int cnt; + unsigned char txbuf[256]; + unsigned char rxbuf[256]; + + int retval; + int msglen; + int fd; + //const char *devname = "/dev/spidevSE"; + //const char *devname = "/dev/spidev0.0"; + const char *devname = "/dev/mtkgpioctrl"; + + // NrsecSpiPort spi("/dev/spidevSE"); + // + // // NrsecSpiPort spi("/dev/spidev0.0"); + + fd = open(devname, O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + spi_master_init(devname, fd); + + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + __android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + + CMD_RESEND: + + memcpy(txbuf, Version_CMD, sizeof(Version_CMD)); + + SendCmdHeader(fd, txbuf, rxbuf); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); // 指令 + + RcvLEN(fd,txbuf,rxbuf+1, txbuf[4]); //长度 多加一个字节的 CRC + + RcvData(fd, txbuf, rxbuf+2); + + RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90); + + //计算接收到数据的CRC + if(get_crc7(rxbuf+2, rxbuf[1]-1) != rxbuf[rxbuf[1]+1]) + { + //CRC Error 命令重发,超过3次,结束 + if(cnt<3) + { + cnt++; + goto CMD_RESEND; + printf("cnt over\n"); + } + else + { + printf("ERROR\n"); + } + } + + //printf("rx %1d bytes: ", rxbuf[1]+4); + __android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + std::string result = "Version: "; + char output[16] = { 0 }; + for (i = 0; i < rxbuf[1]+4; i++) { + sprintf(output, " %c ", rxbuf[i]); + result += output; + } + __android_log_print(ANDROID_LOG_INFO, "SPi", "%s", result.c_str()); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "%s", rxbuf); + // printf("\n"); + + close(fd); + return 0; +} + + diff --git a/app/src/main/cpp/test b/app/src/main/cpp/test new file mode 100644 index 0000000..e69de29 diff --git a/app/src/main/java/com/xinyingpower/testcomm/MainActivity.java b/app/src/main/java/com/xinyingpower/testcomm/MainActivity.java new file mode 100644 index 0000000..a39cecd --- /dev/null +++ b/app/src/main/java/com/xinyingpower/testcomm/MainActivity.java @@ -0,0 +1,149 @@ +package com.xinyingpower.testcomm; + +import androidx.appcompat.app.AppCompatActivity; + +import android.os.Bundle; +import android.os.Handler; +import android.view.View; +import android.widget.TextView; + +import com.xinyingpower.testcomm.databinding.ActivityMainBinding; + +public class MainActivity extends AppCompatActivity { + + // Used to load the 'testcomm' library on application startup. + static { + System.loadLibrary("testcomm"); + } + + private ActivityMainBinding binding; + + View.OnClickListener onButtonClicked = new View.OnClickListener() { + @Override + public void onClick(View view) { + int viewId = view.getId(); + switch (viewId) { + case R.id.turnOn: + turnOn(); + break; + case R.id.turnOff: + turnOff(); + break; + case R.id.turnLeft: + turnLeft(); + break; + case R.id.turnRight: + turnRight(); + break; + case R.id.turnUp: + turnUp(); + break; + case R.id.turnDown: + turnDown(); + break; + case R.id.zoomIn: + zoomIn(); + break; + case R.id.zoomOut: + zoomOut(); + break; + case R.id.turnOnWipers: + turnOnWipers(); + break; + case R.id.turnOffWipers: + turnOffWipers(); + break; + case R.id.turnOnLight: + turnOnLight(); + break; + case R.id.turnOffLight: + turnOffLight(); + break; + case R.id.setSpeed: + { + int speed = 0; + try { + speed = Integer.parseInt(binding.speed.getText().toString()); + } catch (Exception ex) { + + } + setSpeed(speed); + } + break; + case R.id.setPreset: + case R.id.gotoPreset: + { + int preset = 0xFF; + try { + preset = Integer.parseInt(binding.preset.getText().toString()); + } catch (Exception ex) { + + } + if (viewId == R.id.setPreset) { + setPreset(preset); + } else { + gotoPreset(preset); + } + } + break; + } + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + binding = ActivityMainBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + binding.btnSpi.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String s = binding.edtPort.getText().toString(); +// Integer integer = Integer.valueOf(s); + String str = testSpi(0); + } + }); + + Handler handler = new Handler(); + Runnable runnable = new Runnable() { + @Override + public void run() { + binding.btnSpi.performClick(); + } + }; + handler.postDelayed(runnable, 1000); + } + + + /** + * A native method that is implemented by the 'testcomm' native library, + * which is packaged with this application. + */ + public native String stringFromJNI(); + + public native String testSpi(int port); + + public native void turnLeft(); + public native void turnRight(); + public native void turnUp(); + public native void turnDown(); + + public native void turnOn(); + public native void turnOff(); + + public native void zoomIn(); // 拉近 + public native void zoomOut(); // + + public native void setSpeed(int speed); + public native void setPreset(int preset); + public native void gotoPreset(int preset); + + public native void turnOnWipers(); + public native void turnOffWipers(); + + public native void turnOffLight(); + public native void turnOnLight(); + +} \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..d87417f --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,188 @@ + + + +