You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
TermApp/TestComm/app/src/main/cpp/spi-test-random.cpp

427 lines
10 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
}