aboutsummaryrefslogtreecommitdiff
path: root/testing/yup-comm/comm/serial_port.c
blob: da30fab5785440dad27e4e0ba4c08267ec15d2bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* Author: Jan Sucan */

#include <stdio.h>
#include <string.h>

#include "serial_port.h"

static HANDLE  serial_port_open_port(const char * const portName);
static BOOL    serial_port_set_timeouts(HANDLE serial_port, int ms);

LPSTR
serial_port_get_error(void)
{
    DWORD e = GetLastError();
    if (e == 0) {
      return NULL;
    }

    LPSTR msgBuff = NULL;
    FormatMessageA(
       FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
       NULL,
       e,
       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
       (LPSTR) &msgBuff,
       0,
       NULL);

    return msgBuff;
}

void
serial_port_free_error(LPSTR msg)
{
  LocalFree(msg);
}

HANDLE
serial_port_open_port(const char * const portName)
{
  HANDLE sp = INVALID_HANDLE_VALUE;
  
  // Construct Windows serial port name
  char sn[16];
  strcpy(sn, "\\\\.\\");
  strcpy(sn + strlen(sn), portName);
  // Open serial port  
  sp = CreateFile(sn,             // 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

  return sp;
}

HANDLE
serial_port_open(const char * const portName)
{
    HANDLE serial_port = serial_port_open_port(portName);
    if (serial_port == INVALID_HANDLE_VALUE) {
      return INVALID_HANDLE_VALUE;
    }
    
    // Konfiguracia
    DCB dcbSerialParams = { 0 };
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    
    if (GetCommState(serial_port, &dcbSerialParams) == 0) {
      serial_port_close(serial_port);
      return INVALID_HANDLE_VALUE;
    }
    
    dcbSerialParams.BaudRate = CBR_115200;
    dcbSerialParams.ByteSize = 8;         // Setting ByteSize = 8
    dcbSerialParams.StopBits = ONESTOPBIT;// Setting StopBits = 1
    dcbSerialParams.Parity   = NOPARITY;  // Setting Parity = None
    
    if ((SetCommState(serial_port, &dcbSerialParams) == 0)
        || (serial_port_set_timeouts(serial_port, 3000U) == 0)) {
      serial_port_close(serial_port);
      return INVALID_HANDLE_VALUE;
    }

    return serial_port;
}

void
serial_port_close(HANDLE serial_port)
{
    if (serial_port != INVALID_HANDLE_VALUE) {
      CloseHandle(serial_port);
      serial_port = INVALID_HANDLE_VALUE;
    }
}

BOOL
serial_port_set_timeouts(HANDLE serial_port, int ms)
{
    COMMTIMEOUTS timeouts;
    
    if (!GetCommTimeouts(serial_port, &timeouts)) {
      return FALSE;
    }
    
    timeouts.ReadIntervalTimeout = ms; 
    timeouts.ReadTotalTimeoutMultiplier = ms;
    timeouts.ReadTotalTimeoutConstant = 0;
    
    timeouts.WriteTotalTimeoutMultiplier = ms;
    timeouts.WriteTotalTimeoutConstant = 0;
    
    if (!SetCommTimeouts(serial_port, &timeouts)) {
      return FALSE;
    }

    return TRUE;
}

int
serial_port_write_byte(HANDLE serial_port, uint8_t * const data, unsigned size)
{   
    DWORD written = 0;

    if (!WriteFile(serial_port, data, size, &written, NULL)) {
      written = 0;
    }

    return (written != size) ? -1 : 0;
}

int
serial_port_read_byte(HANDLE serial_port, uint8_t * const byte)
{
    DWORD read;

    if (!ReadFile(serial_port, byte, sizeof(uint8_t), &read, NULL)) {
      return -1;
    }

    return (read != 0) ? 0 : -2;
}