📄 serial.cpp
字号:
/*
Robot Interface
(C) 2006 Jason Hunt
nulluser@gmail.com
File: serial.cpp
*/
#include <windows.h>
#include <stdio.h>
#include "serial.h"
#include "robot.h"
#include "display.h"
HANDLE h_serial = NULL; // Handle for serial port
bool serial_ok = false; // True if serial is working
HANDLE h_serial_thread = NULL; // Handel for serial control thread
DWORD serial_thread_id; // Serial control
bool serial_running = false; // True if serial thread is running
CRITICAL_SECTION serial_thread_lock; // Lock for serial thread
bool timeout_flag = false; // Set once for a timeout condition
char serial_port[10]; // Filename of serial port
/* Make sure there is no pending data for the next retry */
void flush_serial( void )
{
DWORD read = 1;
// Wait for byte
while (read)
{
char ch;
ReadFile (h_serial, &ch, 1, &read, NULL);
}
}
/* End of flush serial */
/* Preform transfer with robot */
int transfer_serial( void )
{
// Buffer for send/recv
unsigned char buffer[SERIAL_RECV_SIZE + SERIAL_SEND_SIZE];
// Length of trnaferd data for send or recv
unsigned long length;
// Copy control data into the send buffer
robot.get_control(buffer);
// Send data to controller
if (!WriteFile(h_serial, buffer, SERIAL_SEND_SIZE, &length, NULL))
{
add_line("Unable to send data");
serial_ok = false;
return(1);
}
// Check data sent length
if (length != SERIAL_SEND_SIZE)
{
add_line("Send data error");
serial_ok = false;
return(1);
}
// Read telemetry data from the controller
if (!ReadFile(h_serial, buffer, SERIAL_RECV_SIZE, &length, NULL))
{
add_line("Unable to read data");
serial_ok = false;
return(1);
}
// Check length of packet
if (length != SERIAL_RECV_SIZE)
{
if (!timeout_flag)
{
add_line("Read data timeout");
timeout_flag = true;
}
flush_serial();
// Clear recv buffer
memset(buffer, 0, SERIAL_RECV_SIZE);
serial_ok = false;
return(1);
}
timeout_flag = false;
robot.set_telemetry(buffer);
return(0);
}
/* End of transfer serial */
/* Core thread for serial transfer */
DWORD WINAPI serial_thread(LPVOID p)
{
DWORD length;
bool done = false;
while (!done)
{
// Preform serial transfer, and send result to update
robot.update_complete(transfer_serial());
EnterCriticalSection(&serial_thread_lock);
done = !serial_running;
LeaveCriticalSection(&serial_thread_lock);
}
return(0);
}
/* End of serial thread */
/* Starts the serial system */
void start_serial( void )
{
// serial_ok = false;
h_serial = CreateFile(serial_port, // Port name
GENERIC_READ | GENERIC_WRITE, // File access
0, // share mode
NULL, // Security
OPEN_ALWAYS, // Creation
0, // Flags
NULL ); // Template
if (h_serial == INVALID_HANDLE_VALUE)
{
char b[400];
sprintf(b, "Unable to open serial port (%s)", serial_port);
add_line(b);
return;
}
DCB serial_param;
if (!GetCommState(h_serial, &serial_param))
{
add_line("Unable to get commstate");
return;
}
serial_param.BaudRate = CBR_19200;
serial_param.fParity = false;
serial_param.fBinary = true;
serial_param.fOutxCtsFlow = false;
serial_param.fOutxDsrFlow = false;
serial_param.fDtrControl = DTR_CONTROL_DISABLE;
serial_param.fDsrSensitivity = false;
serial_param.fErrorChar = false;
serial_param.fNull = false;
serial_param.fOutX = false;
serial_param.fInX = false;
serial_param.fRtsControl = RTS_CONTROL_DISABLE; // Disable request to send control
serial_param.Parity = NOPARITY;
serial_param.ByteSize = 8;
serial_param.StopBits = TWOSTOPBITS;
if (!SetCommState(h_serial, &serial_param))
{
add_line("Unable to set commstate");
return;
}
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 200;
timeouts.ReadTotalTimeoutMultiplier = 1;
timeouts.ReadTotalTimeoutConstant = 200;
timeouts.WriteTotalTimeoutMultiplier = 1;
timeouts.WriteTotalTimeoutConstant = 200;
if (!SetCommTimeouts(h_serial, &timeouts))
{
add_line("Unable to get comm timeouts");
return;
}
InitializeCriticalSection(&serial_thread_lock);
// Set serial thread active
serial_running = true;
// Start the serial therad
h_serial_thread = CreateThread(0, 0, serial_thread, NULL, 0, &serial_thread_id);
serial_ok = true;
add_line("Serial Online");
}
/* End of start serial */
/* Close the serial port */
void stop_serial( void )
{
if (h_serial_thread != NULL)
{
EnterCriticalSection(&serial_thread_lock);
serial_running = false; // Tell thread to exit
LeaveCriticalSection(&serial_thread_lock);
WaitForSingleObject(h_serial_thread, INFINITE); // Wait for thread to terminate
}
if (h_serial != NULL)
CloseHandle(h_serial);
}
/* End of stop serial */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -