44 :
rp::hal::serial_rxtx(), _serial_handle(nullptr), _baudrate(0), _flags(0)
49 raw_serial::~raw_serial()
53 CloseHandle(_ro.hEvent);
54 CloseHandle(_wo.hEvent);
55 CloseHandle(_wait_o.hEvent);
58 bool raw_serial::open() {
return open(_portName, _baudrate, _flags); }
59 bool raw_serial::bind(
const char* portname,
_u32 baudrate,
_u32 flags)
61 strncpy(_portName, portname,
sizeof(_portName));
67 bool raw_serial::open(
const char* portname,
_u32 baudrate,
_u32 flags)
69 if (isOpened()) close();
71 _serial_handle = CreateFileA(
72 portname, GENERIC_READ | GENERIC_WRITE, 0,
nullptr, OPEN_EXISTING,
73 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
75 if (_serial_handle == INVALID_HANDLE_VALUE)
return false;
78 _serial_handle, SERIAL_RX_BUFFER_SIZE, SERIAL_TX_BUFFER_SIZE))
84 _dcb.BaudRate = baudrate;
86 _dcb.Parity = NOPARITY;
87 _dcb.StopBits = ONESTOPBIT;
88 _dcb.fDtrControl = DTR_CONTROL_ENABLE;
90 if (!SetCommState(_serial_handle, &_dcb))
96 if (!SetCommTimeouts(_serial_handle, &_co))
102 if (!SetCommMask(_serial_handle, EV_RXCHAR | EV_ERR))
110 PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR))
117 _is_serial_opened =
true;
125 void raw_serial::close()
127 SetCommMask(_serial_handle, 0);
128 ResetEvent(_wait_o.hEvent);
130 CloseHandle(_serial_handle);
131 _serial_handle = INVALID_HANDLE_VALUE;
133 _is_serial_opened =
false;
136 int raw_serial::senddata(
const unsigned char*
data,
size_t size)
139 DWORD w_len = 0, o_len = -1;
140 if (!isOpened())
return ANS_DEV_ERR;
142 if (
data ==
nullptr ||
size == 0)
return 0;
144 if (ClearCommError(_serial_handle, &
error,
nullptr) &&
error > 0)
145 PurgeComm(_serial_handle, PURGE_TXABORT | PURGE_TXCLEAR);
147 if (!WriteFile(_serial_handle,
data,
size, &w_len, &_wo))
148 if (GetLastError() != ERROR_IO_PENDING) w_len = ANS_DEV_ERR;
153 int raw_serial::recvdata(
unsigned char*
data,
size_t size)
155 if (!isOpened())
return 0;
158 if (!ReadFile(_serial_handle,
data,
size, &r_len, &_ro))
160 if (GetLastError() == ERROR_IO_PENDING)
162 if (!GetOverlappedResult(_serial_handle, &_ro, &r_len,
FALSE))
164 if (GetLastError() != ERROR_IO_INCOMPLETE) r_len = 0;
174 void raw_serial::flush(
_u32 flags)
178 PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
181 int raw_serial::waitforsent(
_u32 timeout,
size_t* returned_size)
183 if (!isOpened())
return ANS_DEV_ERR;
185 _word_size_t ans = 0;
187 if (WaitForSingleObject(_wo.hEvent, timeout) == WAIT_TIMEOUT)
192 if (!GetOverlappedResult(_serial_handle, &_wo, &w_len,
FALSE))
197 if (returned_size) *returned_size = w_len;
201 int raw_serial::waitforrecv(
_u32 timeout,
size_t* returned_size)
203 if (!isOpened())
return -1;
205 _word_size_t ans = 0;
207 if (WaitForSingleObject(_ro.hEvent, timeout) == WAIT_TIMEOUT)
211 if (!GetOverlappedResult(_serial_handle, &_ro, &r_len,
FALSE))
215 if (returned_size) *returned_size = r_len;
219 int raw_serial::waitfordata(
220 size_t data_count,
_u32 timeout,
size_t* returned_size)
227 if (returned_size ==
nullptr) returned_size = (
size_t*)&dummy_length;
231 size_t rxqueue_remaining = rxqueue_count();
232 if (rxqueue_remaining >= data_count)
234 *returned_size = rxqueue_remaining;
242 SetCommMask(_serial_handle, EV_RXCHAR | EV_ERR);
243 if (!WaitCommEvent(_serial_handle, &msk, &_wait_o))
245 if (GetLastError() == ERROR_IO_PENDING)
247 if (WaitForSingleObject(_wait_o.hEvent, timeout) ==
254 GetOverlappedResult(_serial_handle, &_wait_o, &
length,
TRUE);
256 ::ResetEvent(_wait_o.hEvent);
260 ClearCommError(_serial_handle, &
error, &stat);
261 *returned_size = stat.cbInQue;
269 ClearCommError(_serial_handle, &
error, &stat);
274 ClearCommError(_serial_handle, &
error, &stat);
275 if (stat.cbInQue >= data_count)
277 *returned_size = stat.cbInQue;
286 size_t raw_serial::rxqueue_count()
288 if (!isOpened())
return 0;
293 if (ClearCommError(_serial_handle, &
error, &com_stat) &&
error > 0)
295 PurgeComm(_serial_handle, PURGE_RXABORT | PURGE_RXCLEAR);
298 return com_stat.cbInQue;
301 void raw_serial::setDTR()
303 if (!isOpened())
return;
305 EscapeCommFunction(_serial_handle, SETDTR);
308 void raw_serial::clearDTR()
310 if (!isOpened())
return;
312 EscapeCommFunction(_serial_handle, CLRDTR);
315 void raw_serial::_init()
317 memset(&_dcb, 0,
sizeof(_dcb));
318 _dcb.DCBlength =
sizeof(_dcb);
319 _serial_handle = INVALID_HANDLE_VALUE;
320 memset(&_co, 0,
sizeof(_co));
321 _co.ReadIntervalTimeout = 0;
322 _co.ReadTotalTimeoutMultiplier = 0;
323 _co.ReadTotalTimeoutConstant = 0;
324 _co.WriteTotalTimeoutMultiplier = 0;
325 _co.WriteTotalTimeoutConstant = 0;
327 memset(&_ro, 0,
sizeof(_ro));
328 memset(&_wo, 0,
sizeof(_wo));
329 memset(&_wait_o, 0,
sizeof(_wait_o));
331 _ro.hEvent = CreateEvent(
nullptr,
TRUE,
FALSE,
nullptr);
332 _wo.hEvent = CreateEvent(
nullptr,
TRUE,
FALSE,
nullptr);
333 _wait_o.hEvent = CreateEvent(
nullptr,
TRUE,
FALSE,
nullptr);
static serial_rxtx * CreateRxTx()
static void ReleaseRxTx(serial_rxtx *)
GLsizei GLsizei GLenum GLenum const GLvoid * data
GLuint GLsizei GLsizei * length