Initial Commit

main
Matthew 7 months ago
parent c2dbfb51b9
commit cb1c68b59a

1
app/.gitignore vendored

@ -0,0 +1 @@
/build

@ -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'
}

@ -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

@ -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 <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@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());
}
}

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.xinyingpower.testcomm">
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.TestComm"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:screenOrientation="landscape" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

@ -0,0 +1,558 @@
#include <jni.h>
#include <string>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <android/log.h>
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <time.h>
#include "GPIOControl.h"
#include "WeatherComm.h"
#include <sys/time.h>
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, &param);
// 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; (i<datanum) && (j<6+pPortParam->m_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; i<len; i++)
{
switch(pPortParam->m_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;
}

@ -0,0 +1,51 @@
//
// Created by hyz on 2024/6/5.
//
#ifndef WEATHERCOMM_H
#define WEATHERCOMM_H
#include <string>
#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

@ -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})

@ -0,0 +1,144 @@
//
// Created by Matthew on 2023/12/27.
//
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include "GPIOControl.h"
#ifdef _DEBUG
#include <AndroidHelper.h>
#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, &param);
// 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, &param);
#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, &param);
// 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, &param);
// 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, &param);
// 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, &param);
// 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 "";
}

@ -0,0 +1,205 @@
//
// Created by Matthew on 2023/12/27.
//
#ifndef MICROPHOTO_GPIOCONTROL_H
#define MICROPHOTO_GPIOCONTROL_H
#include <string>
#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

File diff suppressed because it is too large Load Diff

@ -0,0 +1,467 @@
//
// Created by hyz on 2024/6/5.
//
#ifndef WEATHERCOMM_H
#define WEATHERCOMM_H
#include <string>
#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

@ -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 <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <jni.h>
#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);
}

@ -0,0 +1,18 @@
#ifndef __SERIALPORT_H__
#define __SERIALPORT_H__
#include <string>
class SerialPort
{
public:
bool Open(std::string path, int, int);
bool Close();
protected:
int m_fd;
};
#endif // __SERIALPORT_H__

File diff suppressed because it is too large Load Diff

@ -0,0 +1,123 @@
#ifndef TESTCOMM_SPILIB_H
#define TESTCOMM_SPILIB_H
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <string>
#include <thread>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <android/log.h>
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

@ -0,0 +1,62 @@
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <android/log.h>
#include <string>
#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;
}

@ -0,0 +1,30 @@
#ifndef _SPIPORT_H_
#define _SPIPORT_H_
#include <string>
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

@ -0,0 +1,595 @@
#include <jni.h>
#include <string>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <android/log.h>
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <time.h>
#include "GPIOControl.h"
#include "WeatherComm.h"
#include <sys/time.h>
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, &param);
// 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; (i<datanum) && (j<6+pPortParam->m_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; i<len; i++)
{
switch(pPortParam->m_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;
}

@ -0,0 +1,51 @@
//
// Created by hyz on 2024/6/5.
//
#ifndef WEATHERCOMM_H
#define WEATHERCOMM_H
#include <string>
#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

File diff suppressed because it is too large Load Diff

@ -0,0 +1,116 @@
#include <jni.h>
#include <string>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <android/log.h>
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <time.h>
#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));
}

@ -0,0 +1,19 @@
//
// Created by hyz on 2024/6/5.
//
#ifndef SERIAL_COMM_BASE89656_H
#define SERIAL_COMM_BASE89656_H
#include <string>
#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

@ -0,0 +1,426 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <string>
#include <thread>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <android/log.h>
#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;
}

@ -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();
}

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

@ -0,0 +1,188 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btnSpi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SPI"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<EditText
android:id="@+id/edtPort"
android:text=""
app:layout_constraintLeft_toRightOf="@id/btnSpi"
app:layout_constraintTop_toTopOf="@+id/btnSpi"
android:layout_marginStart="8dp"
android:layout_width="100dp"
android:layout_height="wrap_content">
</EditText>
<Button
android:id="@+id/turnOn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开电源"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnSpi" />
<Button
android:id="@+id/turnOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="关电源"
app:layout_constraintLeft_toRightOf="@+id/turnOn"
app:layout_constraintTop_toTopOf="@+id/turnOn" />
<Button
android:id="@+id/zoomIn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="拉近"
app:layout_constraintLeft_toRightOf="@+id/turnOff"
app:layout_constraintTop_toTopOf="@+id/turnOn" />
<Button
android:id="@+id/zoomOut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="拉远"
app:layout_constraintLeft_toRightOf="@+id/zoomIn"
app:layout_constraintTop_toTopOf="@+id/turnOn" />
<Button
android:id="@+id/turnLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="左"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/turnOn" />
<Button
android:id="@+id/turnRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="右"
app:layout_constraintLeft_toRightOf="@+id/turnLeft"
app:layout_constraintTop_toTopOf="@+id/turnLeft" />
<Button
android:id="@+id/turnUp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="上"
app:layout_constraintLeft_toRightOf="@+id/turnRight"
app:layout_constraintTop_toTopOf="@+id/turnLeft" />
<Button
android:id="@+id/turnDown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="下"
app:layout_constraintLeft_toRightOf="@+id/turnUp"
app:layout_constraintTop_toTopOf="@+id/turnLeft" />
<Button
android:id="@+id/turnOnWipers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="开雨刮"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/turnLeft" />
<Button
android:id="@+id/turnOffWipers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="关雨刮"
app:layout_constraintLeft_toRightOf="@+id/turnOnWipers"
app:layout_constraintTop_toTopOf="@+id/turnOnWipers" />
<Button
android:id="@+id/turnOnLight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="开补光"
app:layout_constraintLeft_toRightOf="@+id/turnOffWipers"
app:layout_constraintTop_toTopOf="@+id/turnOnWipers" />
<Button
android:id="@+id/turnOffLight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="关补光"
app:layout_constraintLeft_toRightOf="@+id/turnOnLight"
app:layout_constraintTop_toTopOf="@+id/turnOnWipers" />
<EditText
android:id="@+id/speed"
android:text=""
android:hint="转速"
android:layout_width="60dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/turnOnWipers">
</EditText>
<Button
android:id="@+id/setSpeed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:text="设置转速"
app:layout_constraintLeft_toRightOf="@+id/speed"
app:layout_constraintTop_toTopOf="@+id/speed"
/>
<EditText
android:id="@+id/preset"
android:text=""
android:hint="预置位"
android:layout_width="72dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
app:layout_constraintLeft_toRightOf="@+id/setSpeed"
app:layout_constraintTop_toTopOf="@+id/speed">
</EditText>
<Button
android:id="@+id/setPreset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:text="设置预置位"
app:layout_constraintLeft_toRightOf="@+id/preset"
app:layout_constraintTop_toTopOf="@+id/setSpeed"
/>
<Button
android:id="@+id/gotoPreset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="调用预置位"
app:layout_constraintLeft_toRightOf="@+id/setPreset"
app:layout_constraintTop_toTopOf="@+id/setSpeed"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

@ -0,0 +1,16 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.TestComm" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>

@ -0,0 +1,3 @@
<resources>
<string name="app_name">TestComm</string>
</resources>

@ -0,0 +1,16 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.TestComm" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample backup rules file; uncomment and customize as necessary.
See https://developer.android.com/guide/topics/data/autobackup
for details.
Note: This file is ignored for devices older that API 31
See https://developer.android.com/about/versions/12/backup-restore
-->
<full-backup-content>
<!--
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
-->
</full-backup-content>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample data extraction rules file; uncomment and customize as necessary.
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
for details.
-->
<data-extraction-rules>
<cloud-backup>
<!-- TODO: Use <include> and <exclude> to control what is backed up.
<include .../>
<exclude .../>
-->
</cloud-backup>
<!--
<device-transfer>
<include .../>
<exclude .../>
</device-transfer>
-->
</data-extraction-rules>

@ -0,0 +1,17 @@
package com.xinyingpower.testcomm;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}

@ -0,0 +1,9 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.2.2' apply false
id 'com.android.library' version '7.2.2' apply false
}
task clean(type: Delete) {
delete rootProject.buildDir
}

@ -0,0 +1,21 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true

Binary file not shown.

@ -0,0 +1,7 @@
#Tue Apr 02 12:39:24 CST 2024
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.3.3-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

185
gradlew vendored

@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# 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
#
# https://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.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
gradlew.bat vendored

@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

@ -0,0 +1,22 @@
pluginManagement {
repositories {
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
maven { url 'https://maven.aliyun.com/repository/google' }
gradlePluginPortal()
google()
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://maven.aliyun.com/repository/google' }
google()
mavenCentral()
}
}
rootProject.name = "TestComm"
include ':app'
Loading…
Cancel
Save