-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 4a36734
Showing
3 changed files
with
349 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <strings.h> | ||
|
||
#include "seriallib.h" | ||
|
||
int main (int argc, char *argv []) { | ||
|
||
char *port = malloc (sizeof (char) * 12); // Just for "straight to test purposes", in production, use the port detection functions instead | ||
strcpy(port, "\\\\.\\COM5"); | ||
|
||
//------------------------------------ Stand-alone function to do their straight work the most synchronous way ------------------------------------ | ||
|
||
AVAILABLE_PORTS *ports; // Initializing the struct values | ||
ports = malloc(sizeof(AVAILABLE_PORTS)); | ||
|
||
updateAvailablePortsInfo(ports); // Setup/load time, the function will update the living struct | ||
|
||
|
||
|
||
DATA_BUFFER *wbuffer; // Initializing the struct values | ||
wbuffer = malloc(sizeof(DATA_BUFFER)); // Buffer Containing Txed Data | ||
strcpy(wbuffer->data, "Hello World"); | ||
|
||
writeSerialPort(port, 9600, wbuffer); | ||
printf("TX Code %i - %s Data -> %s\n", wbuffer->code, wbuffer->message, wbuffer->data); | ||
|
||
|
||
|
||
DATA_BUFFER *rbuffer; // Initializing the struct values | ||
rbuffer = malloc(sizeof(DATA_BUFFER)); // Buffer Containing Rxed Data | ||
|
||
while (1) { | ||
listenSerialPort(port, 9600, rbuffer); | ||
printf("RX Code %i - %s Data -> %s\n", rbuffer->code, rbuffer->message, rbuffer->data); | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,284 @@ | ||
#if defined(_WIN32) || defined(_WIN64) | ||
#include <windows.h> | ||
#endif | ||
|
||
#include "seriallib.h" | ||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <strings.h> | ||
|
||
char* formatSerialPortName(int num) { | ||
|
||
#if defined(_WIN32) || defined(_WIN64) | ||
|
||
char *data = malloc (sizeof (char) * 15); // Allocates memory to handle all possible argument numbers between 1 and 256 | ||
char *str = malloc (sizeof (char) * 4); // Allocates memory just to cast the given argument number into a char | ||
sprintf(str, "%d", num); // Casts the int to char | ||
strcpy(data, "\\\\.\\COM"); // Copies the port base name into the previously allocated space | ||
strcat(data, str); // Concatenates the newly casted char with the port base name | ||
|
||
return data; | ||
|
||
#elif defined(__linux__) || defined(__linux) | ||
// No code yet | ||
#endif | ||
|
||
} | ||
|
||
int getSerialPortAvailability(char *portName) { | ||
|
||
#if defined(_WIN32) || defined(_WIN64) | ||
|
||
HANDLE hComm; | ||
|
||
/*----------------------------------- Opening the Serial Port --------------------------------------------*/ | ||
hComm = CreateFile(portName, // 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) { | ||
printf("Error! CreateFile() %s\n", portName); | ||
return 0; | ||
} | ||
|
||
CloseHandle(hComm); //Closing the Serial Port | ||
|
||
return 1; | ||
|
||
#elif defined(__linux__) || defined(__linux) | ||
// No code yet | ||
#endif | ||
} | ||
|
||
void updateAvailablePortsInfo(AVAILABLE_PORTS *ports) { | ||
|
||
#if defined(_WIN32) || defined(_WIN64) | ||
|
||
ports->openQuantity = 0; // Struct initialization | ||
// int array[S_PORTS] = { 0 }; // As the memory was already allocated/initialized for the array, it can only be updated by whole copying a new one over the existant one | ||
// memcpy(ports->statusList, array, sizeof array); // These two lines are just for good practices, they are not actually needed | ||
|
||
int i, status; // These two variables are just for loop actions control | ||
|
||
for (i = 0; i < S_PORTS; ++i) { | ||
status = getSerialPortAvailability(formatSerialPortName(i)); | ||
if (status != 0) { // Zero status means that the port is not available | ||
ports->openQuantity++; // Updates the number of open ports | ||
ports->statusList[i] = status; // Records which port got its status different from zero on its proper position of number array | ||
status = 0; // Clear the status value for the next iteration | ||
} | ||
} | ||
|
||
#elif defined(__linux__) || defined(__linux) | ||
// No code yet | ||
#endif | ||
} | ||
|
||
void writeSerialPort(char *portName, int baudRate, DATA_BUFFER *buffer) { | ||
|
||
#if defined(_WIN32) || defined(_WIN64) | ||
|
||
HANDLE hComm; // Handle to the Serial port | ||
BOOL Status; | ||
|
||
buffer->code = 0; // Default code is zero | ||
*buffer->message = 0; // Straightest way to erase all pointer content | ||
|
||
/*----------------------------------- Opening the Serial Port --------------------------------------------*/ | ||
hComm = CreateFile(portName, // Name of the Port to be Opened | ||
GENERIC_READ | GENERIC_WRITE, // Read/Write Access | ||
0, // No Sharing, ports cant be shared | ||
NULL, // No Security | ||
OPEN_EXISTING, // Open existing port only | ||
0, // Non Overlapped I/O | ||
NULL); // Null for Comm Devices | ||
|
||
if (hComm == INVALID_HANDLE_VALUE) { | ||
strcpy(buffer->message, "Error! CreateFile() "); | ||
strcat(buffer->message, portName); | ||
return; | ||
} | ||
|
||
/*------------------------------- Setting the Parameters for the SerialPort ------------------------------*/ | ||
DCB dcbSerialParams = { 0 }; // Initializing DCB structure | ||
dcbSerialParams.DCBlength = sizeof(dcbSerialParams); | ||
|
||
Status = GetCommState(hComm, &dcbSerialParams); //retreives the current settings | ||
|
||
if (Status == FALSE) { | ||
strcpy(buffer->message, "Error! GetCommState() "); | ||
strcat(buffer->message, portName); | ||
return; | ||
} | ||
|
||
dcbSerialParams.BaudRate = baudRate; // Setting BaudRate = CBR_<baud_rate_number> | ||
dcbSerialParams.ByteSize = 8; // Setting ByteSize = 8 | ||
dcbSerialParams.StopBits = ONESTOPBIT; // Setting StopBits = 1 | ||
dcbSerialParams.Parity = NOPARITY; // Setting Parity = None | ||
|
||
Status = SetCommState(hComm, &dcbSerialParams); //Configuring the port according to settings in DCB | ||
|
||
if (Status == FALSE) { | ||
strcpy(buffer->message, "Error! GetCommState() "); | ||
strcat(buffer->message, portName); | ||
return; | ||
} | ||
|
||
/*------------------------------------ Setting Timeouts --------------------------------------------------*/ | ||
COMMTIMEOUTS timeouts = { 0 }; | ||
|
||
timeouts.ReadIntervalTimeout = 50; | ||
timeouts.ReadTotalTimeoutConstant = 50; | ||
timeouts.ReadTotalTimeoutMultiplier = 10; | ||
timeouts.WriteTotalTimeoutConstant = 50; | ||
timeouts.WriteTotalTimeoutMultiplier = 10; | ||
|
||
if (SetCommTimeouts(hComm, &timeouts) == FALSE) { | ||
strcpy(buffer->message, "Error! SetCommState() "); | ||
strcat(buffer->message, portName); | ||
return; | ||
} | ||
|
||
/*----------------------------- Writing a Character to Serial Port----------------------------------------*/ | ||
DWORD dNoOFBytestoWrite; // No of bytes to write into the port | ||
DWORD dNoOfBytesWritten = 0; // No of bytes written to the port | ||
|
||
dNoOFBytestoWrite = sizeof(buffer->message); // Calculating the no of bytes to write into the port | ||
|
||
Status = WriteFile(hComm, // Handle to the Serialport | ||
buffer->message, // Data to be written to the port (should be char or byte array, otherwise write will fail) | ||
dNoOFBytestoWrite, // No of bytes to write into the port | ||
&dNoOfBytesWritten, // No of bytes written to the port | ||
NULL); | ||
|
||
if (Status != TRUE) { | ||
strcpy(buffer->message, "Error "); | ||
char *str = malloc (sizeof (char) * 4); // Allocates memory just to cast the given argument number into a char | ||
sprintf(str, "%d", GetLastError()); // Casts the int to char | ||
strcat(buffer->message, str); | ||
strcat(buffer->message, " WriteFile() "); | ||
strcat(buffer->message, portName); | ||
return; | ||
} | ||
|
||
buffer->code = 1; | ||
|
||
CloseHandle(hComm); // Closing the Serial Port | ||
return; | ||
|
||
#elif defined(__linux__) || defined(__linux) | ||
// No code yet | ||
#endif | ||
} | ||
|
||
void listenSerialPort(char *portName, int baudRate, DATA_BUFFER *buffer) { | ||
|
||
#if defined(_WIN32) || defined(_WIN64) | ||
|
||
HANDLE hComm; // Handle to the Serial port | ||
BOOL Status; // Status of the various operations | ||
DWORD dwEventMask; // Event mask to trigger | ||
char TempChar; // Temperory Character | ||
DWORD NoBytesRead; // Bytes read by ReadFile() | ||
int i = 0; | ||
|
||
buffer->code = 0; // Default code is zero | ||
*buffer->message = 0; // Straightest way to erase all pointer content | ||
|
||
/*----------------------------------- Opening the Serial Port --------------------------------------------*/ | ||
hComm = CreateFile(portName, // Name of the Port to be Opened | ||
GENERIC_READ | GENERIC_WRITE, // Read/Write Access | ||
0, // No Sharing, ports cant be shared | ||
NULL, // No Security | ||
OPEN_EXISTING, // Open existing port only | ||
0, // Non Overlapped I/O | ||
NULL); // Null for Comm Devices | ||
|
||
if (hComm == INVALID_HANDLE_VALUE) { | ||
strcpy(buffer->message, "Error! CreateFile() "); | ||
strcat(buffer->message, portName); | ||
return; | ||
} | ||
|
||
/*------------------------------- Setting the Parameters for the SerialPort ------------------------------*/ | ||
DCB dcbSerialParams = { 0 }; // Initializing DCB structure | ||
dcbSerialParams.DCBlength = sizeof(dcbSerialParams); | ||
|
||
Status = GetCommState(hComm, &dcbSerialParams); //retreives the current settings | ||
|
||
if (Status == FALSE) { | ||
strcpy(buffer->message, "Error! GetCommState() "); | ||
strcat(buffer->message, portName); | ||
return; | ||
} | ||
|
||
dcbSerialParams.BaudRate = baudRate; // Setting BaudRate = CBR_<baud_rate_number> | ||
dcbSerialParams.ByteSize = 8; // Setting ByteSize = 8 | ||
dcbSerialParams.StopBits = ONESTOPBIT; // Setting StopBits = 1 | ||
dcbSerialParams.Parity = NOPARITY; // Setting Parity = None | ||
|
||
Status = SetCommState(hComm, &dcbSerialParams); //Configuring the port according to settings in DCB | ||
|
||
if (Status == FALSE) { | ||
strcpy(buffer->message, "Error! SetCommState() "); | ||
strcat(buffer->message, portName); | ||
return; | ||
} | ||
|
||
/*------------------------------------ Setting Timeouts --------------------------------------------------*/ | ||
COMMTIMEOUTS timeouts = { 0 }; | ||
|
||
timeouts.ReadIntervalTimeout = 50; | ||
timeouts.ReadTotalTimeoutConstant = 50; | ||
timeouts.ReadTotalTimeoutMultiplier = 10; | ||
timeouts.WriteTotalTimeoutConstant = 50; | ||
timeouts.WriteTotalTimeoutMultiplier = 10; | ||
|
||
if (SetCommTimeouts(hComm, &timeouts) == FALSE) { | ||
strcpy(buffer->message, "Error! SetCommTimeouts() "); | ||
strcat(buffer->message, portName); | ||
return; | ||
} | ||
|
||
/*------------------------------------ Setting Receive Mask ----------------------------------------------*/ | ||
Status = SetCommMask(hComm, EV_RXCHAR); //Configure Windows to Monitor the serial device for Character Reception | ||
|
||
if (Status == FALSE) { | ||
strcpy(buffer->message, "Error! SetCommMask() "); | ||
strcat(buffer->message, portName); | ||
return; | ||
} | ||
|
||
/*------------------------------------ Setting WaitComm() Event ----------------------------------------*/ | ||
Status = WaitCommEvent(hComm, &dwEventMask, NULL); //Wait for the character to be received | ||
|
||
/*-------------------------- Program will Wait here till a Character is received ------------------------*/ | ||
if (Status == FALSE) { | ||
strcpy(buffer->message, "Error! WaitCommEvent() "); | ||
strcat(buffer->message, portName); | ||
return; | ||
} | ||
else { //If WaitCommEvent() == True, read the RXed data using ReadFile(); | ||
buffer->code = 1; | ||
do { | ||
Status = ReadFile(hComm, &TempChar, sizeof(TempChar), &NoBytesRead, NULL); | ||
// SerialBuffer[i] = TempChar; | ||
buffer->data[i] = TempChar; | ||
i++; | ||
} | ||
// while (NoBytesRead > 0 && i < S_BUFFER); // Need improvement in logic | ||
while (i < S_BUFFER); | ||
|
||
} | ||
|
||
CloseHandle(hComm); //Closing the Serial Port | ||
return; | ||
|
||
#elif defined(__linux__) || defined(__linux) | ||
// No code yet | ||
#endif | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#ifndef SERIALLIB_H | ||
#define SERIALLIB_H | ||
|
||
#define S_PORTS 256 | ||
#define S_BUFFER 256 | ||
|
||
// These two variables control how many and which ports are open, if any | ||
typedef struct AVAILABLE_PORTS { | ||
int openQuantity; | ||
int statusList[S_PORTS]; | ||
} AVAILABLE_PORTS; | ||
|
||
// This struct is a library standard to send/receive the serial data, this way any runtime error messages can reach the main code | ||
typedef struct DATA_BUFFER { | ||
int code; | ||
char message[32]; | ||
char data[S_BUFFER]; | ||
} DATA_BUFFER; | ||
|
||
char* formatSerialPortName (int num); | ||
int getSerialPortAvailability (char *portName); | ||
void updateAvailablePortsInfo (AVAILABLE_PORTS *ports); | ||
void writeSerialPort (char *portName, int baudRate, DATA_BUFFER *buffer); | ||
void listenSerialPort (char *portName, int baudRate, DATA_BUFFER *buffer); | ||
|
||
#endif |