diff --git a/TestComm/.gitignore b/TestComm/.gitignore new file mode 100644 index 00000000..aa724b77 --- /dev/null +++ b/TestComm/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/TestComm/app/.gitignore b/TestComm/app/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/TestComm/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/TestComm/app/build.gradle b/TestComm/app/build.gradle new file mode 100644 index 00000000..afdc5d40 --- /dev/null +++ b/TestComm/app/build.gradle @@ -0,0 +1,52 @@ +plugins { + id 'com.android.application' +} + +android { + compileSdk 32 + + defaultConfig { + applicationId "com.xinyingpower.testcomm" + minSdk 28 + targetSdk 32 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + externalNativeBuild { + cmake { + cppFlags '-std=c++17' + } + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + externalNativeBuild { + cmake { + path file('src/main/cpp/CMakeLists.txt') + version '3.18.1' + } + } + buildFeatures { + viewBinding true + } +} + +dependencies { + + implementation 'androidx.appcompat:appcompat:1.3.0' + implementation 'com.google.android.material:material:1.4.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' +} \ No newline at end of file diff --git a/TestComm/app/proguard-rules.pro b/TestComm/app/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/TestComm/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/TestComm/app/src/androidTest/java/com/xinyingpower/testcomm/ExampleInstrumentedTest.java b/TestComm/app/src/androidTest/java/com/xinyingpower/testcomm/ExampleInstrumentedTest.java new file mode 100644 index 00000000..44bbb0d8 --- /dev/null +++ b/TestComm/app/src/androidTest/java/com/xinyingpower/testcomm/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.xinyingpower.testcomm; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.xinyingpower.testcomm", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/TestComm/app/src/main/AndroidManifest.xml b/TestComm/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..1c677876 --- /dev/null +++ b/TestComm/app/src/main/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TestComm/app/src/main/cpp/CMakeLists.txt b/TestComm/app/src/main/cpp/CMakeLists.txt new file mode 100644 index 00000000..282af7cc --- /dev/null +++ b/TestComm/app/src/main/cpp/CMakeLists.txt @@ -0,0 +1,56 @@ +# 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) + +# Searches for a specified prebuilt library and stores the path as a +# variable. Because CMake includes system libraries in the search path by +# default, you only need to specify the name of the public NDK library +# you want to add. CMake verifies that the library exists before +# completing its build. + +find_library( # Sets the name of the path variable. + log-lib + + # Specifies the name of the NDK library that + # you want CMake to locate. + + log) + +# Specifies libraries CMake should link to your target library. You +# can link multiple libraries, such as libraries you define in this +# build script, prebuilt third-party libraries, or system libraries. + +target_link_libraries( # Specifies the target library. + testcomm + + android + + # Links the target library to the log library + # included in the NDK. + ${log-lib}) \ No newline at end of file diff --git a/TestComm/app/src/main/cpp/GPIOControl.cpp b/TestComm/app/src/main/cpp/GPIOControl.cpp new file mode 100644 index 00000000..187f7e33 --- /dev/null +++ b/TestComm/app/src/main/cpp/GPIOControl.cpp @@ -0,0 +1,134 @@ +// +// Created by Matthew on 2023/12/27. +// + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "GPIOControl.h" + +#ifdef _DEBUG +#include +#endif + +#define IOT_PARAM_WRITE 0xAE +#define IOT_PARAM_READ 0xAF +#define MAX_STRING_LEN 32 + +typedef struct +{ + int cmd; + int value; + int result; + long value2; + char str[MAX_STRING_LEN]; +}IOT_PARAM; + +void GpioControl::setInt(int cmd, int value) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + IOT_PARAM param; + param.cmd = cmd; + param.value = value; + // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value); + if( fd > 0 ) + { + int res = ioctl(fd, IOT_PARAM_WRITE, ¶m); + // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result); + close(fd); + } + return; +} + +int GpioControl::getInt(int cmd) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + // LOGE("get_int fd=%d,cmd=%d\r\n",fd, cmd); + if( fd > 0 ) + { + IOT_PARAM param; + param.cmd = cmd; + ioctl(fd, IOT_PARAM_READ, ¶m); +#ifdef _DEBUG + ALOGI("getInt cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result); +#endif + close(fd); + return param.value; + } + return -1; +} + +void GpioControl::setLong(int cmd, long value) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + IOT_PARAM param; + param.cmd = cmd; + param.value2 = value; + // LOGE("set_long fd=%d,cmd=%d,value2=%ld\r\n",fd, param.cmd, param.value2); + + if( fd > 0 ) + { + ioctl(fd, IOT_PARAM_WRITE, ¶m); + // LOGE("set_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result); + close(fd); + } +} + +long GpioControl::getLong(int cmd) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + // LOGE("get_long fd=%d,cmd=%d\r\n",fd, cmd); + if( fd > 0 ) + { + IOT_PARAM param; + param.cmd = cmd; + ioctl(fd, IOT_PARAM_READ, ¶m); + // LOGE("get_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result); + close(fd); + return param.value2; + } + return -1; +} + +void GpioControl::setString(int cmd, const std::string& value) +{ + IOT_PARAM param; + // char *pval = jstringToChars(env, value); + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + int len = MAX_STRING_LEN < value.size() ? MAX_STRING_LEN : value.size(); + + param.cmd = cmd; + memset(param.str, 0, MAX_STRING_LEN); + memcpy(param.str, value.c_str(), len); + // LOGE("set_string fd=%d,cmd=%d,str=%s\r\n",fd, param.cmd, param.str); + if( fd > 0 ) + { + ioctl(fd, IOT_PARAM_WRITE, ¶m); + // LOGE("set_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result); + close(fd); + } + return; +} + +std::string GpioControl::getString(int cmd) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + // LOGE("get_string fd=%d,cmd=%d\r\n",fd, cmd); + if( fd > 0 ) + { + IOT_PARAM param; + param.cmd = cmd; + ioctl(fd, IOT_PARAM_READ, ¶m); + // LOGE("get_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result); + close(fd); + return std::string(param.str); + } + return ""; +} diff --git a/TestComm/app/src/main/cpp/GPIOControl.h b/TestComm/app/src/main/cpp/GPIOControl.h new file mode 100644 index 00000000..54a46177 --- /dev/null +++ b/TestComm/app/src/main/cpp/GPIOControl.h @@ -0,0 +1,167 @@ +// +// Created by Matthew on 2023/12/27. +// + +#ifndef MICROPHOTO_GPIOCONTROL_H +#define MICROPHOTO_GPIOCONTROL_H + +#include + +#define CMD_GET_LIGHT_ADC 101 +#define CMD_SET_LIGHT_ADC 102 +#define CMD_GET_KEY_LOCKSTATE 103 +#define CMD_GET_BAT_ADC 104 +#define CMD_SET_FLASH_LED 105 +#define CMD_SET_NETWORK_STATE 106 +#define CMD_SET_OTG_STATE 107 +#define CMD_GET_OTG_STATE 108 +#define CMD_GET_CHARGING_VOL_STATE 110 +#define CMD_GET_CHARGING_SHUNT_VOLTAGE_STATE 111 +#define CMD_GET_CHARGING_BUS_VOLTAGE_STATE 112 +#define CMD_GET_CHARGING_POWER_STATE 113 +#define CMD_GET_CHARGING_CURRENT_STATE 114 +#define CMD_GET_BAT_VOL_STATE 115 +#define CMD_GET_BAT_SHUNT_VOLTAGE_STATE 116 +#define CMD_GET_BAT_BUS_VOLTAGE_STATE 117 +#define CMD_GET_BAT_POWER_STATE 118 +#define CMD_GET_BAT_CURRENT_STATE 119 +#define CMD_SET_485_STATE 121 +#define CMD_SET_SPI_MODE 123 +#define CMD_SET_SPI_BITS_PER_WORD 124 +#define CMD_SET_SPI_MAXSPEEDHZ 125 +#define CMD_SET_PWM_BEE_STATE 126 +#define CMD_SET_ALM_MODE 128 +#define CMD_SET_SPI_POWER 129 +#define CMD_SET_485_EN_STATE 131 +#define CMD_SET_CAM_3V3_EN_STATE 132 +#define CMD_SET_12V_EN_STATE 133 +#define CMD_SET_SYSTEM_RESET 202 + +class GpioControl +{ +public: + + static void setInt(int cmd, int value); + static int getInt(int cmd); + static void setLong(int cmd, long value); + static long getLong(int cmd); + static void setString(int cmd, const std::string& value); + static std::string getString(int cmd); + + static void setOtgState(bool on) + { + setInt(CMD_SET_OTG_STATE, on ? 1 : 0); + } + + static bool getOtgState() + { + return getInt(CMD_SET_OTG_STATE) != 0; + } + + static void setCam3V3Enable(bool enabled) + { + setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0); + } + + static void reboot() + { + setInt(CMD_SET_SYSTEM_RESET, 1); + } + + static void setLightAdc(int i) + { + setInt(CMD_SET_LIGHT_ADC, i); + } + + static int getLightAdc() + { + return getInt(CMD_GET_LIGHT_ADC); + } + + static int getChargingVoltage() + { + return getInt(CMD_GET_CHARGING_VOL_STATE); + } + + static int getChargingShuntVoltage() + { + return getInt(CMD_GET_CHARGING_SHUNT_VOLTAGE_STATE); + } + + static int getChargingBusVoltage() { + return getInt(CMD_GET_CHARGING_BUS_VOLTAGE_STATE); + } + + static int getChargingPower() { + return getInt(CMD_GET_CHARGING_POWER_STATE); + } + + static int getChargingCurrent() { + return getInt(CMD_GET_CHARGING_CURRENT_STATE); + } + + static int getBatteryVoltage() { + return getInt(CMD_GET_BAT_VOL_STATE); + } + + static int getBatteryShuntVoltage() { + return getInt(CMD_GET_BAT_SHUNT_VOLTAGE_STATE); + } + + static int getBatteryBusVoltage() { + return getInt(CMD_GET_BAT_BUS_VOLTAGE_STATE); + } + + static int getBatteryPower() { + return getInt(CMD_GET_BAT_POWER_STATE); + } + + static int getBatteryCurrent() { + return getInt(CMD_GET_BAT_CURRENT_STATE); + } + + static void set485WriteMode() { + setInt(CMD_SET_485_STATE, 1); + } + + static void set485ReadMode() { + setInt(CMD_SET_485_STATE, 0); + } + + static void setSpiMode(int i) { + setInt(CMD_SET_SPI_MODE, i); + } + + static void setSpiBitsPerWord(int i) { + setInt(CMD_SET_SPI_BITS_PER_WORD, i); + } + + static void setSpiMaxSpeedHz(long j) { + setLong(CMD_SET_SPI_MAXSPEEDHZ, j); + } + + static void setBeeOn(bool z) { + setInt(CMD_SET_PWM_BEE_STATE, z ? 1 : 0); + } + + static void setJidianqiState(bool z) { + setInt(CMD_SET_ALM_MODE, z ? 1 : 0); + } + + static void setSpiPower(bool on) { + setInt(CMD_SET_SPI_POWER, on ? 1 : 0); + } + + static void setRS485Enable(bool z) { + setInt(CMD_SET_485_EN_STATE, z ? 1 : 0); + } + + + static void set12VEnable(bool z) { + setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0); + } + +}; + + +#endif //MICROPHOTO_GPIOCONTROL_H diff --git a/TestComm/app/src/main/cpp/SerialPort.cpp b/TestComm/app/src/main/cpp/SerialPort.cpp new file mode 100644 index 00000000..e035c8da --- /dev/null +++ b/TestComm/app/src/main/cpp/SerialPort.cpp @@ -0,0 +1,142 @@ +/* + * Copyright 2009-2011 Cedric Priscal + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "SerialPort.h" + +#include "android/log.h" +static const char *TAG="serial_port"; +#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##args) +#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args) +#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args) + +static speed_t getBaudrate(int baudrate) +{ + switch(baudrate) { + case 0: return B0; + case 50: return B50; + case 75: return B75; + case 110: return B110; + case 134: return B134; + case 150: return B150; + case 200: return B200; + case 300: return B300; + case 600: return B600; + case 1200: return B1200; + case 1800: return B1800; + case 2400: return B2400; + case 4800: return B4800; + case 9600: return B9600; + case 19200: return B19200; + case 38400: return B38400; + case 57600: return B57600; + case 115200: return B115200; + case 230400: return B230400; + case 460800: return B460800; + case 500000: return B500000; + case 576000: return B576000; + case 921600: return B921600; + case 1000000: return B1000000; + case 1152000: return B1152000; + case 1500000: return B1500000; + case 2000000: return B2000000; + case 2500000: return B2500000; + case 3000000: return B3000000; + case 3500000: return B3500000; + case 4000000: return B4000000; + default: return -1; + } +} + +/* + * Class: android_serialport_SerialPort + * Method: open + * Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor; + */ +bool SerialPort::Open(std::string path, int baudrate, int flags) +{ + speed_t speed; + + /* Check arguments */ + { + speed = getBaudrate(baudrate); + if (speed == -1) { + /* TODO: throw an exception */ + LOGE("Invalid baudrate"); + return false; + } + } + + /* Opening device */ + { + + m_fd = open(path.c_str(), O_RDWR | flags); + LOGD("open() m_fd = %d", m_fd); + if (m_fd == -1) + { + /* Throw an exception */ + LOGE("Cannot open port"); + /* TODO: throw an exception */ + return false; + } + } + + /* Configure device */ + { + struct termios cfg; + LOGD("Configuring serial port"); + if (tcgetattr(m_fd, &cfg)) + { + LOGE("tcgetattr() failed"); + close(m_fd); + /* TODO: throw an exception */ + return false; + } + + cfmakeraw(&cfg); + cfsetispeed(&cfg, speed); + cfsetospeed(&cfg, speed); + + if (tcsetattr(m_fd, TCSANOW, &cfg)) + { + LOGE("tcsetattr() failed"); + close(m_fd); + /* TODO: throw an exception */ + return false; + } + } + + return true; +} + +/* + * Class: cedric_serial_SerialPort + * Method: close + * Signature: ()V + */ +bool SerialPort::Close() +{ + LOGD("close(m_fd = %d)", m_fd); + close(m_fd); +} + diff --git a/TestComm/app/src/main/cpp/SerialPort.h b/TestComm/app/src/main/cpp/SerialPort.h new file mode 100644 index 00000000..28f603af --- /dev/null +++ b/TestComm/app/src/main/cpp/SerialPort.h @@ -0,0 +1,18 @@ +#ifndef __SERIALPORT_H__ +#define __SERIALPORT_H__ + +#include + +class SerialPort +{ +public: + + bool Open(std::string path, int, int); + + bool Close(); + +protected: + int m_fd; +}; + +#endif // __SERIALPORT_H__ diff --git a/TestComm/app/src/main/cpp/SpiLib.cpp b/TestComm/app/src/main/cpp/SpiLib.cpp new file mode 100644 index 00000000..1934b923 --- /dev/null +++ b/TestComm/app/src/main/cpp/SpiLib.cpp @@ -0,0 +1,1290 @@ +#include "SpiLib.h" + +//typedef unsigned char u8; + +#define RE_SUC 0x01 +#define RE_ERROR 0x00 + + + +int SpiLIb::spi_transfer(int fd, unsigned char *txbuf, unsigned char *rxbuf, int bytes) +{ + struct spi_ioc_transfer xfer[2]; + int status; + + memset(xfer, 0, sizeof(xfer)); + + xfer[0].tx_buf = (__u64)txbuf; + xfer[0].rx_buf = (__u64)rxbuf; + xfer[0].len = bytes; + + status = ioctl(fd, SPI_IOC_MESSAGE(1), xfer); + if (status < 0) + { + perror("SPI_IOC_MESSAGE"); + return -1; + } + + return status; + +} + +void SpiLIb::spi_master_init(const char *name, int fd) +{ + __u8 mode = 3; + __u8 lsb, bits; + //__u32 speed = 30000000; + __u32 speed = 2000000; + //__u32 speed = 2000000; + //__u32 speed = 33000000; + + // SPI_IOC_WR_MODE + + ioctl(fd, SPI_IOC_WR_MODE, &mode); + ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); + + if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0) + { + perror("SPI rd_mode"); + return; + } + + if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) + { + perror("SPI rd_lsb_fist"); + return; + } + + if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) + { + perror("SPI rd bits_per_word"); + return; + } + + if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) + { + perror("SPI rd max_speed_hz"); + return; + } + + __android_log_print(ANDROID_LOG_INFO, "SPi", "%s: spi mode %d, %d bits %sper word, %d Hz max\n", name, mode, bits, lsb ? "(lsb first) " : "", speed); + //printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n", + // name, mode, bits, lsb ? "(lsb first) " : "", speed); +} + +unsigned char SpiLIb::get_crc7(const unsigned char *buff, int len) +{ + unsigned char crc7_accum = 0; + int i; + + for (i=0; i < len; i++) { + crc7_accum = + crc7_table[(crc7_accum << 1) ^ buff[i]]; + } + return crc7_accum; +} + +int SpiLIb::delay(int x) +{ + // while (--x); + // std::this_thread::sleep_for(std::chrono::milliseconds(50)); + usleep(50000); + return 0; +} + + +void SpiLIb::SendCmdHeader(int fd,u8 *cmd, u8 *rxbuf) +{ + int i=0; + int retval; + +#if defined (CONFIG_ATMEL_SPI_DEBUG) + printf("tx %1d bytes: ", CMD_HEAD_SIZE); + for (i = 0; i < CMD_HEAD_SIZE; i++) + { + printf(" %02x", cmd[i]); + } + printf("\n"); +#endif + + /* send five command header */ + for (i=0; i< CMD_HEAD_SIZE; i++) + { + retval = spi_transfer(fd, cmd+i, rxbuf+i, 1); + __android_log_print(ANDROID_LOG_INFO, "SPiCMD", "cmd[%d]=%x,rxbuf[%d]=%x",i,*(cmd+i),i, *(rxbuf+i)); + delay(20); + } + + cmd[0]=0xaa; //for response + +} + +void SpiLIb::RcvINS(int fd, u8 *txbuf, u8 *buf, u8 ins) +{ + int retval; + int cnt = 1000; + int count=0; + /* receive ins */ + INS: + txbuf[0] = 0xaa; + delay(20); + while(cnt--) + { + retval = spi_transfer(fd, txbuf, buf, 1); + __android_log_print(ANDROID_LOG_INFO, "SPiINS", "txbuf=%x,buf=%x", *txbuf,*buf); + if(*buf == ins) + { + return; + break; + } + else + goto INS; + } +} + +void SpiLIb::RcvLEN(int fd, u8 *txbuf, u8 *buf, u8 len) +{ + + int retval; + /* receive length */ + LEN: + for(int i=0;i>= 8; + memset(Z, entl & 0xFF, 1); + memcpy(Z + 2, pucID, idl); + memcpy(Z + 2 + idl, abxy, 32 *4); + memcpy(Z + 2 + idl + 4 * 32, pubkey, 32); + memcpy(Z + 2 + idl + 5 * 32, pubkey+32, 32); + nRet = SM3Hash(Z,l,tmpm); + if (nRet != 0) + goto quit; + free(Z); + l = inl + 32; + Z = (unsigned char *)malloc(l); + if (!Z) { + nRet = -1; + goto quit; + } + memcpy(Z,tmpm,32); + memcpy(Z+32, in, inl); + nRet = SM3Hash(Z,l,out); + quit: + if (Z) + free(Z); + return nRet; +}//用于签名的处理哈希值,用户标识01*16 + +int SpiLIb::SM2Sign(int index,const unsigned char *to_sign,unsigned char *out_sign)//SM2签名 所使用的哈希值应该来源于sm3hash_tosm2 +{ + int i; + int cnt; + unsigned char txbuf[256]; + unsigned char rxbuf[256]; + + int retval; + int msglen; + int fd; + const char *devname = "/dev/spidevSE"; + //const char *devname = "/dev/spidev0.0"; + //const char *devname = "/dev/mtkgpioctrl"; + + // NrsecSpiPort spi("/dev/spidevSE"); + // + // // NrsecSpiPort spi("/dev/spidev0.0") + fd = open(devname, O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + spi_master_init(devname, fd); + + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + SM2Sign_CMD[3]=index; + + CMD_RESEND: + + memcpy(txbuf, (const void *) SM2Sign_CMD, sizeof(SM2Sign_CMD)); + + SendCmdHeader(fd, txbuf, rxbuf); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); + + SendId(fd,txbuf,rxbuf, 0x55); + + memcpy(txbuf, to_sign, 32); + + SendData(fd, txbuf, rxbuf,32); + + SendEnd(fd,txbuf,rxbuf); + + memcpy(txbuf, (const void *) SM2Sign_CMD, sizeof(SM2Sign_CMD)); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); + + RcvLEN(fd,txbuf,rxbuf+1, 1); + + RcvData(fd, txbuf, rxbuf+2); + + RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90); + + __android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + for (i = 2; i < rxbuf[1]+2; i++) { + //sprintf(output, " %02x ", rxbuf[i]); + out_sign[i-2]= rxbuf[i]; + } + + close(fd); + return 0; +} + +int SpiLIb::SM2VerifySign(int index, unsigned char *hash,unsigned char *vs)//SM2验签 +{ + unsigned char txbuf[256]; + unsigned char rxbuf[256]; + + int retval; + int msglen; + int fd; + const char *devname = "/dev/spidevSE"; + //const char *devname = "/dev/spidev0.0"; + //const char *devname = "/dev/mtkgpioctrl"; + + // NrsecSpiPort spi("/dev/spidevSE"); + // + // // NrsecSpiPort spi("/dev/spidev0.0") + fd = open(devname, O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + spi_master_init(devname, fd); + + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + SM2VerifySign_CMD[3]=index; + + CMD_RESEND: + + memcpy(txbuf, (const void *) SM2VerifySign_CMD, sizeof(SM2VerifySign_CMD)); + + SendCmdHeader(fd, txbuf, rxbuf); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); + + SendId(fd,txbuf,rxbuf, 0x55); + + memcpy(txbuf, hash, 32); + memcpy(txbuf+32,vs,64); + + SendData(fd, txbuf, rxbuf,96); + + SendEnd(fd,txbuf,rxbuf); + + RcvSW(fd, txbuf, rxbuf, 0x90); + + __android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + + + close(fd); + return 0; +} + +int SpiLIb::SM2encrypt(int index,unsigned char *to_encrypt ,unsigned char *out_encrypt)//加密 +{ + int i; + int cnt; + unsigned char txbuf[512]; + unsigned char rxbuf[512]; + + int retval; + int msglen; + int fd; + const char *devname = "/dev/spidevSE"; + //const char *devname = "/dev/spidev0.0"; + //const char *devname = "/dev/mtkgpioctrl"; + + // NrsecSpiPort spi("/dev/spidevSE"); + // + // // NrsecSpiPort spi("/dev/spidev0.0") + fd = open(devname, O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + spi_master_init(devname, fd); + + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + SM2encrypt_CMD[3]=index; + + CMD_RESEND: + + memcpy(txbuf, (const void *) SM2encrypt_CMD, sizeof(SM2encrypt_CMD)); + + SendCmdHeader(fd, txbuf, rxbuf); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); + + SendId(fd,txbuf,rxbuf, 0x55); + + memcpy(txbuf, to_encrypt, 32); + + SendData(fd, txbuf, rxbuf,32); + + SendEnd(fd,txbuf,rxbuf); + + memcpy(txbuf, (const void *) SM2encrypt_CMD, sizeof(SM2encrypt_CMD)); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); + + RcvLEN(fd,txbuf,rxbuf+1, 1); + + RcvData(fd, txbuf, rxbuf+2); + + RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90); + + //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + for (i = 2; i < rxbuf[1]+2; i++) { + //sprintf(output, " %02x ", rxbuf[i]); + out_encrypt[i-2]= rxbuf[i]; + } + + close(fd); + return 0; +} +int SpiLIb::SM2decoder(int index,unsigned char *to_decoder ,unsigned char *out_decoder)//解密 +{ + int i; + int cnt; + unsigned char txbuf[512]; + unsigned char rxbuf[512]; + + int retval; + int msglen; + int fd; + const char *devname = "/dev/spidevSE"; + //const char *devname = "/dev/spidev0.0"; + //const char *devname = "/dev/mtkgpioctrl"; + + // NrsecSpiPort spi("/dev/spidevSE"); + // + // // NrsecSpiPort spi("/dev/spidev0.0") + fd = open(devname, O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + spi_master_init(devname, fd); + + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + SM2decoder_CMD[3]=index; + + CMD_RESEND: + + memcpy(txbuf, (const void *) SM2decoder_CMD, sizeof(SM2decoder_CMD)); + + SendCmdHeader(fd, txbuf, rxbuf); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); + + SendId(fd,txbuf,rxbuf, 0x55); + + memcpy(txbuf, to_decoder, 128); + + SendData(fd, txbuf, rxbuf,128); + + SendEnd(fd,txbuf,rxbuf); + + memcpy(txbuf, (const void *) SM2decoder_CMD, sizeof(SM2decoder_CMD)); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); + + RcvLEN(fd,txbuf,rxbuf+1, 1); + + RcvData(fd, txbuf, rxbuf+2); + + RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90); + + //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + for (i = 2; i < rxbuf[1]+2; i++) { + //sprintf(output, " %02x ", rxbuf[i]); + out_decoder[i-2]= rxbuf[i]; + } + + close(fd); + return 0; +} + +int SpiLIb::SM2cert(int type,int index,string cert,unsigned char *out_cert)//证书 +{ + int i; + int cnt; + unsigned char txbuf[512]; + unsigned char rxbuf[1024]; + + int retval; + int msglen; + int fd; + const char *devname = "/dev/spidevSE"; + //const char *devname = "/dev/spidev0.0"; + //const char *devname = "/dev/mtkgpioctrl"; + + // NrsecSpiPort spi("/dev/spidevSE"); + // + // // NrsecSpiPort spi("/dev/spidev0.0") + fd = open(devname, O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + spi_master_init(devname, fd); + + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + + int certlen=cert.length(); + unsigned char to_cert[certlen]; + for(int x=0;x +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +using namespace std; + +#define CMD_HEAD_SIZE 5 +using namespace std; +typedef unsigned char u8; + +class SpiLIb{ +public: + int Spirandom(); + int Version(); + int Indentify(unsigned char *to_idt,unsigned char *out_idt); + int SM2keypair(int index); + int SM2OutPub(int index,unsigned char result[]); + int SM2OutPri(int index,unsigned char result[]); + int SM2InPub(int index,const unsigned char new_key[]); + int SM2InPri(int index,const unsigned char new_key[]); + int SM3Hash(unsigned char *to_hash ,int len,unsigned char *out_hash); + int sm3hash_tosm2(unsigned char *in,int inl,unsigned char *out, unsigned char *pubkey, unsigned char + *pucID, int idl); + int SM2Sign(int index,const unsigned char *to_sign,unsigned char *out_sign); + int SM2VerifySign(int index,unsigned char *hash,unsigned char *vs); + int SM2encrypt(int index,unsigned char *to_encrypt ,unsigned char *out_encrypt); + int SM2decoder(int index,unsigned char *to_decoder ,unsigned char *out_decoder); + int SM2cert(int type,int index,string cert,unsigned char *out_cert); + + + + +private: + const unsigned char crc7_table[256]= { + 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, + 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, + 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, + 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e, + 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, + 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45, + 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, + 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c, + 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, + 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13, + 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, + 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a, + 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, + 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21, + 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, + 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38, + 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, + 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36, + 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, + 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f, + 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, + 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, + 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, + 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d, + 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, + 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52, + 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, + 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b, + 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, + 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60, + 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, + 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79 + }; + const unsigned char EK_CMD[5]={0x80,0xd4,0x01,0x00,0x10}; + const unsigned char AK_CMD[5]={0x80,0xd4,0x02,0x00,0x10}; + const unsigned char IV_CMD[5]={0x80,0xd4,0x04,0x00,0x10}; + volatile unsigned char SM1encrpt_CMD[5]={0xa0,0xe0,0x80,0xff,0xff}; + volatile unsigned char SM1decoder_CMD[5]={0xa0,0xe0,0x81,0xff,0xff}; + volatile unsigned char SM2Keypair_CMD[5]={0x80,0xb2,0x00,0xff,0x00}; + volatile unsigned char SM2OutPub_CMD[5]={0x80,0xb8,0x01,0xff,0x40}; + volatile unsigned char SM2OutPri_CMD[5]={0x80,0xb8,0x02,0xff,0x20}; + volatile unsigned char SM2InPub_CMD[5]={0x80,0xba,0x01,0xff,0x40}; + volatile unsigned char SM2InPri_CMD[5]={0x80,0xba,0x02,0xff,0x20}; + volatile unsigned char SM3Hash_CMD[5]={0x80,0xb5,0x00,0xff,0xff}; + volatile unsigned char SM2Sign_CMD[5]={0x80,0xb4,0x00,0xff,0x20}; + volatile unsigned char SM2VerifySign_CMD[5]={0x80,0xb6,0x00,0xff,0x60}; + volatile unsigned char SM2encrypt_CMD[5]={0x80,0xb3,0x01,0xff,0x20}; + volatile unsigned char SM2decoder_CMD[5]={0x80,0xb3,0x81,0xff,0x80}; + volatile unsigned char SM2cert_CMD[5]={0x80,0xb7,0xff,0xff,0xff}; + volatile unsigned char Random_CMD[5]={0x00,0x84,0x00,0x00,0xff}; + const unsigned char Version_CMD[5]={0x00,0x5b,0x00,0x00,0x40}; + const unsigned char Indentify_CMD[5]={0x80,0xb3,0x01,0x04,0x20}; + + int spi_transfer(int fd, unsigned char *txbuf, unsigned char *rxbuf, int bytes); + void spi_master_init(const char *name, int fd); + unsigned char get_crc7(const unsigned char *buff, int len); + void SendCmdHeader(int fd,u8 *cmd, u8 *rxbuf); + int delay(int x); + void RcvINS(int fd, u8 *txbuf, u8 *buf, u8 ins); + void RcvLEN(int fd, u8 *txbuf, u8 *buf, u8 len); + void RcvData(int fd, u8 *txbuf, u8 *buf); + void RcvData(int fd, u8 *txbuf, u8 *buf, int len); + void RcvSW(int fd, u8 *txbuf, u8 *buf, u8 sw); + void SendEnd(int fd, u8 *txbuf, u8 *buf); + void SendId(int fd, u8 *txbuf, u8 *buf, u8 id); + void SendData(int fd,u8 *data, u8 *rxbuf,int data_size); + + + +}; + + + + +#endif //TESTCOMM_SPILIB_H diff --git a/TestComm/app/src/main/cpp/SpiPort.cpp b/TestComm/app/src/main/cpp/SpiPort.cpp new file mode 100644 index 00000000..44e1afb9 --- /dev/null +++ b/TestComm/app/src/main/cpp/SpiPort.cpp @@ -0,0 +1,62 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SpiPort.h" + +SpiPort::SpiPort(const std::string& path) : m_path(path), m_fd(0) +{ +} + +SpiPort::~SpiPort() +{ + if (m_fd > 0) + { + close(m_fd); + } +} + +bool SpiPort::Open() +{ + if(m_fd <= 0) m_fd = open(m_path.c_str(), O_RDWR/*|O_NDELAY|O_NOCTTY*/); + if(m_fd <= 0 ) { + int err = errno; + m_log = "open spi Error errno=" + std::to_string(err); + __android_log_print(ANDROID_LOG_INFO, "SPi", "open spi Error errno=%d", err); + return false; + } + else __android_log_print(ANDROID_LOG_INFO, "SPi", "open spi Success m_fd=%d",m_fd); + + return true; +} + +// write +int SpiPort::Write(unsigned char *buf, int len) +{ + return write(m_fd, buf, len); +} + +// read +int SpiPort::Read(unsigned char *buf, int len) +{ + return read(m_fd, buf, len); +} + +//close +bool SpiPort::Close() +{ + if(m_fd > 0) + { + close(m_fd); + m_fd = 0; + } + + return true; +} \ No newline at end of file diff --git a/TestComm/app/src/main/cpp/SpiPort.h b/TestComm/app/src/main/cpp/SpiPort.h new file mode 100644 index 00000000..a4d82697 --- /dev/null +++ b/TestComm/app/src/main/cpp/SpiPort.h @@ -0,0 +1,30 @@ +#ifndef _SPIPORT_H_ +#define _SPIPORT_H_ + +#include + +class SpiPort +{ +public: + + SpiPort(const std::string& path); + ~SpiPort(); + + bool Open(); + int Write(unsigned char *buf, int len); + int Read(unsigned char *buf, int len); + + bool Close(); + + std::string GetLog() const + { + return m_log; + } + +protected: + std::string m_path; + std::string m_log; + int m_fd; +}; + +#endif \ No newline at end of file diff --git a/TestComm/app/src/main/cpp/native-lib.cpp b/TestComm/app/src/main/cpp/native-lib.cpp new file mode 100644 index 00000000..9d693290 --- /dev/null +++ b/TestComm/app/src/main/cpp/native-lib.cpp @@ -0,0 +1,604 @@ +#include +#include + +#include "SpiPort.h" +#include "SpiLib.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GPIOControl.h" + +#if 0 +int main() { + int fd; + struct termios options; + char *serialPort = "/dev/ttyS0"; // 串口设备文件路径 + char *message = "Hello, serial port!\n"; + int messageLength = strlen(message); + char buffer[50]; + int bytesRead; + + // 打开串口设备 + fd = open(serialPort, O_RDWR | O_NOCTTY | O_NDELAY); + if (fd == -1) { + perror("open_port: Unable to open serial port - "); + return(-1); + } + + // 获取并配置串口选项 + tcgetattr(fd, &options); + cfsetispeed(&options, B9600); // 输入波特率 + cfsetospeed(&options, B9600); // 输出波特率 + options.c_cflag |= (CLOCAL | CREAD); // 开启接收 + options.c_cflag &= ~CSIZE; // 清除当前数据位设置 + options.c_cflag |= CS8; // 8位数据位 + options.c_cflag &= ~PARENB; // 关闭校验位 + options.c_cflag &= ~CSTOPB; // 1位停止位 + options.c_cc[VTIME] = 0; // 非阻塞读取 + options.c_cc[VMIN] = 10; // 读取字符的最小数目 + tcflush(fd, TCIFLUSH); // 清空输入缓冲区 + + // 使用配置好的选项 + tcsetattr(fd, TCSANOW, &options); + + // 写入数据到串口 + write(fd, message, messageLength); + + // 从串口读取数据 + bytesRead = read(fd, buffer, sizeof(buffer)); + if (bytesRead > 0) { + buffer[bytesRead] = '\0'; // 确保字符串以null结尾 + printf("Response from serial port: %s\n", buffer); + } + + // 关闭串口 + close(fd); + + return 0; +} +#endif + +class NrsecSpiPort : public SpiPort { +public: + NrsecSpiPort(const std::string& path) : SpiPort(path) { + + } + + bool Open() + { + if (!SpiPort::Open()) + { + return false; + } + + uint8_t mode = SPI_MODE_3; + uint8_t bits = 8; + uint32_t speed = 33000000; + uint8_t lsb = 1; + // const char *device = "/dev/spidev32766.1"; + + if (ioctl(m_fd, SPI_IOC_WR_MODE, &mode) == -1 || + ioctl(m_fd, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1 || + ioctl(m_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1 || + ioctl(m_fd, SPI_IOC_WR_LSB_FIRST, &lsb) == -1) + { + Close(); + return false; + } + + return true; + } + bool GenKeyPair(int keyIdx) { + unsigned char header[] = {0x80, 0xb2, 0x00, (unsigned char)keyIdx, 0x00 }; + + int bytesWriten = Write(header, sizeof(header)); + unsigned char buffer[2] = { 0 }; + int bytesRead = Read(buffer, sizeof(buffer)); + if (bytesRead > 0) { + int aa = 0; + } else { + int bb = 0; + } + + return true; + } +}; + +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 */ + set_data_bit(&opt, databit); + set_parity(&opt, parity); + set_stopbit(&opt, stopbit); + opt.c_oflag = 0; + opt.c_lflag |= 0; + opt.c_oflag &= ~OPOST; + opt.c_cc[VTIME] = vtime; + opt.c_cc[VMIN] = vmin; + tcflush (fd, TCIFLUSH); + return (tcsetattr (fd, TCSANOW, &opt)); +} +#define MAX_STRING_LEN 32 +#define IOT_PARAM_WRITE 0xAE +#define IOT_PARAM_READ 0xAF + +typedef struct +{ + int cmd; + int value; + int result; + long value2; + char str[MAX_STRING_LEN]; +}IOT_PARAM; + +#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "_test_", fmt, ##args) + +void setInt(int cmd, int value) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + IOT_PARAM param; + param.cmd = cmd; + param.value = value; + // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value); + if( fd > 0 ) + { + int res = ioctl(fd, IOT_PARAM_WRITE, ¶m); + // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result); + close(fd); + } + return; +} +static void setRS485Enable(bool z) { + setInt(CMD_SET_485_EN_STATE, z ? 1 : 0); +} + +static void set485WriteMode() { + setInt(CMD_SET_485_STATE, 1); +} + +static void set485ReadMode() { + setInt(CMD_SET_485_STATE, 0); +} +static void set12VEnable(bool z) { + setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0); +} + +int serial_port_comm() +{ + int fd; + int len, i,ret; + unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0xFF,0x02,0x01,0x16, 0x0D,0x0A}; + char recvbuf[256]; + char serial_description[] = "/dev/ttyS0"; + + 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); + + //fd = open(serial_description, O_RDWR | O_NDELAY); + fd = open(serial_description, O_RDWR | O_NOCTTY); + if(fd < 0) + { + LOGE("_test_ open serial error \n"); + perror(serial_description); + return -1; + } + ret= set_port_attr (fd, B9600,8,"1",'N',150,0 );/*9600 8n1 */ + if(ret < 0) + { + LOGE("_test_ set uart arrt faile \n"); + exit(-1); + } + set485WriteMode(); + len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */ + if (len < 0) + { + LOGE("_test_ write data error \n"); + return -1; + } + set485ReadMode(); + memset(recvbuf, 0, sizeof(recvbuf)); + len = read(fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */ + if (len < 0) + { + LOGE("_test_ read error \n"); + return -1; + } + LOGE("_test_ recv=%s \n", recvbuf); /* 打印在串口读取的字符串 */ + //lxy modify + close(fd); + return(0); +} + +extern "C" JNIEXPORT jstring JNICALL +Java_com_xinyingpower_testcomm_MainActivity_stringFromJNI( + JNIEnv* env, + jobject /* this */) { + std::string hello = "Hello from C++"; + return env->NewStringUTF(hello.c_str()); +} + +extern "C" JNIEXPORT jstring JNICALL +Java_com_xinyingpower_testcomm_MainActivity_testSpi( + JNIEnv* env, + jobject /* this */, jint port) { + //testSpi(); + SpiLIb a; + unsigned char newkey[32]={0xaf,0x0c,0xa9,0x40,0x1f,0xe6,0xee,0x0f,0x4c, + 0xfb,0xf7,0x17,0x71,0xde,0x61,0x59 + ,0x0a,0x05,0x77, + 0xfa,0xe7,0xd1,0x8d,0x10,0x3a,0x79,0x23,0xf2,0xb3, + 0x6d,0xea,0x8e +// ,0xe0,0x64,0xe7,0x5d,0x49,0x84,0xe4, +// 0x5f,0xc9,0x07,0x03,0x52,0x33,0x79,0x87,0xd4,0x62, +// 0x62,0xc0,0xcc,0xf0,0xd6,0x85,0x20,0x7f,0x7a,0xe8, +// 0xc8,0xed,0x12,0xdb,0xdc + }; + unsigned char outpub[32],outsign[64], *outen = new unsigned char [256]; + unsigned char pucid[16]={0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}; + string b="C=CN,ST=jiangsu,L=nanjing,O=GDD,OU=nari,CN=test001"; + //a.SM2keypair(0x00); + //a.SM3Hash(newkey,16, outpub); + //a.sm3hash_tosm2(newkey,16,outpub,newkey,pucid,16); + //a.SM2Sign(0x00,outpub,outsign); + //a.SM2VerifySign(0x00,outpub,outsign); + + //lxy modify modify + LOGE("_test_ setRS485Enable true"); + setRS485Enable(true); + + set12VEnable(true); + serial_port_comm(); + + //lxy modify modify + LOGE("_test_ setRS485Enable false"); + setRS485Enable(false); + return env->NewStringUTF(""); + +#if 0 + DIR *dir = opendir("/dev"); + if (dir == NULL) { + perror("opendir"); + //return env->NewStringUTF("error"); + //return -1; + } + + // 读取目录项 + struct dirent *entry; + while ((entry = readdir(dir)) != NULL) { + // 过滤出串口设备,通常以"ttyS"或"ttyUSB"开头 + if ((strncmp(entry->d_name, "ttyS2", 5) == 0) || + (strncmp(entry->d_name, "ttyS0", 5) == 0)) { + printf("Found serial port: %s\n", entry->d_name); + } + } + + // 关闭目录 + closedir(dir); +#endif + a.SM2cert(0x00,0x00,b,outen); + for (int i = 0; i < 32; i++) { + //sprintf(output, " %02x ", rxbuf[i]); + __android_log_print(ANDROID_LOG_INFO, "SPi", "%02x", outen[i]); + } +// a.SM2decoder(0x00,outen,outpub); +// +// for (int i = 0; i < 64; i++) { +// //sprintf(output, " %02x ", rxbuf[i]); +// __android_log_print(ANDROID_LOG_INFO, "SPi", "%02x", outpub[i]); +// } + + //a.SM3Hash(0x00,0x10,newkey); + //testVersion(); + + return env->NewStringUTF("End"); + + // NrsecSpiPort spi("/dev/mtkgpioctrl"); + NrsecSpiPort spi("/dev/spidevSE"); + + // NrsecSpiPort spi("/dev/spidev0.0"); + + if (!spi.Open()) { + return env->NewStringUTF(spi.GetLog().c_str()); + } + + spi.GenKeyPair(0); + + unsigned char header[] = { 0x00, 0x5b, 0x00, 0x00, 0x40 }; + + int bytesWriten = spi.Write(header, sizeof(header)); + unsigned char buffer[1024] = { 0 }; + int bytesRead = spi.Read(buffer, 1); + if (bytesRead > 0) { + int aa = 0; + } else { + int bb = 0; + } + int len = buffer[0]; + bytesRead += spi.Read(&buffer[1], len); + + spi.Close(); + + std::string result; + char buf[32] = { 0 }; + for (int idx = 0; idx < 32; idx++) + { + sprintf(buf, "%X ", buffer[idx]); + result += buf; + } + + + + return env->NewStringUTF(result.c_str()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//// lxy add +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static speed_t getBaudrate(jint baudrate) +{ + switch(baudrate) { + case 0: return B0; + case 50: return B50; + case 75: return B75; + case 110: return B110; + case 134: return B134; + case 150: return B150; + case 200: return B200; + case 300: return B300; + case 600: return B600; + case 1200: return B1200; + case 1800: return B1800; + case 2400: return B2400; + case 4800: return B4800; + case 9600: return B9600; + case 19200: return B19200; + case 38400: return B38400; + case 57600: return B57600; + case 115200: return B115200; + case 230400: return B230400; + case 460800: return B460800; + case 500000: return B500000; + case 576000: return B576000; + case 921600: return B921600; + case 1000000: return B1000000; + case 1152000: return B1152000; + case 1500000: return B1500000; + case 2000000: return B2000000; + case 2500000: return B2500000; + case 3000000: return B3000000; + case 3500000: return B3500000; + case 4000000: return B4000000; + default: return -1; + } +} +char* jstring2str(JNIEnv* env, jstring jstr) +{ + char* rtn = NULL; + jclass clsstring = env->FindClass("java/lang/String"); + jstring strencode = env->NewStringUTF("UTF-8"); + jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); + jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr,mid,strencode); + jsize alen = env->GetArrayLength(barr); + jbyte* ba = env->GetByteArrayElements(barr,JNI_FALSE); + + if(alen > 0) + { + rtn = (char*)malloc(alen+1); //new char[alen+1]; + memcpy(rtn,ba,alen); + rtn[alen] = 0; + } + + env->ReleaseByteArrayElements(barr,ba,0); + return (char*)rtn; +} + + +int g_fd = -1; +int serial_open(char *devPath, speed_t baudrate ) { + int ret = 0; + setRS485Enable(true); + int fd = open("/dev/ttyS0", O_RDWR |O_NOCTTY |O_NONBLOCK); + LOGE("_test_ serial_open fd=%d \n",fd); + if(fd < 0) + { + LOGE("_test_ open serial error \n"); + return 0; + } + //ret= set_port_attr (fd, baudrate,8,"1",'N',150,0 );/*9600 8n1 */ + ret= set_port_attr (fd, baudrate,8,"1",'N',150,0 );/*9600 8n1 */ + if(ret < 0) + { + LOGE("_test_ set serial param fail \n"); + return 0; + } + g_fd = fd; + return 1; +} + +void serial_close() +{ + LOGE("_test_ serial_close fd=%d \n",g_fd); + if(g_fd != -1) + { + close(g_fd); + setRS485Enable(false); + } + g_fd = -1; +} + +int serial_write(char *sendbuf, int length) +{ + int len = 0; + if(g_fd < 0) + return 0; + set485WriteMode(); + len = write(g_fd, sendbuf, length);/* 向串囗发送字符串 */ + LOGE("_test_ serial_write len=%d \n",len); + if (len < 0) + { + LOGE("_test_ write data error \n"); + return 0; + } + return len; +} + +int serial_read(char *readbuf,int length) +{ + int len = 0; + if(g_fd < 0) + return 0; + set485ReadMode(); + memset(readbuf, 0, length); + len = read(g_fd, readbuf, length);/* 在串口读取字符串 */ + LOGE("_test_ serial_read len=%d \n",len); + if (len < 0) + { + //LOGE("_test_ read error \n"); + return 0; + } + return len; +} + +extern "C" JNIEXPORT jboolean JNICALL Java_com_xinyingpower_testcomm_MainActivity_openSerial +(JNIEnv* env, jobject, jstring dev, jint baudrate) { + char *devPath = jstring2str(env, dev); + LOGE("_test open serial path=%s, baudrate=%d\n", devPath, baudrate); + speed_t speed = getBaudrate(baudrate); + int res = serial_open(devPath, speed); + return res == 1 ? JNI_TRUE: JNI_FALSE; +} + +extern "C" JNIEXPORT void JNICALL Java_com_xinyingpower_testcomm_MainActivity_closeSerial + (JNIEnv* env, jobject) { + serial_close(); +} + +extern "C" JNIEXPORT jint JNICALL Java_com_xinyingpower_testcomm_MainActivity_writeSerial + (JNIEnv *env, jobject , jbyteArray jstr) { + jsize len = env->GetArrayLength(jstr); + if (len <= 0) + return 0; + jbyte *jdata = env->GetByteArrayElements(jstr, 0); + int res = serial_write((char*)jdata, len); + env->ReleaseByteArrayElements(jstr, jdata, 0); + return res; +} + +extern "C" JNIEXPORT jint JNICALL Java_com_xinyingpower_testcomm_MainActivity_readSerial + (JNIEnv *env, jobject, jbyteArray out) +{ + jsize outlen = env->GetArrayLength(out); + //LOGE("_test readSerial outlen=%d\n", outlen); + if(outlen <= 0) + return 0; + jbyte* outData = env->GetByteArrayElements(out, 0); + char* outbuf = (char*)outData; + int res = serial_read(outbuf, outlen); + //LOGE("_test serial_read res=%d\n", res); + env->ReleaseByteArrayElements(out, outData, 0); + return res; +} \ No newline at end of file diff --git a/TestComm/app/src/main/cpp/spi-test-random.cpp b/TestComm/app/src/main/cpp/spi-test-random.cpp new file mode 100644 index 00000000..e519010a --- /dev/null +++ b/TestComm/app/src/main/cpp/spi-test-random.cpp @@ -0,0 +1,426 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define CMD_HEAD_SIZE 5 +typedef unsigned char u8; + +#define RE_SUC 0x01 +#define RE_ERROR 0x00 + +const unsigned char crc7_table[256] = { + 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, + 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, + 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, + 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e, + 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, + 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45, + 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, + 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c, + 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, + 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13, + 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, + 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a, + 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, + 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21, + 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, + 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38, + 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, + 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36, + 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, + 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f, + 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, + 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, + 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, + 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d, + 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, + 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52, + 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, + 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b, + 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, + 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60, + 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, + 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79 +}; + +const unsigned char EK_CMD[5]={0x80,0xd4,0x01,0x00,0x10}; +const unsigned char AK_CMD[5]={0x80,0xd4,0x02,0x00,0x10}; +const unsigned char IV_CMD[5]={0x80,0xd4,0x04,0x00,0x10}; +volatile unsigned char SM1encrpt_CMD[5]={0xa0,0xe0,0x80,0xff,0xff}; +volatile unsigned char SM1decoder_CMD[5]={0xa0,0xe0,0x81,0xff,0xff}; +volatile unsigned char SM2Keypair_CMD[5]={0x80,0xb2,0x00,0xff,0x00}; +volatile unsigned char SM2OutPub_CMD[5]={0x80,0xb8,0x01,0xff,0x40}; +volatile unsigned char SM2OutPri_CMD[5]={0x80,0xb8,0x02,0xff,0x20}; +volatile unsigned char SM2InPub_CMD[5]={0x80,0xba,0x01,0xff,0x40}; +volatile unsigned char SM2InPri_CMD[5]={0x80,0xba,0x02,0xff,0x20}; +volatile unsigned char SM3Hash_CMD[5]={0x80,0xb5,0x00,0xff,0xff}; +volatile unsigned char SM2Sign_CMD[5]={0x80,0xb4,0x00,0xff,0x20}; +volatile unsigned char SM2VerifySign_CMD[5]={0x80,0xb6,0x00,0xff,0x60}; +volatile unsigned char SM2encrypt_CMD[5]={0x80,0xb3,0x01,0xff,0x20}; +volatile unsigned char SM2decoder_CMD[5]={0x80,0xb3,0x81,0xff,0x80}; +volatile unsigned char SM2cert_CMD[5]={0x80,0xb7,0xff,0xff,0xff}; +volatile unsigned char Random_CMD[5]={0x00,0x84,0x00,0x00,0xff}; +const unsigned char Version_CMD[5]={0x00,0x5b,0x00,0x00,0x40}; +const unsigned char Indentify_CMD[5]={0x80,0xb3,0x01,0x04,0x20}; + +int spi_transfer(int fd, unsigned char *txbuf, unsigned char *rxbuf, int bytes) +{ + struct spi_ioc_transfer xfer[2]; + int status; + + memset(xfer, 0, sizeof(xfer)); + + xfer[0].tx_buf = (__u64)txbuf; + xfer[0].rx_buf = (__u64)rxbuf; + xfer[0].len = bytes; + + status = ioctl(fd, SPI_IOC_MESSAGE(1), xfer); + if (status < 0) + { + perror("SPI_IOC_MESSAGE"); + return -1; + } + + return status; + +} + +void spi_master_init(const char *name, int fd) +{ + __u8 mode = 3; + __u8 lsb, bits; + //__u32 speed = 30000000; + __u32 speed = 2000000; + //__u32 speed = 2000000; + //__u32 speed = 33000000; + + // SPI_IOC_WR_MODE + + ioctl(fd, SPI_IOC_WR_MODE, &mode); + ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); + + if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0) + { + perror("SPI rd_mode"); + return; + } + + if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) + { + perror("SPI rd_lsb_fist"); + return; + } + + if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) + { + perror("SPI rd bits_per_word"); + return; + } + + if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) + { + perror("SPI rd max_speed_hz"); + return; + } + + __android_log_print(ANDROID_LOG_INFO, "SPi", "%s: spi mode %d, %d bits %sper word, %d Hz max\n", name, mode, bits, lsb ? "(lsb first) " : "", speed); + //printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n", + // name, mode, bits, lsb ? "(lsb first) " : "", speed); +} + +unsigned char get_crc7(const unsigned char *buff, int len) +{ + unsigned char crc7_accum = 0; + int i; + + for (i=0; i < len; i++) { + crc7_accum = + crc7_table[(crc7_accum << 1) ^ buff[i]]; + } + return crc7_accum; +} + +int delay(int x) +{ + // while (--x); + // std::this_thread::sleep_for(std::chrono::milliseconds(50)); + usleep(50000); + return 0; +} + +void delay_us(int x) +{ + usleep(x); +}; + +void SendCmdHeader(int fd,u8 *cmd, u8 *rxbuf) +{ + int i=0; + int retval; + +#if defined (CONFIG_ATMEL_SPI_DEBUG) + printf("tx %1d bytes: ", CMD_HEAD_SIZE); + for (i = 0; i < CMD_HEAD_SIZE; i++) + { + printf(" %02x", cmd[i]); + } + printf("\n"); +#endif + + /* send five command header */ + for (i=0; i< CMD_HEAD_SIZE; i++) + { + retval = spi_transfer(fd, cmd+i, rxbuf+i, 1); + __android_log_print(ANDROID_LOG_INFO, "SPiCMD", "cmd[%d]=%x,rxbuf[%d]=%x",i,*(cmd+i),i, *(rxbuf+i)); + delay(20); + } + + cmd[0]=0xaa; //for response + +} + +void RcvINS(int fd, u8 *txbuf, u8 *buf, u8 ins) +{ + int retval; + int cnt = 1000; + int count=0; + /* receive ins */ +INS: + txbuf[0] = 0xaa; + delay(20); + while(cnt--) + { + retval = spi_transfer(fd, txbuf, buf, 1); + __android_log_print(ANDROID_LOG_INFO, "SPiINS", "txbuf=%x,buf=%x", *txbuf,*buf); + if(*buf == ins) + { + return; + break; + } + else + goto INS; + } +} + +void RcvLEN(int fd, u8 *txbuf, u8 *buf, u8 len) +{ + + int retval; + /* receive length */ +LEN: + retval = spi_transfer(fd, txbuf, buf, 1); + __android_log_print(ANDROID_LOG_INFO, "SPiLEN", "txbuf=%x,rxbuf=%hhu", *txbuf,*buf); +} + +//Rcvdata +void RcvData(int fd, u8 *txbuf, u8 *buf) +{ + int i; + int retval; + + /* receive data and crc */ + for(i=0; i<*(buf-1); i++) + { + + retval = spi_transfer(fd, txbuf, buf+i, 1); + __android_log_print(ANDROID_LOG_INFO, "SPiDATA", "data[%d]=%x",i, *(buf+i)); + } +} + + +//RcvSW +void RcvSW(int fd, u8 *txbuf, u8 *buf, u8 sw) +{ + int i; + int retval; + +SW90: + /* receive state word */ + delay(20); + while(1) + { + retval = spi_transfer(fd, txbuf, buf, 1); + if(*buf != sw) + { + goto SW90; + } + break; + } + retval = spi_transfer(fd, txbuf, buf+1, 1); +} + + +int testSpi() +{ + int i; + int cnt; + unsigned char txbuf[256]; + unsigned char rxbuf[256]; + + int retval; + int msglen; + int fd; + const char *devname = "/dev/spidevSE"; + + + // NrsecSpiPort spi("/dev/spidevSE"); + // + // // NrsecSpiPort spi("/dev/spidev0.0"); + // devname = "/dev/spidevSE"; + + fd = open(devname, O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + spi_master_init(devname, fd); + + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + printf("tx %1d bytes: ", msglen); + +CMD_RESEND: + txbuf[0] = 0x00; + txbuf[1] = 0x84; + txbuf[2] = 0x00; + txbuf[3] = 0x00; + txbuf[4] = 0x08; + + SendCmdHeader(fd, txbuf, rxbuf); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); // 指令 + + RcvLEN(fd, txbuf,rxbuf+1, txbuf[4]+1); //长度 多加一个字节的 CRC + + RcvData(fd, txbuf, rxbuf+2); + + RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90); + + //计算接收到数据的CRC + if(get_crc7(rxbuf+2, rxbuf[1]-1) != rxbuf[rxbuf[1]+1]) + { + //CRC Error 命令重发,超过3次,结束 + if(cnt<3) + { + cnt++; + goto CMD_RESEND; + printf("cnt over\n"); + } + else + { + printf("ERROR\n"); + } + } + + printf("rx %1d bytes: ", rxbuf[1]+4); + __android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + close(fd); + + std::string result = "Random: "; + char output[16] = { 0 }; + for (i = 0; i < rxbuf[1]+4; i++) { + sprintf(output, " %02x ", rxbuf[i]); + result += output; + } + __android_log_print(ANDROID_LOG_INFO, "SPi", "%s", result.c_str()); + // printf("\n"); + + return 0; +} + +int testVersion() +{ + int i; + int cnt; + unsigned char txbuf[256]; + unsigned char rxbuf[256]; + + int retval; + int msglen; + int fd; + //const char *devname = "/dev/spidevSE"; + //const char *devname = "/dev/spidev0.0"; + const char *devname = "/dev/mtkgpioctrl"; + + // NrsecSpiPort spi("/dev/spidevSE"); + // + // // NrsecSpiPort spi("/dev/spidev0.0"); + + fd = open(devname, O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + spi_master_init(devname, fd); + + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + __android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + + CMD_RESEND: + + memcpy(txbuf, Version_CMD, sizeof(Version_CMD)); + + SendCmdHeader(fd, txbuf, rxbuf); + + RcvINS(fd,txbuf,rxbuf,txbuf[1]); // 指令 + + RcvLEN(fd,txbuf,rxbuf+1, txbuf[4]); //长度 多加一个字节的 CRC + + RcvData(fd, txbuf, rxbuf+2); + + RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90); + + //计算接收到数据的CRC + if(get_crc7(rxbuf+2, rxbuf[1]-1) != rxbuf[rxbuf[1]+1]) + { + //CRC Error 命令重发,超过3次,结束 + if(cnt<3) + { + cnt++; + goto CMD_RESEND; + printf("cnt over\n"); + } + else + { + printf("ERROR\n"); + } + } + + //printf("rx %1d bytes: ", rxbuf[1]+4); + __android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + std::string result = "Version: "; + char output[16] = { 0 }; + for (i = 0; i < rxbuf[1]+4; i++) { + sprintf(output, " %c ", rxbuf[i]); + result += output; + } + __android_log_print(ANDROID_LOG_INFO, "SPi", "%s", result.c_str()); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "%s", rxbuf); + // printf("\n"); + + close(fd); + return 0; +} + + diff --git a/TestComm/app/src/main/cpp/test b/TestComm/app/src/main/cpp/test new file mode 100644 index 00000000..e69de29b diff --git a/TestComm/app/src/main/java/com/xinyingpower/testcomm/MainActivity.java b/TestComm/app/src/main/java/com/xinyingpower/testcomm/MainActivity.java new file mode 100644 index 00000000..e731c731 --- /dev/null +++ b/TestComm/app/src/main/java/com/xinyingpower/testcomm/MainActivity.java @@ -0,0 +1,59 @@ +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; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + binding = ActivityMainBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + // Example of a call to a native method + TextView tv = binding.sampleText; + // tv.setText(stringFromJNI()); + + binding.btnSpi.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String str = testSpi(0); + binding.sampleText.setText(str); + } + }); + + 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); +} \ No newline at end of file diff --git a/TestComm/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/TestComm/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 00000000..2b068d11 --- /dev/null +++ b/TestComm/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/TestComm/app/src/main/res/drawable/ic_launcher_background.xml b/TestComm/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000..07d5da9c --- /dev/null +++ b/TestComm/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TestComm/app/src/main/res/layout/activity_main.xml b/TestComm/app/src/main/res/layout/activity_main.xml new file mode 100644 index 00000000..458f1c53 --- /dev/null +++ b/TestComm/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,28 @@ + + + + + +