mirror of
https://github.com/ole00/afterburner.git
synced 2024-09-27 15:56:47 +00:00
version 0.2
* added support for Win32/64 builds * fixed Mac OSX serial connection parameters
This commit is contained in:
parent
2c6ada613d
commit
d5744a7d1a
@ -30,6 +30,9 @@ Requires:
|
|||||||
|
|
||||||
Changelog:
|
Changelog:
|
||||||
* 2019.02.02 - initial version 0.1
|
* 2019.02.02 - initial version 0.1
|
||||||
|
* 2019.03.24 - version 0.2
|
||||||
|
- added support for Win32 and Win64 builds
|
||||||
|
- fixed serial port setup for Mac OSX
|
||||||
|
|
||||||
This is the PC part that communicates with Arduino UNO by serial line.
|
This is the PC part that communicates with Arduino UNO by serial line.
|
||||||
To compile: gcc -g3 -O0 afterburner afterburner.c
|
To compile: gcc -g3 -O0 afterburner afterburner.c
|
||||||
@ -40,14 +43,12 @@ To compile: gcc -g3 -O0 afterburner afterburner.c
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <termios.h>
|
#include "serial_port.h"
|
||||||
|
|
||||||
|
#define VERSION "v.0.2"
|
||||||
|
|
||||||
#define VERSION "v.0.1"
|
|
||||||
#define DEFAULT_DEVICE_NAME "/dev/ttyUSB0"
|
|
||||||
|
|
||||||
#define MAX_LINE 200
|
#define MAX_LINE 200
|
||||||
|
|
||||||
@ -98,7 +99,7 @@ char verbose = 0;
|
|||||||
char* filename = 0;
|
char* filename = 0;
|
||||||
char* deviceName = 0;
|
char* deviceName = 0;
|
||||||
|
|
||||||
int serialF = -1;
|
SerialDeviceHandle serialF = INVALID_HANDLE;
|
||||||
Galtype gal;
|
Galtype gal;
|
||||||
int security = 0;
|
int security = 0;
|
||||||
unsigned short checksum;
|
unsigned short checksum;
|
||||||
@ -131,7 +132,7 @@ static void printHelp() {
|
|||||||
printf(" -v : verbose mode\n");
|
printf(" -v : verbose mode\n");
|
||||||
printf(" -t <gal_type> : the GAL type. use GAL16V8 GAL20V8 GAL22V10 ATF16V8B ATF22V10B ATF22V10C\n");
|
printf(" -t <gal_type> : the GAL type. use GAL16V8 GAL20V8 GAL22V10 ATF16V8B ATF22V10B ATF22V10C\n");
|
||||||
printf(" -f <file> : JEDEC fuse map file\n");
|
printf(" -f <file> : JEDEC fuse map file\n");
|
||||||
printf(" -d <serial_device> : name of the serial device. Default is: %s\n", DEFAULT_DEVICE_NAME);
|
printf(" -d <serial_device> : name of the serial device. Default is: %s\n", DEFAULT_SERIAL_DEVICE_NAME);
|
||||||
printf(" serial params are: 38400, 8N1\n");
|
printf(" serial params are: 38400, 8N1\n");
|
||||||
printf("examples:\n");
|
printf("examples:\n");
|
||||||
printf(" afterburner i : reads and prints the device info\n");
|
printf(" afterburner i : reads and prints the device info\n");
|
||||||
@ -462,48 +463,29 @@ static char readJedec(void) {
|
|||||||
|
|
||||||
static int openSerial(void) {
|
static int openSerial(void) {
|
||||||
char buf[512];
|
char buf[512];
|
||||||
char devName[16];
|
char devName[256] = {0};
|
||||||
int total;
|
int total;
|
||||||
int labelPos;
|
int labelPos;
|
||||||
|
|
||||||
|
|
||||||
//open device name
|
//open device name
|
||||||
snprintf(devName, 15, "%s", (deviceName == 0) ? DEFAULT_DEVICE_NAME : deviceName);
|
snprintf(devName, sizeof(devName), "%s", (deviceName == 0) ? DEFAULT_SERIAL_DEVICE_NAME : deviceName);
|
||||||
devName[15] = 0;
|
serialDeviceCheckName(devName, sizeof(devName));
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printf("opening serial: %s\n", devName);
|
printf("opening serial: %s\n", devName);
|
||||||
}
|
}
|
||||||
|
|
||||||
serialF = open(devName, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
serialF = serialDeviceOpen(devName);
|
||||||
if (serialF < 1) {
|
if (serialF == INVALID_HANDLE) {
|
||||||
printf("Error: failed to open serial device: %s\n", devName);
|
printf("Error: failed to open serial device: %s\n", devName);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
//set the serial port parameters
|
|
||||||
{
|
|
||||||
struct termios serial;
|
|
||||||
|
|
||||||
memset(&serial, 0, sizeof(struct termios));
|
|
||||||
cfsetispeed(&serial, B38400);
|
|
||||||
cfsetospeed(&serial, B38400);
|
|
||||||
|
|
||||||
serial.c_cflag |= CS8; // no parity, 1 stop bit
|
|
||||||
|
|
||||||
if (0 != tcsetattr(serialF, TCSANOW, &serial)) {
|
|
||||||
printf("Error: failed to set serial parameters %i, %s\n", errno, strerror(errno));
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//ensure no leftover bytes exist on the serial line
|
|
||||||
tcdrain(serialF);
|
|
||||||
tcflush(serialF, TCIOFLUSH); //flush both queues
|
|
||||||
|
|
||||||
// prod the programmer to output it's identification
|
// prod the programmer to output it's identification
|
||||||
sprintf(buf, "*\r");
|
sprintf(buf, "*\r");
|
||||||
write(serialF, buf, 2);
|
serialDeviceWrite(serialF, buf, 2);
|
||||||
|
|
||||||
//read programmer's message
|
//read programmer's message
|
||||||
total = waitForSerialPrompt(buf, 512, 3000);
|
total = waitForSerialPrompt(buf, 512, 3000);
|
||||||
@ -519,17 +501,17 @@ static int openSerial(void) {
|
|||||||
if (verbose) {
|
if (verbose) {
|
||||||
printf("Output from programmer not recognised: %s\n", buf);
|
printf("Output from programmer not recognised: %s\n", buf);
|
||||||
}
|
}
|
||||||
close(serialF);
|
serialDeviceClose(serialF);
|
||||||
serialF = 0;
|
serialF = INVALID_HANDLE;
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void closeSerial(void) {
|
static void closeSerial(void) {
|
||||||
if (0 == serialF) {
|
if (INVALID_HANDLE == serialF) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
close(serialF);
|
serialDeviceClose(serialF);
|
||||||
serialF = 0;
|
serialF = INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -583,7 +565,7 @@ static int waitForSerialPrompt(char* buf, int bufSize, int maxDelay) {
|
|||||||
memset(buf, 0, bufSize);
|
memset(buf, 0, bufSize);
|
||||||
|
|
||||||
while (maxDelay > 0) {
|
while (maxDelay > 0) {
|
||||||
readSize = read(serialF, buf, bufSize);
|
readSize = serialDeviceRead(serialF, buf, bufSize);
|
||||||
if (readSize > 0) {
|
if (readSize > 0) {
|
||||||
bufPos += readSize;
|
bufPos += readSize;
|
||||||
if (checkPromptExists(bufStart, bufTotal) >= 0) {
|
if (checkPromptExists(bufStart, bufTotal) >= 0) {
|
||||||
@ -606,7 +588,7 @@ static int sendLine(char* buf, int bufSize, int maxDelay) {
|
|||||||
int writeSize;
|
int writeSize;
|
||||||
char* obuf = buf;
|
char* obuf = buf;
|
||||||
|
|
||||||
if (serialF == 0) {
|
if (serialF == INVALID_HANDLE) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,9 +600,9 @@ static int sendLine(char* buf, int bufSize, int maxDelay) {
|
|||||||
// write the query into the modem's file
|
// write the query into the modem's file
|
||||||
// file is opened non blocking so we have to ensure all contents is written
|
// file is opened non blocking so we have to ensure all contents is written
|
||||||
while (total > 0) {
|
while (total > 0) {
|
||||||
writeSize = write(serialF, buf, total);
|
writeSize = serialDeviceWrite(serialF, buf, total);
|
||||||
if (writeSize < 0) {
|
if (writeSize < 0) {
|
||||||
printf("ERROR: written: %i", writeSize);
|
printf("ERROR: written: %i (%s)\n", writeSize, strerror(errno));
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
buf += writeSize;
|
buf += writeSize;
|
||||||
|
4
compile_win32.sh
Executable file
4
compile_win32.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
# path to your win32 cross-compiler
|
||||||
|
CC=~/opt/mingw32/bin/i686-w64-mingw32-gcc
|
||||||
|
|
||||||
|
$CC -g3 -O0 -o afterburner_w32.exe afterburner.c -D_USE_WIN_API_
|
4
compile_win64.sh
Executable file
4
compile_win64.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
# path to your Win64 cross-compiler
|
||||||
|
CC=~/opt/mingw64/bin/x86_64-w64-mingw32-gcc
|
||||||
|
|
||||||
|
$CC -g3 -O0 -o afterburner_w64.exe afterburner.c -D_USE_WIN_API_
|
170
serial_port.h
Normal file
170
serial_port.h
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
#ifndef _SERIAL_PORT_H_
|
||||||
|
#define _SERIAL_PORT_H_
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _USE_WIN_API_
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#define SerialDeviceHandle HANDLE
|
||||||
|
#define DEFAULT_SERIAL_DEVICE_NAME "COM1"
|
||||||
|
#define INVALID_HANDLE INVALID_HANDLE_VALUE
|
||||||
|
|
||||||
|
// https://www.xanthium.in/Serial-Port-Programming-using-Win32-API
|
||||||
|
|
||||||
|
static inline SerialDeviceHandle serialDeviceOpen(char* deviceName) {
|
||||||
|
SerialDeviceHandle h;
|
||||||
|
|
||||||
|
h = CreateFile(
|
||||||
|
deviceName, //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 (h != INVALID_HANDLE) {
|
||||||
|
BOOL result;
|
||||||
|
COMMTIMEOUTS timeouts = { 0 };
|
||||||
|
|
||||||
|
DCB dcbSerialParams = { 0 }; // Initializing DCB structure
|
||||||
|
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
|
||||||
|
|
||||||
|
result = GetCommState(h, &dcbSerialParams);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
dcbSerialParams.BaudRate = CBR_38400; // Setting BaudRate = 38400
|
||||||
|
dcbSerialParams.ByteSize = 8; // Setting ByteSize = 8
|
||||||
|
dcbSerialParams.StopBits = ONESTOPBIT;// Setting StopBits = 1
|
||||||
|
dcbSerialParams.Parity = NOPARITY; // Setting Parity = None
|
||||||
|
|
||||||
|
result = SetCommState(h, &dcbSerialParams);
|
||||||
|
if (!result) {
|
||||||
|
return INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeouts.ReadIntervalTimeout = 50; // in milliseconds
|
||||||
|
timeouts.ReadTotalTimeoutConstant = 50; // in milliseconds
|
||||||
|
timeouts.ReadTotalTimeoutMultiplier = 10; // in milliseconds
|
||||||
|
timeouts.WriteTotalTimeoutConstant = 50; // in milliseconds
|
||||||
|
timeouts.WriteTotalTimeoutMultiplier = 10; // in milliseconds
|
||||||
|
|
||||||
|
result = SetCommTimeouts(h, &timeouts);
|
||||||
|
if (!result) {
|
||||||
|
return INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return h;
|
||||||
|
} else {
|
||||||
|
return INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialDeviceCheckName(char* name, int maxSize) {
|
||||||
|
int nameLen = strlen(name);
|
||||||
|
//convert comxx to COMxx
|
||||||
|
if (strncmp(name, "com", 3) == 0 && (nameLen > 3 && name[3] >= '0' && name[3] <= '9')) {
|
||||||
|
name[0] = 'C';
|
||||||
|
name[1] = 'O';
|
||||||
|
name[2] = 'M';
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert COMxx and higher to \\\\.\\COMxx
|
||||||
|
if (strncmp(name, "COM", 3) == 0 && (nameLen > 4 && name[3] >= '0' && name[3] <= '9')) {
|
||||||
|
if (nameLen + 4 < maxSize) {
|
||||||
|
int i;
|
||||||
|
for (i = nameLen - 1; i >= 0; i--) {
|
||||||
|
name[ i + 4] = name[i];
|
||||||
|
}
|
||||||
|
name[0] = '\\';
|
||||||
|
name[1] = '\\';
|
||||||
|
name[2] = '.';
|
||||||
|
name[3] = '\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void serialDeviceClose(SerialDeviceHandle deviceHandle) {
|
||||||
|
CloseHandle(deviceHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int serialDeviceWrite(SerialDeviceHandle deviceHandle, char* buffer, int bytesToWrite) {
|
||||||
|
DWORD written = 0;
|
||||||
|
WriteFile(deviceHandle, buffer, bytesToWrite, &written, NULL);
|
||||||
|
return (int) written;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int serialDeviceRead(SerialDeviceHandle deviceHandle, char* buffer, int bytesToRead) {
|
||||||
|
DWORD read = 0;
|
||||||
|
ReadFile(deviceHandle, buffer, bytesToRead, &read, NULL);
|
||||||
|
return (int) read;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
#define SerialDeviceHandle int
|
||||||
|
#define DEFAULT_SERIAL_DEVICE_NAME "/dev/ttyUSB0"
|
||||||
|
|
||||||
|
#define INVALID_HANDLE -1
|
||||||
|
|
||||||
|
static inline SerialDeviceHandle serialDeviceOpen(char* deviceName) {
|
||||||
|
|
||||||
|
SerialDeviceHandle h;
|
||||||
|
h = open(deviceName, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||||
|
|
||||||
|
if (h != INVALID_HANDLE) {
|
||||||
|
//set the serial port parameters
|
||||||
|
struct termios serial;
|
||||||
|
|
||||||
|
memset(&serial, 0, sizeof(struct termios));
|
||||||
|
cfsetispeed(&serial, B38400);
|
||||||
|
cfsetospeed(&serial, B38400);
|
||||||
|
|
||||||
|
serial.c_cflag |= CS8; // no parity, 1 stop bit
|
||||||
|
serial.c_cflag |= CREAD | CLOCAL;
|
||||||
|
|
||||||
|
if (0 != tcsetattr(h, TCSANOW, &serial)) {
|
||||||
|
close(h);
|
||||||
|
printf("Error: failed to set serial parameters %i, %s\n", errno, strerror(errno));
|
||||||
|
return INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//ensure no leftover bytes exist on the serial line
|
||||||
|
tcdrain(h);
|
||||||
|
tcflush(h, TCIOFLUSH); //flush both queues
|
||||||
|
return h;
|
||||||
|
} else {
|
||||||
|
return INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialDeviceCheckName(char* name, int maxSize) {
|
||||||
|
//nothing to check
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void serialDeviceClose(SerialDeviceHandle deviceHandle) {
|
||||||
|
close(deviceHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int serialDeviceWrite(SerialDeviceHandle deviceHandle, char* buffer, int bytesToWrite) {
|
||||||
|
return write(deviceHandle, buffer, bytesToWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int serialDeviceRead(SerialDeviceHandle deviceHandle, char* buffer, int bytesToRead) {
|
||||||
|
return read(deviceHandle, buffer, bytesToRead);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _SERIAL_PORT_H_ */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user