0 registered members (),
1,397
guests, and 7
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Serial Communications Header
#280484
07/22/09 20:32
07/22/09 20:32
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
OP
Expert
|
OP
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
Hi again. Due to inspiration by The_Mehmaster, Ive decided to write a Serial Communications Suite. It enables 3DGS to communicate via the SERIAL port (COMx) of the computer, like port_in & port_out does with the parallel port. But Serial devices are easier to design (in my mind), much more common on "specialised" hardware than parallel, and more flexible. Also, my code contains buffering of data on both READ and WRITE data-flow, so it needs less effort by your code than port_in/port_out.Another thing to remember, this being a work in progress and all, THEORETICALLY, my code can be utilised to use many types of ports at the same time, with the same code, the only difference being the parameters you call the port_open_xxxx with. I am still investigating this, but theoretically, my code will be able to handle TCP ports, parallel ports, serial ports and possibly more. But this investigation is on hold till this code is "finished" exclusivly for Serial-Ports. Its still under development, but Im brain-fried for the night. So I'm putting this work-in-progress up for everyones scrutiny. All the serial READing functions are fully functional, as are the WRITEing functions. (I'll be starting the the bi-directional port handling tomorrow) [EDIT] The bi-directional communications appears to be working but still needs quality testing. (Ive updated the code-block below) But both all three types are in need of further testing. Im hoping for you guys to help. Im also looking for suggestions as to improvements/additions to make this header a more complete communications suite. I know this tool is a bit of a "niche" product, but Im hoping it will get some interest. The usage is modeled on 3DGS's way of handling files. There is plenty of included documentation so there shouldnt be a problem for you to get it going. If the documentation is lacking, please let me know. [EDIT]Thanks to the newbie "druid" spotting it, but there was a bug when trying to access serial ports with a number higher than 9. This has now been fixed and the code in this post has been corrected. No changes in usage are required, and only the "port_open_???" functions have been changed.[EDIT] ALSO, if you have any code/implementation problems, let me know here, so all can see what is going on. BUT, If you are connecting to external hardware (that ISNT a PC), please let me know of any Success/Fail/Wish stories via PM. Im VERY interested to hear about it.Port_IO.H
#ifndef port_io_h
#define port_io_h
////
//
//////////////////////////////////////////////////////////////////////////////////////////
// //
// File : Port_IO.h //
// Author: EvilSOB //
// Date: 23/July/2009 //
// Updated:23/May /2010 (Failing Com ports > 9 bug fixed) //
// //
// Requirements: None (except acknex.h or litec.h of course) //
// //
// //
//======================================================================================//
// USAGE Descriptions //
//======================================================================================//
// //
// var port_open_read(char* portname, char* config); //
// //
//--------------------------------------------------------------------------------------//
// //
// Opens a communications port for reading. //
// //
//--------------------------------------------------------------------------------------//
// //
// Parameters: //
// char* portname = The windows name for the port. eg COM1. (see NOTES#1) //
// char* config = The serial port settings. eg "9600,n,8,1" (see NOTES#2) //
// //
//--------------------------------------------------------------------------------------//
// Returns: //
// NULL = Port could not be opened. //
// else = A VAR handle for the open port. //
// //
// //
// //
// //
//======================================================================================//
// //
// var port_open_write(char* portname, char* config); //
// //
//--------------------------------------------------------------------------------------//
// //
// Opens a communications port for writing. //
// //
//--------------------------------------------------------------------------------------//
// //
// Parameters: //
// char* portname = The windows name for the port. eg COM1. (see NOTES#1) //
// char* config = The serial port settings. eg "9600,n,8,1" (see NOTES#2) //
// //
//--------------------------------------------------------------------------------------//
// Returns: //
// NULL = Port could not be opened. //
// else = A VAR handle for the open port. //
// //
// //
// //
// //
//======================================================================================//
// //
// var port_open_readwrite(char* portname, char* config); //
// //
//--------------------------------------------------------------------------------------//
// //
// Opens a communications port for both reading and writing. //
// //
//--------------------------------------------------------------------------------------//
// //
// Parameters: //
// char* portname = The windows name for the port. eg COM1. (see NOTES#1) //
// char* config = The serial port settings. eg "9600,n,8,1" (see NOTES#2) //
// //
//--------------------------------------------------------------------------------------//
// Returns: //
// NULL = Port could not be opened. //
// else = A VAR handle for the open port. //
// //
// //
// //
// //
//======================================================================================//
// //
// void port_close(var port); //
// //
//--------------------------------------------------------------------------------------//
// //
// Closes a communications port that was previously opened for reading or writing. //
// //
//--------------------------------------------------------------------------------------//
// //
// Parameters: //
// char* port = The VAR handle of a previously opened communications port.//
// //
//--------------------------------------------------------------------------------------//
// Returns: NONE //
// //
// //
// //
// //
//======================================================================================//
// //
// var port_read_status(var port); //
// //
//--------------------------------------------------------------------------------------//
// //
// Checks the "IDLE" status of an open communications port. //
// //
//--------------------------------------------------------------------------------------//
// //
// Parameters: //
// char* port = The VAR handle of a previously opened communications port.//
// //
//--------------------------------------------------------------------------------------//
// Returns: TRUE = Port is IDLE. Ready for read/write. (writing untested) //
// FALSE = Port is BUSY. Waiting to Send, or Still Receiving. //
// //
// //
// //
// //
//======================================================================================//
// //
// var port_read_buffer_size(var port); //
// //
//--------------------------------------------------------------------------------------//
// //
// Checks how full the READ buffer is in bytes. //
// //
//--------------------------------------------------------------------------------------//
// //
// Parameters: //
// char* port = The VAR handle of a previously opened communications port.//
// //
//--------------------------------------------------------------------------------------//
// Returns: -1 = Port was opened for WRITE-ONLY. //
// else = Number of bytes in use. //
// //
// //
// //
// //
//======================================================================================//
// PORT READING FUNCTIONS //
//======================================================================================//
// //
// var port_read_bytes(var port, void* outdata, long bytes); //
// //
//--------------------------------------------------------------------------------------//
// //
// Reads a "block" of data into a buffer, to a maximum length of 'bytes'. //
// //
//--------------------------------------------------------------------------------------//
// //
// Parameters: //
// char* port = The VAR handle of a previously opened communications port.//
// void* outdata = A pointer to an output-buffer to store the data in. //
// long bytes = The maximum length of the output-buffer. //
// //
//--------------------------------------------------------------------------------------//
// Returns: -1 = The port handle was invalid or the Port is WRITE-ONLY. //
// 0 = There was NO data in the READ-buffer to retrieve. //
// else = The number of bytes retieved from the READ-buffer. //
// //
// //
// //
//======================================================================================//
// //
// var port_read_string(var port, STRING* outdata); //
// //
//--------------------------------------------------------------------------------------//
// //
// Reads a null-terminated string and overwrites the contents of 'outdata'. //
// //
//--------------------------------------------------------------------------------------//
// //
// Parameters: //
// char* port = The VAR handle of a previously opened communications port.//
// void* outdata = A pointer to valid STRING object to store the data in. //
// //
//--------------------------------------------------------------------------------------//
// Returns: -1 = The port handle was invalid or the Port is WRITE-ONLY. //
// 0 = There was NO data in the READ-buffer to retrieve. //
// else = The length of the retrieved string. //
// //
// //
// //
//======================================================================================//
// //
// var port_read_number(var port, DWORD* outdata); //
// //
//--------------------------------------------------------------------------------------//
// //
// Reads a 4-byte number (long,int,DWORD,var,float) and stores it at 'outdata'. //
// //
//--------------------------------------------------------------------------------------//
// //
// Parameters: //
// char* port = The VAR handle of a previously opened communications port.//
// void* outdata = A pointer to valid numeric object to store the data in. //
// //
//--------------------------------------------------------------------------------------//
// Returns: -1 = The port handle was invalid or the Port is WRITE-ONLY. //
// 0 = There was NO data in the READ-buffer to retrieve. //
// 4 = The length in bytes of the retrieved number. //
// //
// //
// //
//======================================================================================//
// //
// var port_read_double(var port, double* outdata); //
// //
//--------------------------------------------------------------------------------------//
// //
// Reads an 8-byte number (double) and stores it at 'outdata'. //
// //
//--------------------------------------------------------------------------------------//
// //
// Parameters: //
// char* port = The VAR handle of a previously opened communications port.//
// void* outdata = A pointer to valid numeric object to store the data in. //
// //
//--------------------------------------------------------------------------------------//
// Returns: -1 = The port handle was invalid or the Port is WRITE-ONLY. //
// 0 = There was NO data in the READ-buffer to retrieve. //
// 8 = The length in bytes of the retrieved number. //
// //
// //
// //
//======================================================================================//
// PORT WRITING FUNCTIONS //
//======================================================================================//
// //
// var port_write_bytes(var port, void* data, long bytes, long ms_wait); //
// //
//--------------------------------------------------------------------------------------//
// //
// Writes a "block" of data from a buffer, for a length of 'bytes'. //
// //
//--------------------------------------------------------------------------------------//
// //
// Parameters: //
// char* port = The VAR handle of a previously opened communications port.//
// void* data = A pointer to an output-buffer to send the data in. //
// long bytes = The length in bytes of the output-buffer. //
// long ms_wait = The TIMEOUT period in milliseconds after which to abort. //
// //
//--------------------------------------------------------------------------------------//
// Returns: 0 = The port handle was invalid or the Port is READ-ONLY. //
// 0 = There 'data' buffer pointer is NULL. //
// < MAX_READ_BUFFER = The number of bytes INSTANTLY sent. //
// else = A spurious huge number because the send has been delayed. //
// //
// //
// //
//======================================================================================//
// //
// var port_write_string(var port, STRING* data, long ms_wait); //
// //
//--------------------------------------------------------------------------------------//
// //
// Writes a null-terminated string from the supplied STRING object. //
// //
//--------------------------------------------------------------------------------------//
// //
// Parameters: //
// char* port = The VAR handle of a previously opened communications port.//
// void* data = A pointer to valid STRING object to send the data from. //
// long ms_wait = The TIMEOUT period in milliseconds after which to abort. //
// //
//--------------------------------------------------------------------------------------//
// Returns: 0 = The port handle was invalid or the Port is READ-ONLY. //
// 0 = There 'data' buffer pointer is NULL. //
// < MAX_READ_BUFFER = The number of bytes INSTANTLY sent. //
// else = A spurious huge number because the send has been delayed. //
// //
// //
// //
//======================================================================================//
// //
// var port_write_number(var port, DWORD* data, long ms_wait); //
// //
//--------------------------------------------------------------------------------------//
// //
// Writes a 4-byte number (long,int,DWORD,var,float) pointed to by 'outdata'. //
// //
//--------------------------------------------------------------------------------------//
// //
// Parameters: //
// char* port = The VAR handle of a previously opened communications port.//
// void* data = A pointer to valid numeric object to send the data from. //
// long ms_wait = The TIMEOUT period in milliseconds after which to abort. //
// //
//--------------------------------------------------------------------------------------//
// Returns: 0 = The port handle was invalid or the Port is READ-ONLY. //
// 0 = There 'data' buffer pointer is NULL. //
// < MAX_READ_BUFFER = The number of bytes INSTANLT sent. //
// else = A spurious huge number because the send has been delayed. //
// //
// //
// //
//======================================================================================//
// //
// var port_write_double(var port, double* data, long ms_wait); //
// //
//--------------------------------------------------------------------------------------//
// //
// Writes an 8-byte number (double) pointed to by 'outdata'. //
// //
//--------------------------------------------------------------------------------------//
// //
// Parameters: //
// char* port = The VAR handle of a previously opened communications port.//
// void* data = A pointer to valid numeric object to send the data from. //
// long ms_wait = The TIMEOUT period in milliseconds after which to abort. //
// //
//--------------------------------------------------------------------------------------//
// Returns: 0 = The port handle was invalid or the Port is READ-ONLY. //
// 0 = There 'data' buffer pointer is NULL. //
// < MAX_READ_BUFFER = The number of bytes INSTANLT sent. //
// else = A spurious huge number because the send has been delayed. //
// //
// //
// //
//======================================================================================//
//======================================================================================//
// //
// //
//======================================================================================//
//======================================================================================//
// //
// NOTES#1 :: PORT Naming Convention (from known and tested ports) //
// "COM1", "com1", "COM1:", "com1:" //
// "COM2", "com2", "COM2:", "com2:" //
// "COM3", "com3", "COM3:", "com3:" //
// "COM4", "com4", "COM4:", "com4:" //
// //
//======================================================================================//
//======================================================================================//
// //
// NOTES#2 :: SERIAL PORT SETTINGS - "WWWWW,X,Y,Z [,A]" (eg "9600,n,8,1" ) //
// //
// WWWWWW = Baud Rate (110, 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200) //
// X = Parity ( 'n' = None, 'o' = Odd, 'e' = Even, 'm' = Mark, 's' = Space ) //
// Y = Data Bits ( 5, 6, 7, 8 ) //
// Z = Stop Bits ( 1, 1.5, 2 ) //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//
// A = [ OPTIONAL ] Hardware Flow Control //
// no entry = NONE (default) (eg "9600,n,8,1" ) //
// ,x = Xon/Xoff (eg "9600,n,8,1,x" ) //
// ,p = Hardware (eg "9600,n,8,1,p" ) //
// //
// NOTE:: Option 'A' being other than default has not HARDWARE tested //
// //
//======================================================================================//
//======================================================================================//
// //
// NOTES#3 :: TWEAKABLES //
// //
#define MAX_PORTS 20 //Maximum number of open IO-Ports //
#define MAX_READ_BUFFER 10240 //Size (in bytes) in READ buffer/s (10240 = 10kb) //
// //
// //
//======================================================================================//
//======================================================================================//
//
//
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// ANY CHANGES MADE FROM HERE ON IN ARE AT YOUR OWN RISK ! PROCEED WITH CAUTION ! //
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////////////////////
// API linkages //
//////////////////////////////////////////////////////////////////////////////////////////
// //
long __stdcall _GetLastError(); //
#define PRAGMA_API _GetLastError;kernel32!GetLastError //
// //
#ifndef windows_h //
// long __stdcall GetCommState(long hFile, long lpDCB); //
// #define PRAGMA_API GetCommState;kernel32!GetCommState //
long __stdcall BuildCommDCB(char* lpDef, long lpDCB); //
#define PRAGMA_API BuildCommDCB;kernel32!BuildCommDCBA //
long __stdcall SetCommState(long hFile, long lpDCB); //
#define PRAGMA_API SetCommState;kernel32!SetCommState //
long __stdcall CreateFile(char*,long,long,long,long,long,long); //
#define PRAGMA_API CreateFile;kernel32!CreateFileA //
long __stdcall ReadFile(long,long,long,long,long); //
#define PRAGMA_API ReadFile;kernel32!ReadFile //
long __stdcall WriteFile(long,long,long,long,long); //
#define PRAGMA_API WriteFile;kernel32!WriteFile //
long __stdcall CreateEvent(long,long,long,char*); //
#define PRAGMA_API CreateEvent;kernel32!CreateEventA //
long __stdcall WaitForSingleObject(long,long); //
#define PRAGMA_API WaitForSingleObject;kernel32!WaitForSingleObject //
long __stdcall GetOverlappedResult(long,long,long,long); //
#define PRAGMA_API GetOverlappedResult;kernel32!GetOverlappedResult //
long __stdcall CloseHandle(long); //
#define PRAGMA_API CloseHandle;kernel32!CloseHandle //
long __stdcall FormatMessage(long,long,long,long,char,long,long); //
#define PRAGMA_API FormatMessage;kernel32!FormatMessageA //
#endif //windows_h //
// //
// //
//======================================================================================//
//======================================================================================//
// Port Access WORKSPACE //
//======================================================================================//
// //
long open_port[MAX_PORTS][3]; //
void open_port_startup() { var i; for(i=0;i<MAX_PORTS;i++) open_port[i][0]=0; } //
void port_read_worker(var); //function prototype for PORT-READing worker 'thread' //
// //
//////////////////////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////////////////////
// //
// PORT ACCESS FUNCTIONS //
// //
//////////////////////////////////////////////////////////////////////////////////////////
//
var port_open_read(char* portname, char* config)
{ if((!portname)||(!config)) return(0); //invalid (EMPTY) data pointer/s
STRING* dev_name = str_create("\\\\.\\"); str_cat(dev_name, _str(portname));
long *ols = malloc(sizeof(long)*6); memset(ols,0,sizeof(long)*6);
long *dcb = malloc(sizeof(long)*8); memset(dcb,0,sizeof(long)*8);
long *buff = malloc(MAX_READ_BUFFER); memset(buff,0,MAX_READ_BUFFER);
long port; var s=0, i;
port = CreateFile(dev_name.chars, 0x80000000, 0,0, 0x3, 0x40000000, 0);
str_remove(dev_name);
if(port!=-1)
{ if(BuildCommDCB( config, dcb)) //decode supplied port-config
{ if(SetCommState(port, dcb)) //configure port to new config
{ if(ols[4]=CreateEvent(NULL,true,false,NULL))
{ for(i=1;i<MAX_PORTS;i++) if(!open_port[i][0]) break;
if(i<MAX_PORTS)
{ open_port[i][0] = port;
open_port[i][1] = ols;
open_port[i][2] = buff;
ols[5] = 0;
port_read_worker(i);
return(i); //SUCCESS, return port-handle
} } } }
CloseHandle(port);
}
free(dcb); free(ols);
return(s); //file has NOT been opened.
}
//
void port_read_worker(var port)
{ if(!open_port[port][0]) return; //ABORT - invalid handle
long rport = open_port[port][0];
long* ols = (long*)open_port[port][1]; ols[5] = 0; //filled-to pos
void* data = (void*)open_port[port][2];
long fWaitingonread=false;
while(open_port[port][0])
{ if(!fWaitingonread)
{ if(!ReadFile(rport, (long)data+ols[5], MAX_READ_BUFFER-ols[5], NULL, ols))
{ if(_GetLastError()==997) fWaitingonread = true; }
else
{ fWaitingonread = false; ols[5] += ols[1]; } //INSTANT-read succeeded
}
else
if(!WaitForSingleObject(ols[4],0))
{ fWaitingonread = false; ols[5] += ols[1]; } //DELAYED-read succeeded
wait(1);
} }
//
//
//
//////////////////////////////////////////////////////////////////////////////////////////
//
var port_read_status(var port)
{ if(!open_port[port][0]) return(0); //invalid handle
long* ols = (long*)open_port[port][1];
if(WaitForSingleObject(ols[4],1)==0x00000102) return(1); //port idle
return(0); //port busy
}
//
//
//
//////////////////////////////////////////////////////////////////////////////////////////
//
var port_read_buffer_size(var port)
{ if(!open_port[port][0]) return(0); //invalid handle
long* ols = (long*)open_port[port][1];
return(ols[5]);
}
//
//
//
//////////////////////////////////////////////////////////////////////////////////////////
//
var port_open_write(char* portname, char* config)
{ if((!portname)||(!config)) return(0); //invalid (EMPTY) data pointer/s
STRING* dev_name = str_create("\\\\.\\"); str_cat(dev_name, _str(portname));
long *ols = malloc(sizeof(long)*5); memset(ols,0,sizeof(long)*5);
byte *dcb = malloc(sizeof(long)*8); memset(dcb,0,sizeof(long)*8);
long port; var s=0, i;
port = CreateFile(dev_name.chars, 0x40000000, 0,0, 0x3, 0x40000000, 0);
str_remove(dev_name);
if(port!=-1)
{ if(BuildCommDCB( config, dcb)) //decode supplied port-config
{ if(SetCommState(port, dcb)) //configure port to new config
{ if(ols[4]=CreateEvent(NULL,true,false,NULL))
{ for(i=1;i<MAX_PORTS;i++) if(!open_port[i][0]) break;
if(i<MAX_PORTS)
{ open_port[i][0] = port;
open_port[i][1] = ols;
open_port[i][2] = NULL;
ols[5] = -1;
return(i); //SUCCESS, return port-handle
} } } }
CloseHandle(port);
}
free(dcb); free(ols);
return(s); //file has NOT been opened.
}
//
//
//////////////////////////////////////////////////////////////////////////////////////////
//
var port_open_readwrite(char* portname, char* config)
{ if((!portname)||(!config)) return(0); //invalid (EMPTY) data pointer/s
STRING* dev_name = str_create("\\\\.\\"); str_cat(dev_name, _str(portname));
long *ols = malloc(sizeof(long)*5); memset(ols,0,sizeof(long)*5);
byte *dcb = malloc(sizeof(long)*8); memset(dcb,0,sizeof(long)*8);
long *buff = malloc(MAX_READ_BUFFER); memset(buff,0,MAX_READ_BUFFER);
long port; var s=0, i;
port = CreateFile(dev_name.chars, 0xC0000000, 0,0, 0x3, 0x40000000, 0);
str_remove(dev_name);
if(port!=-1)
{ if(BuildCommDCB( config, dcb)) //decode supplied port-config
{ if(SetCommState(port, dcb)) //configure port to new config
{ if(ols[4]=CreateEvent(NULL,true,false,NULL))
{ for(i=1;i<MAX_PORTS;i++) if(!open_port[i][0]) break;
if(i<MAX_PORTS)
{ open_port[i][0] = port;
open_port[i][1] = ols;
open_port[i][2] = buff;
ols[5] = 0;
port_read_worker(i);
return(i); //SUCCESS, return port-handle
} } } }
CloseHandle(port);
}
free(dcb); free(ols);
return(s); //file has NOT been opened.
}
//
//
//////////////////////////////////////////////////////////////////////////////////////////
//
void port_close(var port)
{ if(open_port[port][0])
{ //only close ports if it is still open.
long* ols = (long*)open_port[port][1];
proc_mode = PROC_LATE; wait(1);
while(ols[1]<=0) wait(1); //wait till idle
CloseHandle(open_port[port][1]); //close event
CloseHandle(open_port[port][0]); //close port
free(open_port[port][0]);
}
if(open_port[port][2]) free(open_port[port][2]);
open_port[port][0] = open_port[port][1] = open_port[port][2] = NULL;
}
//
//
//
//
//////////////////////////////////////////////////////////////////////////////////////////
// Start Port READING Functions //
//////////////////////////////////////////////////////////////////////////////////////////
//
var port_read_bytes(var port, void* outdata, long bytes)
{ if(!open_port[port][0]) return(-1); //invalid handle
if(!outdata) return(-1); //invalid pointer to buffer
long* ols = (long*)open_port[port][1];
if(!ols[5]) return(0); //No data to retrieve, buffer EMPTY
if(bytes>ols[5]) bytes = ols[5];
byte* data = (byte*)open_port[port][2];
long i; for(i=0;i<bytes;i++) if(i<MAX_READ_BUFFER) ((byte*)outdata)[i]=data[i];
for(i=0; i<(ols[5]-bytes); i++) data[i] = data[i+bytes]; ols[5] -= bytes;
for(i=ols[5]; i<MAX_READ_BUFFER; i++) data[i] = 0;
return(bytes);
}
//
//
//////////////////////////////////////////////////////////////////////////////////////////
//
var port_read_string(var port, STRING* outdata)
{ if(!open_port[port][0]) return(-1); //invalid handle
if(!outdata) return(-1); //invalid pointer to buffer
long* ols = (long*)open_port[port][1];
if(!ols[5]) return(0); //No data to retrieve, buffer EMPTY
char* data = (char*)open_port[port][2]; str_cpy(outdata, data);
long bytes; for(bytes=0;bytes<ols[5];bytes++) if(data[bytes]) break;
long i; for(i=0;i<bytes;i++) if(i<MAX_READ_BUFFER) ((byte*)outdata)[i]=data[i];
for(i=0; i<(ols[5]-bytes); i++) data[i] = data[i+bytes]; ols[5] -= bytes;
for(i=ols[5]; i<MAX_READ_BUFFER; i++) data[i] = 0;
return(bytes-1);
}
//
//
//////////////////////////////////////////////////////////////////////////////////////////
//
var port_read_number(var port, DWORD* outdata)
{ if(!open_port[port][0]) return(-1); //invalid handle
if(!outdata) return(-1); //invalid pointer to buffer
long* ols = (long*)open_port[port][1];
if(ols[5]<4) return(0); //Not enough data to retrieve a 4-byte number
byte* data = (byte*)open_port[port][2]; *outdata = ((DWORD*)data)[0];
long i; for(i=0; i<(ols[5]-4); i++) data[i] = data[i+4]; ols[5] -= 4;
for(i=ols[5]; i<MAX_READ_BUFFER; i++) data[i] = 0;
return(4);
}
//
//
//////////////////////////////////////////////////////////////////////////////////////////
//
var port_read_double(var port, double* outdata)
{ if(!open_port[port][0]) return(-1); //invalid handle
if(!outdata) return(-1); //invalid pointer to buffer
long* ols = (long*)open_port[port][1];
if(ols[5]<8) return(0); //Not enough data to retrieve a 8-byte number
byte* data = (byte*)open_port[port][2]; *outdata = ((double*)data)[0];
long i; for(i=0; i<(ols[5]-8); i++) data[i] = data[i+8]; ols[5] -= 8;
for(i=ols[5]; i<MAX_READ_BUFFER; i++) data[i] = 0;
return(8);
}
//
//
//
//////////////////////////////////////////////////////////////////////////////////////////
// Start Port WRITING Functions //
//////////////////////////////////////////////////////////////////////////////////////////
//
var port_write_bytes(var port, void* data, long bytes, long ms_wait)
{ if(!open_port[port][0]) return(0); //invalid handle
long* ols = (long*)open_port[port][1];
while((proc_status(port_write_bytes))&&(ols[1]==-1)) wait(1);
if(WriteFile(open_port[port][0], data, bytes, NULL, ols)!=-1)
{ if(_GetLastError()==997)
{ ols[1] = -1; proc_mode = PROC_LATE;
float timr=0; while(timr<ms_wait)
{ if(!WaitForSingleObject(ols[4],0)) break;
timr += time_frame*64; wait(1);
} } } }
//
//
//////////////////////////////////////////////////////////////////////////////////////////
//
var port_write_string(var port, STRING* data, long ms_wait)
{ if(!open_port[port][0]) return(0); //invalid handle
return(port_write_bytes(port, data.chars, data.length, ms_wait));
}
//
//
//////////////////////////////////////////////////////////////////////////////////////////
//
var port_write_number(var port, DWORD* data, long ms_wait)
{ if(!open_port[port][0]) return(0); //invalid handle
return(port_write_bytes(port, data, 4, ms_wait));
}
//
//
//////////////////////////////////////////////////////////////////////////////////////////
//
var port_write_double(var port, double* data, long ms_wait)
{ if(!open_port[port][0]) return(0); //invalid handle
return(port_write_bytes(port, data, 8, ms_wait));
}
//
//
//////////////////////////////////////////////////////////////////////////////////////////
//
////
#endif //port_io_h
Last edited by EvilSOB; 05/23/10 03:03. Reason: COM>9 bugfix
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
Re: Serial Communications Header
[Re: EvilSOB]
#280520
07/23/09 05:28
07/23/09 05:28
|
Joined: Dec 2008
Posts: 528 Wagga, Australia
the_mehmaster
User
|
User
Joined: Dec 2008
Posts: 528
Wagga, Australia
|
Wonderful contribution evilSOB! I'll be sure to test it out. I think you should 'ask the developers' to implement this into the engine.
Last edited by the_mehmaster; 07/23/09 05:34.
|
|
|
Re: Serial Communications Header
[Re: Joozey]
#280569
07/23/09 12:06
07/23/09 12:06
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
OP
Expert
|
OP
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
Bump!
Lead-Post updated a bit to clarify what it actually does! And its plans for the future. Sorry Joozey, I was at the end of a 12hr night-shift, and the brain was a bit blurry.
Ive updated the header again, as the "bi-directional" code is now included and looks good. But I feel like doing something else tonight, but I will still respond if anyone posts any problems/suggestions.
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
Re: Serial Communications Header
[Re: the_mehmaster]
#280813
07/24/09 10:30
07/24/09 10:30
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
OP
Expert
|
OP
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
It was tested, but only lightly. I have since discovered there was a TYPO in it which meant it only worked if you included windows.h, which I was doing accidently. To fix, replace all the #define's with what is in it now. (Ive fixed the header-post code). Or find the line long __stdcall BuildCommDCB(char lpDef, long lpDCB); and replace it with long __stdcall BuildCommDCB(char* lpDef, long lpDCB);(just one missing asterix...) I have been doing my testing using a null-model cable connecting twp PC's and using the windows program "HyperTerminal" on the 'other' PC. (The code was tested using a "factory" null-modem cable with both real serial ports and ONE type of USB->Serial adapter, that fakes a serial port very well)NOTE: I think I MAY have found a minor bug that is preventing the port from being configured correctly. This USED to work, so it shouldnt be too hard to fix. Im looking at it now.NO FAULT FOUNDthe_mehmaster :: here is a test "main" for you to try. All it does is display the last byte recieved. If you need something more 'specific' than this, let me know what you are doing... MAIN.C
#include <acknex.h>
#include <default.c>
#include "Port_IO.h"
TEXT* debug = { pos_x=20; pos_y=20; size_y=400; font="Arial#20b"; strings=20; flags=SHOW + WWRAP; }
function main()
{
wait(1); level_load(NULL); wait(1); diag("\n\n\n");
on_esc = NULL;
//
//
byte last_recieved = 0;
var hPort = port_open_read("COM1", "9600,n,8,1");
//
while(1)
{
if(port_read_bytes(hPort,&last_recieved,1))
{
str_cpy((debug.pstring)[0], "Last Byte Recieved = ");
str_cat((debug.pstring)[0], _chr(str_for_int(NULL,(long)last_recieved)));
}
if(key_esc) break;
wait(1);
}
port_close(hPort);
//
//
sys_exit("");
}
Last edited by EvilSOB; 07/29/09 23:58.
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
|