3 \brief
\83V
\83\8a\83A
\83\8b\92Ê
\90M (Windows
\8eÀ
\91\95)
\r
5 Serial Communication Interface
\90§
\8cä
\r
7 \author Satofumi KAMIMURA
\r
9 $Id: serial_ctrl_win.c 1559 2009-12-01 13:13:08Z satofumi $
\r
12 #include "serial_ctrl.h"
\r
13 #include "serial_errno.h"
\r
14 #include "ring_buffer.h"
\r
24 static void setTimeout(serial_t *serial, int timeout)
\r
26 COMMTIMEOUTS timeouts;
\r
27 GetCommTimeouts(serial->hCom_, &timeouts);
\r
29 timeouts.ReadIntervalTimeout = (timeout == 0) ? MAXDWORD : 0;
\r
30 timeouts.ReadTotalTimeoutConstant = timeout;
\r
31 timeouts.ReadTotalTimeoutMultiplier = 0;
\r
33 SetCommTimeouts(serial->hCom_, &timeouts);
\r
37 void serial_initialize(serial_t *serial)
\r
39 serial->hCom_ = INVALID_HANDLE_VALUE;
\r
40 serial->errno_ = SerialNoError;
\r
41 serial->has_last_ch_ = False;
\r
43 ring_initialize(&serial->ring_, serial->buffer_, RingBufferSizeShift);
\r
48 int serial_connect(serial_t *serial, const char *device, long baudrate)
\r
50 // COM10
\88È
\8d~
\82Ö
\82Ì
\91Î
\89\9e\97p
\r
51 enum { NameLength = 11 };
\r
52 char adjusted_device[NameLength];
\r
54 serial_initialize(serial);
\r
56 /* COM
\83|
\81[
\83g
\82ð
\8aJ
\82 */
\r
57 _snprintf(adjusted_device, NameLength, "\\\\.\\%s", device);
\r
58 serial->hCom_ = CreateFileA(adjusted_device, GENERIC_READ | GENERIC_WRITE, 0,
\r
59 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
\r
61 if (serial->hCom_ == INVALID_HANDLE_VALUE) {
\r
62 printf("open failed: %s\n", device);
\r
66 /*
\92Ê
\90M
\83T
\83C
\83Y
\82Ì
\8dX
\90V */
\r
67 SetupComm(serial->hCom_, 4096 * 8, 4096);
\r
69 /*
\83{
\81[
\83\8c\81[
\83g
\82Ì
\95Ï
\8dX */
\r
70 serial_setBaudrate(serial, baudrate);
\r
72 /*
\83V
\83\8a\83A
\83\8b\90§
\8cä
\8d\
\91¢
\91Ì
\82Ì
\8f\89\8aú
\89» */
\r
73 serial->has_last_ch_ = False;
\r
75 /*
\83^
\83C
\83\80\83A
\83E
\83g
\82Ì
\90Ý
\92è */
\r
76 serial->current_timeout_ = 0;
\r
77 setTimeout(serial, serial->current_timeout_);
\r
84 void serial_disconnect(serial_t *serial)
\r
86 if (serial->hCom_ != INVALID_HANDLE_VALUE) {
\r
87 CloseHandle(serial->hCom_);
\r
88 serial->hCom_ = INVALID_HANDLE_VALUE;
\r
93 int serial_isConnected(const serial_t *serial)
\r
95 return (serial->hCom_ == INVALID_HANDLE_VALUE) ? 0 : 1;
\r
99 /*
\83{
\81[
\83\8c\81[
\83g
\82Ì
\95Ï
\8dX */
\r
100 int serial_setBaudrate(serial_t *serial, long baudrate)
\r
102 long baudrate_value;
\r
105 switch (baudrate) {
\r
108 baudrate_value = CBR_4800;
\r
112 baudrate_value = CBR_9600;
\r
116 baudrate_value = CBR_19200;
\r
120 baudrate_value = CBR_38400;
\r
124 baudrate_value = CBR_57600;
\r
128 baudrate_value = CBR_115200;
\r
132 baudrate_value = baudrate;
\r
135 GetCommState(serial->hCom_, &dcb);
\r
136 dcb.BaudRate = baudrate_value;
\r
138 dcb.Parity = NOPARITY;
\r
139 dcb.fParity = FALSE;
\r
140 dcb.StopBits = ONESTOPBIT;
\r
141 SetCommState(serial->hCom_, &dcb);
\r
148 int serial_send(serial_t *serial, const char *data, int data_size)
\r
152 if (data_size < 0) {
\r
156 if (! serial_isConnected(serial)) {
\r
157 return SerialConnectionFail;
\r
160 WriteFile(serial->hCom_, data, (DWORD)data_size, &n, NULL);
\r
165 static int internal_receive(char data[], int data_size_max,
\r
166 serial_t* serial, int timeout)
\r
171 if (timeout != serial->current_timeout_) {
\r
172 setTimeout(serial, timeout);
\r
173 serial->current_timeout_ = timeout;
\r
176 ReadFile(serial->hCom_, &data[filled],
\r
177 (DWORD)data_size_max - filled, &n, NULL);
\r
184 int serial_recv(serial_t *serial, char* data, int data_size_max, int timeout)
\r
190 if (data_size_max <= 0) {
\r
194 /*
\8f\91\82«
\96ß
\82µ
\82½
\82P
\95¶
\8e\9a\82ª
\82 \82ê
\82Î
\81A
\8f\91\82«
\8fo
\82· */
\r
195 if (serial->has_last_ch_) {
\r
196 data[0] = serial->last_ch_;
\r
197 serial->has_last_ch_ = False;
\r
201 if (! serial_isConnected(serial)) {
\r
205 return SerialConnectionFail;
\r
208 buffer_size = ring_size(&serial->ring_);
\r
209 read_n = data_size_max - filled;
\r
210 if (buffer_size < read_n) {
\r
211 //
\83\8a\83\93\83O
\83o
\83b
\83t
\83@
\93à
\82Ì
\83f
\81[
\83^
\82Å
\91«
\82è
\82È
\82¯
\82ê
\82Î
\81A
\83f
\81[
\83^
\82ð
\93Ç
\82Ý
\91«
\82·
\r
212 char buffer[RingBufferSize];
\r
213 int n = internal_receive(buffer,
\r
214 ring_capacity(&serial->ring_) - buffer_size,
\r
216 ring_write(&serial->ring_, buffer, n);
\r
218 buffer_size = ring_size(&serial->ring_);
\r
220 //
\83\8a\83\93\83O
\83o
\83b
\83t
\83@
\93à
\82Ì
\83f
\81[
\83^
\82ð
\95Ô
\82·
\r
221 if (read_n > buffer_size) {
\r
222 read_n = buffer_size;
\r
225 ring_read(&serial->ring_, &data[filled], read_n);
\r
229 //
\83f
\81[
\83^
\82ð
\83^
\83C
\83\80\83A
\83E
\83g
\95t
\82«
\82Å
\93Ç
\82Ý
\8fo
\82·
\r
230 filled += internal_receive(&data[filled],
\r
231 data_size_max - filled, serial, timeout);
\r
236 /*
\82P
\95¶
\8e\9a\8f\91\82«
\96ß
\82· */
\r
237 void serial_ungetc(serial_t *serial, char ch)
\r
239 serial->has_last_ch_ = True;
\r
240 serial->last_ch_ = ch;
\r
244 void serial_clear(serial_t* serial)
\r
246 PurgeComm(serial->hCom_,
\r
247 PURGE_RXABORT | PURGE_TXABORT | PURGE_RXCLEAR | PURGE_TXCLEAR);
\r
249 serial->has_last_ch_ = False;
\r