pc-hosted: Put serial handling in own files for unix and implement for windows.
- If host provided /dev/serial/by-id, device must not be given and multiple devices may be selected with -s <(partial) serial number> - On windows, device must by specifies with -d
This commit is contained in:
parent
18ae2bb50d
commit
b4ab9f328e
|
@ -3,9 +3,13 @@ SYS = $(shell $(CC) -dumpmachine)
|
|||
CFLAGS += -DPC_HOSTED -DNO_LIBOPENCM3 -DENABLE_DEBUG
|
||||
CFLAGS +=-I ./target -I./platforms/pc
|
||||
ifneq (, $(findstring mingw, $(SYS)))
|
||||
SRC += serial_win.c
|
||||
LDFLAGS += -lws2_32
|
||||
else ifneq (, $(findstring cygwin, $(SYS)))
|
||||
SRC += serial_win.c
|
||||
LDFLAGS += -lws2_32
|
||||
else
|
||||
SRC += serial_unix.c
|
||||
endif
|
||||
VPATH += platforms/pc
|
||||
SRC += cl_utils.c timing.c utils.c
|
||||
|
|
|
@ -25,77 +25,16 @@
|
|||
#include "remote.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "cl_utils.h"
|
||||
|
||||
/* Allow 100mS for responses to reach us */
|
||||
#define RESP_TIMEOUT (100)
|
||||
|
||||
/* Define this to see the transactions across the link */
|
||||
//#define DUMP_TRANSACTIONS
|
||||
|
||||
static int f; /* File descriptor for connection to GDB remote */
|
||||
|
||||
int set_interface_attribs (int fd, int speed, int parity)
|
||||
|
||||
/* A nice routine grabbed from
|
||||
* https://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c
|
||||
*/
|
||||
|
||||
{
|
||||
struct termios tty;
|
||||
memset (&tty, 0, sizeof tty);
|
||||
if (tcgetattr (fd, &tty) != 0)
|
||||
{
|
||||
fprintf(stderr,"error %d from tcgetattr", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cfsetospeed (&tty, speed);
|
||||
cfsetispeed (&tty, speed);
|
||||
|
||||
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
|
||||
// disable IGNBRK for mismatched speed tests; otherwise receive break
|
||||
// as \000 chars
|
||||
tty.c_iflag &= ~IGNBRK; // disable break processing
|
||||
tty.c_lflag = 0; // no signaling chars, no echo,
|
||||
// no canonical processing
|
||||
tty.c_oflag = 0; // no remapping, no delays
|
||||
tty.c_cc[VMIN] = 0; // read doesn't block
|
||||
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
|
||||
|
||||
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
|
||||
|
||||
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
|
||||
// enable reading
|
||||
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
|
||||
tty.c_cflag |= parity;
|
||||
tty.c_cflag &= ~CSTOPB;
|
||||
tty.c_cflag &= ~CRTSCTS;
|
||||
|
||||
if (tcsetattr (fd, TCSANOW, &tty) != 0)
|
||||
{
|
||||
fprintf(stderr,"error %d from tcsetattr", errno);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BMP_CL_OPTIONS_t cl_opts; /* Portable way to nullify the struct*/
|
||||
|
||||
void platform_init(int argc, char **argv)
|
||||
{
|
||||
BMP_CL_OPTIONS_t cl_opts = {0};
|
||||
cl_opts.opt_idstring = "Blackmagic Debug Probe Remote";
|
||||
cl_init(&cl_opts, argc, argv);
|
||||
char construct[PLATFORM_MAX_MSG_SIZE];
|
||||
|
@ -105,18 +44,8 @@ void platform_init(int argc, char **argv)
|
|||
printf("License GPLv3+: GNU GPL version 3 or later "
|
||||
"<http://gnu.org/licenses/gpl.html>\n\n");
|
||||
|
||||
f=open(cl_opts.opt_serial,O_RDWR|O_SYNC|O_NOCTTY);
|
||||
if (f<0)
|
||||
{
|
||||
fprintf(stderr,"Couldn't open serial port %s\n", cl_opts.opt_serial);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (set_interface_attribs (f, 115000, 0)<0)
|
||||
{
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (serial_open(&cl_opts))
|
||||
exit(-1);
|
||||
int c=snprintf(construct,PLATFORM_MAX_MSG_SIZE,"%s",REMOTE_START_STR);
|
||||
platform_buffer_write((uint8_t *)construct,c);
|
||||
c=platform_buffer_read((uint8_t *)construct, PLATFORM_MAX_MSG_SIZE);
|
||||
|
@ -132,7 +61,7 @@ void platform_init(int argc, char **argv)
|
|||
int ret = cl_execute(&cl_opts);
|
||||
if (cl_opts.opt_tpwr)
|
||||
platform_target_set_power(0);
|
||||
close(f);
|
||||
serial_close();
|
||||
exit(ret);
|
||||
} else {
|
||||
assert(gdb_if_init() == 0);
|
||||
|
@ -217,96 +146,6 @@ void platform_buffer_flush(void)
|
|||
|
||||
}
|
||||
|
||||
int platform_buffer_write(const uint8_t *data, int size)
|
||||
{
|
||||
int s;
|
||||
|
||||
#ifdef DUMP_TRANSACTIONS
|
||||
printf("%s\n",data);
|
||||
#endif
|
||||
s=write(f,data,size);
|
||||
if (s<0)
|
||||
{
|
||||
fprintf(stderr,"Failed to write\n");
|
||||
exit(-2);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int platform_buffer_read(uint8_t *data, int maxsize)
|
||||
|
||||
{
|
||||
uint8_t *c;
|
||||
int s;
|
||||
int ret;
|
||||
uint32_t endTime;
|
||||
fd_set rset;
|
||||
struct timeval tv;
|
||||
|
||||
c=data;
|
||||
tv.tv_sec=0;
|
||||
|
||||
endTime=platform_time_ms()+RESP_TIMEOUT;
|
||||
tv.tv_usec=1000*(endTime-platform_time_ms());
|
||||
|
||||
/* Look for start of response */
|
||||
do
|
||||
{
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(f, &rset);
|
||||
|
||||
ret = select(f + 1, &rset, NULL, NULL, &tv);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr,"Failed on select\n");
|
||||
exit(-4);
|
||||
}
|
||||
if(ret == 0)
|
||||
{
|
||||
fprintf(stderr,"Timeout on read\n");
|
||||
exit(-3);
|
||||
}
|
||||
|
||||
s=read(f,c,1);
|
||||
}
|
||||
while ((s>0) && (*c!=REMOTE_RESP));
|
||||
|
||||
/* Now collect the response */
|
||||
do
|
||||
{
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(f, &rset);
|
||||
ret = select(f + 1, &rset, NULL, NULL, &tv);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr,"Failed on select\n");
|
||||
exit(-4);
|
||||
}
|
||||
if(ret == 0)
|
||||
{
|
||||
fprintf(stderr,"Timeout on read\n");
|
||||
exit(-3);
|
||||
}
|
||||
s=read(f,c,1);
|
||||
if (*c==REMOTE_EOM)
|
||||
{
|
||||
*c=0;
|
||||
#ifdef DUMP_TRANSACTIONS
|
||||
printf(" %s\n",data);
|
||||
#endif
|
||||
return (c-data);
|
||||
}
|
||||
else
|
||||
c++;
|
||||
}
|
||||
while ((s>=0) && (c-data<maxsize));
|
||||
|
||||
fprintf(stderr,"Failed to read\n");
|
||||
exit(-3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *platform_target_voltage(void)
|
||||
|
||||
{
|
||||
|
|
|
@ -41,10 +41,12 @@
|
|||
#define SET_IDLE_STATE(state)
|
||||
#define SET_ERROR_STATE(state)
|
||||
|
||||
/* Allow 100mS for responses to reach us */
|
||||
#define RESP_TIMEOUT (100)
|
||||
|
||||
void platform_buffer_flush(void);
|
||||
int platform_buffer_write(const uint8_t *data, int size);
|
||||
int platform_buffer_read(uint8_t *data, int size);
|
||||
|
||||
static inline int platform_hwversion(void)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -53,6 +53,9 @@ struct mmap_data {
|
|||
int fd;
|
||||
#endif
|
||||
};
|
||||
int cl_debuglevel;
|
||||
static struct mmap_data map; /* Portable way way to nullify the struct!*/
|
||||
|
||||
|
||||
static int bmp_mmap(char *file, struct mmap_data *map)
|
||||
{
|
||||
|
@ -116,6 +119,7 @@ static void cl_help(char **argv, BMP_CL_OPTIONS_t *opt)
|
|||
printf("Usage: %s [options]\n", argv[0]);
|
||||
printf("\t-h\t\t: This help.\n");
|
||||
printf("\t-v[1|2]\t\t: Increasing verbosity\n");
|
||||
printf("\t-d \"path\"\t: Use serial device at \"path\"\n");
|
||||
printf("\t-s \"string\"\t: Use dongle with (partial) "
|
||||
"serial number \"string\"\n");
|
||||
printf("\t-c \"string\"\t: Use ftdi dongle with type \"string\"\n");
|
||||
|
@ -145,7 +149,7 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
|
|||
opt->opt_target_dev = 1;
|
||||
opt->opt_flash_start = 0x08000000;
|
||||
opt->opt_flash_size = 16 * 1024 *1024;
|
||||
while((c = getopt(argc, argv, "Ehv::s:c:CnN:tVta:S:jprR")) != -1) {
|
||||
while((c = getopt(argc, argv, "Ehv::d:s:c:CnN:tVta:S:jprR")) != -1) {
|
||||
switch(c) {
|
||||
case 'c':
|
||||
if (optarg)
|
||||
|
@ -156,7 +160,9 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
|
|||
break;
|
||||
case 'v':
|
||||
if (optarg)
|
||||
opt->opt_debuglevel = strtol(optarg, NULL, 0);
|
||||
cl_debuglevel = strtol(optarg, NULL, 0);
|
||||
else
|
||||
cl_debuglevel = -1;
|
||||
break;
|
||||
case 'j':
|
||||
opt->opt_usejtag = true;
|
||||
|
@ -167,6 +173,10 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
|
|||
case 'n':
|
||||
opt->opt_no_wait = true;
|
||||
break;
|
||||
case 'd':
|
||||
if (optarg)
|
||||
opt->opt_device = optarg;
|
||||
break;
|
||||
case 's':
|
||||
if (optarg)
|
||||
opt->opt_serial = optarg;
|
||||
|
@ -277,7 +287,6 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
|
|||
goto target_detach;
|
||||
}
|
||||
int read_file = -1;
|
||||
struct mmap_data map = {0};
|
||||
if ((opt->opt_mode == BMP_MODE_FLASH_WRITE) ||
|
||||
(opt->opt_mode == BMP_MODE_FLASH_VERIFY)) {
|
||||
int mmap_res = bmp_mmap(opt->opt_flash_file, &map);
|
||||
|
|
|
@ -41,6 +41,7 @@ typedef struct BMP_CL_OPTIONS_s {
|
|||
bool opt_tpwr;
|
||||
bool opt_connect_under_reset;
|
||||
char *opt_flash_file;
|
||||
char *opt_device;
|
||||
char *opt_serial;
|
||||
char *opt_cable;
|
||||
int opt_debuglevel;
|
||||
|
@ -52,4 +53,6 @@ typedef struct BMP_CL_OPTIONS_s {
|
|||
|
||||
void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv);
|
||||
int cl_execute(BMP_CL_OPTIONS_t *opt);
|
||||
int serial_open(BMP_CL_OPTIONS_t *opt);
|
||||
void serial_close(void);
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* This file is part of the Black Magic Debug project.
|
||||
*
|
||||
* Copyright (C) 2019 Dave Marples <dave@marples.net>
|
||||
* with additions from Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "general.h"
|
||||
#include "remote.h"
|
||||
#include "cl_utils.h"
|
||||
|
||||
static int fd; /* File descriptor for connection to GDB remote */
|
||||
extern int cl_debuglevel;
|
||||
/* A nice routine grabbed from
|
||||
* https://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c
|
||||
*/
|
||||
static int set_interface_attribs(void)
|
||||
{
|
||||
struct termios tty;
|
||||
memset (&tty, 0, sizeof tty);
|
||||
if (tcgetattr (fd, &tty) != 0) {
|
||||
fprintf(stderr,"error %d from tcgetattr", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
|
||||
// disable IGNBRK for mismatched speed tests; otherwise receive break
|
||||
// as \000 chars
|
||||
tty.c_iflag &= ~IGNBRK; // disable break processing
|
||||
tty.c_lflag = 0; // no signaling chars, no echo,
|
||||
// no canonical processing
|
||||
tty.c_oflag = 0; // no remapping, no delays
|
||||
tty.c_cc[VMIN] = 0; // read doesn't block
|
||||
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
|
||||
|
||||
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
|
||||
|
||||
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
|
||||
// enable reading
|
||||
tty.c_cflag &= ~CSTOPB;
|
||||
tty.c_cflag &= ~CRTSCTS;
|
||||
|
||||
if (tcsetattr (fd, TCSANOW, &tty) != 0) {
|
||||
fprintf(stderr,"error %d from tcsetattr", errno);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#define BMP_IDSTRING "usb-Black_Sphere_Technologies_Black_Magic_Probe"
|
||||
#define DEVICE_BY_ID "/dev/serial/by-id/"
|
||||
int serial_open(BMP_CL_OPTIONS_t *opt)
|
||||
{
|
||||
char name[256];
|
||||
if (!opt->opt_device) {
|
||||
/* Try to find some BMP if0*/
|
||||
struct dirent *dp;
|
||||
DIR *dir = opendir(DEVICE_BY_ID);
|
||||
if (!dir) {
|
||||
fprintf(stderr, "No serial device found\n");
|
||||
return -1;
|
||||
}
|
||||
int num_devices = 0;
|
||||
int num_total = 0;
|
||||
while ((dp = readdir(dir)) != NULL) {
|
||||
if ((strstr(dp->d_name, BMP_IDSTRING)) &&
|
||||
(strstr(dp->d_name, "-if00"))) {
|
||||
num_total++;
|
||||
if (((opt->opt_serial) &&
|
||||
(!strstr(dp->d_name, opt->opt_serial))))
|
||||
continue;
|
||||
num_devices++;
|
||||
strcpy(name, DEVICE_BY_ID);
|
||||
strncat(name, dp->d_name, sizeof(name) - strlen(name) - 1);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
if ((num_devices == 0) && (num_total == 0)){
|
||||
fprintf(stderr, "No BMP probe found\n");
|
||||
return -1;
|
||||
} else if (num_devices != 1) {
|
||||
fprintf(stderr, "Available Probes:\n");
|
||||
dir = opendir(DEVICE_BY_ID);
|
||||
if (dir) {
|
||||
while ((dp = readdir(dir)) != NULL) {
|
||||
if ((strstr(dp->d_name, BMP_IDSTRING)) &&
|
||||
(strstr(dp->d_name, "-if00")))
|
||||
fprintf(stderr, "%s\n", dp->d_name);
|
||||
}
|
||||
closedir(dir);
|
||||
if (opt->opt_serial)
|
||||
fprintf(stderr, "Do no match given serial \"%s\"\n", opt->opt_serial);
|
||||
else
|
||||
fprintf(stderr, "Select Probe with -s <(Partial) Serial Number\n");
|
||||
} else {
|
||||
fprintf(stderr, "Could not opendir %s: %s\n", name, strerror(errno));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
strncpy(name, opt->opt_device, sizeof(name) - 1);
|
||||
}
|
||||
fd = open(name, O_RDWR | O_SYNC | O_NOCTTY);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr,"Couldn't open serial port %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
/* BMP only offers an USB-Serial connection with no real serial
|
||||
* line in between. No need for baudrate or parity.!
|
||||
*/
|
||||
return set_interface_attribs();
|
||||
}
|
||||
|
||||
void serial_close(void)
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
int platform_buffer_write(const uint8_t *data, int size)
|
||||
{
|
||||
int s;
|
||||
|
||||
if (cl_debuglevel)
|
||||
printf("%s\n",data);
|
||||
s = write(fd, data, size);
|
||||
if (s < 0) {
|
||||
fprintf(stderr, "Failed to write\n");
|
||||
exit(-2);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int platform_buffer_read(uint8_t *data, int maxsize)
|
||||
{
|
||||
uint8_t *c;
|
||||
int s;
|
||||
int ret;
|
||||
uint32_t endTime;
|
||||
fd_set rset;
|
||||
struct timeval tv;
|
||||
|
||||
c = data;
|
||||
tv.tv_sec = 0;
|
||||
|
||||
endTime = platform_time_ms() + RESP_TIMEOUT;
|
||||
tv.tv_usec = 1000 * (endTime - platform_time_ms());
|
||||
|
||||
/* Look for start of response */
|
||||
do {
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(fd, &rset);
|
||||
|
||||
ret = select(fd + 1, &rset, NULL, NULL, &tv);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr,"Failed on select\n");
|
||||
exit(-4);
|
||||
}
|
||||
if(ret == 0) {
|
||||
fprintf(stderr,"Timeout on read RESP\n");
|
||||
exit(-3);
|
||||
}
|
||||
|
||||
s = read(fd, c, 1);
|
||||
}
|
||||
while ((s > 0) && (*c != REMOTE_RESP));
|
||||
/* Now collect the response */
|
||||
do {
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(fd, &rset);
|
||||
ret = select(fd + 1, &rset, NULL, NULL, &tv);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr,"Failed on select\n");
|
||||
exit(-4);
|
||||
}
|
||||
if(ret == 0) {
|
||||
fprintf(stderr,"Timeout on read\n");
|
||||
exit(-3);
|
||||
}
|
||||
s = read(fd, c, 1);
|
||||
if (*c==REMOTE_EOM) {
|
||||
*c = 0;
|
||||
if (cl_debuglevel)
|
||||
printf(" %s\n",data);
|
||||
return (c - data);
|
||||
} else {
|
||||
c++;
|
||||
}
|
||||
}while ((s >= 0) && ((c - data) < maxsize));
|
||||
|
||||
fprintf(stderr,"Failed to read\n");
|
||||
exit(-3);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* This file is part of the Black Magic Debug project.
|
||||
*
|
||||
* Copyright (C) 2020 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "general.h"
|
||||
#include <windows.h>
|
||||
#include "remote.h"
|
||||
#include "cl_utils.h"
|
||||
|
||||
HANDLE hComm;
|
||||
extern int cl_debuglevel;
|
||||
|
||||
int serial_open(BMP_CL_OPTIONS_t *opt)
|
||||
{
|
||||
if (!opt->opt_device) {
|
||||
fprintf(stderr,"Specify the serial device to use!\n");
|
||||
return -1;
|
||||
}
|
||||
char device[256];
|
||||
if (strstr(opt->opt_device, "\\\\.\\")) {
|
||||
strncpy(device, opt->opt_device, sizeof(device) - 1);
|
||||
} else {
|
||||
strcpy(device, "\\\\.\\");
|
||||
strncat(device, opt->opt_device, sizeof(device) - strlen(device) - 1);
|
||||
}
|
||||
hComm = CreateFile(device, //port name
|
||||
GENERIC_READ | GENERIC_WRITE, //Read/Write
|
||||
0, // No Sharing
|
||||
NULL, // No Security
|
||||
OPEN_EXISTING,// Open existing port only
|
||||
0, // Non Overlapped I/O
|
||||
NULL); // Null for Comm Devices}
|
||||
if (hComm == INVALID_HANDLE_VALUE) {
|
||||
fprintf(stderr, "Could not open %s: %ld\n", device,
|
||||
GetLastError());
|
||||
return -1;
|
||||
}
|
||||
DCB dcbSerialParams;
|
||||
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
|
||||
if (!GetCommState(hComm, &dcbSerialParams)) {
|
||||
fprintf(stderr, "GetCommState failed %ld\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
dcbSerialParams.ByteSize = 8;
|
||||
if (!SetCommState(hComm, &dcbSerialParams)) {
|
||||
fprintf(stderr, "SetCommState failed %ld\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
COMMTIMEOUTS timeouts = {0};
|
||||
timeouts.ReadIntervalTimeout = 10;
|
||||
timeouts.ReadTotalTimeoutConstant = 10;
|
||||
timeouts.ReadTotalTimeoutMultiplier = 10;
|
||||
timeouts.WriteTotalTimeoutConstant = 10;
|
||||
timeouts.WriteTotalTimeoutMultiplier = 10;
|
||||
if (!SetCommTimeouts(hComm, &timeouts)) {
|
||||
fprintf(stderr, "SetCommTimeouts failed %ld\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void serial_close(void)
|
||||
{
|
||||
CloseHandle(hComm);
|
||||
}
|
||||
|
||||
int platform_buffer_write(const uint8_t *data, int size)
|
||||
{
|
||||
if (cl_debuglevel)
|
||||
printf("%s\n",data);
|
||||
int s = 0;
|
||||
|
||||
do {
|
||||
DWORD written;
|
||||
if (!WriteFile(hComm, data + s, size - s, &written, NULL)) {
|
||||
fprintf(stderr, "Serial write failed %ld, written %d\n",
|
||||
GetLastError(), s);
|
||||
return -1;
|
||||
}
|
||||
s += written;
|
||||
} while (s < size);
|
||||
return 0;
|
||||
}
|
||||
int platform_buffer_read(uint8_t *data, int maxsize)
|
||||
{
|
||||
DWORD s;
|
||||
uint8_t response = 0;
|
||||
uint32_t startTime = platform_time_ms();
|
||||
uint32_t endTime = platform_time_ms() + RESP_TIMEOUT;
|
||||
do {
|
||||
if (!ReadFile(hComm, &response, 1, &s, NULL)) {
|
||||
fprintf(stderr,"ERROR on read RESP\n");
|
||||
exit(-3);
|
||||
}
|
||||
if (platform_time_ms() > endTime) {
|
||||
fprintf(stderr,"Timeout on read RESP\n");
|
||||
exit(-4);
|
||||
}
|
||||
} while (response != REMOTE_RESP);
|
||||
uint8_t *c = data;
|
||||
do {
|
||||
if (!ReadFile(hComm, c, 1, &s, NULL)) {
|
||||
fprintf(stderr,"Error on read\n");
|
||||
exit(-3);
|
||||
}
|
||||
if (s > 0 ) {
|
||||
if (cl_debuglevel)
|
||||
printf("%c", *c);
|
||||
if (*c == REMOTE_EOM) {
|
||||
*c = 0;
|
||||
if (cl_debuglevel)
|
||||
printf("\n");
|
||||
return (c - data);
|
||||
} else {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
} while (((c - data) < maxsize) && (platform_time_ms() < endTime));
|
||||
fprintf(stderr,"Failed to read EOM at %d\n",
|
||||
platform_time_ms() - startTime);
|
||||
exit(-3);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue