OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [libdbg64g/] [services/] [comport/] [com_win.cpp] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 sergeykhbr
/**
2
 * @file
3
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      Serial port implementation for Windows.
6
 */
7
 
8
#include "api_types.h"
9
#include "api_core.h"
10
#include "attribute.h"
11
#include "comport.h"
12
#include <winspool.h>
13
#include <cstdlib>
14
 
15
namespace debugger {
16
 
17
void ComPortService::getSerialPortList(AttributeType *list) {
18
    list->make_list(0);
19
 
20
    AttributeType portInfo;
21
    DWORD  Ports_MemSize = 0;
22
    DWORD  Ports_Count   = 0;
23
    BYTE*  lpPorts       = NULL;
24
 
25
    //Getting Ports_MemSize value...
26
    EnumPorts(NULL,
27
              1,
28
              lpPorts,
29
              0,
30
              &Ports_MemSize,
31
              &Ports_Count);
32
 
33
 
34
    //Getting lpPorts...
35
    lpPorts = new BYTE[Ports_MemSize];
36
    EnumPorts(NULL,
37
              1,
38
              lpPorts,
39
              Ports_MemSize,
40
              &Ports_MemSize,
41
              &Ports_Count);
42
 
43
 
44
    //Forming List Of Ports...
45
    DWORD dw;
46
    char temp[4] = {0};
47
    int port = -1;
48
    PORT_INFO_1 *pPortInfo;
49
    pPortInfo = (PORT_INFO_1 *)lpPorts;
50
 
51
 
52
    char comName[16];
53
    char chCom[20];
54
    size_t szComLen;
55
    for (dw = 0; dw < Ports_Count; dw++) {
56
 
57
        if (strstr(pPortInfo->pName, "com") == 0) {
58
            continue;
59
        }
60
        temp[0] = pPortInfo->pName[3];
61
                if (pPortInfo->pName[4] != ':' && pPortInfo->pName[4] != '\0') {
62
                        temp[1] = pPortInfo->pName[4];
63
        }
64
        if (pPortInfo->pName[5] != ':' && pPortInfo->pName[5] != '\0') {
65
                    temp[2] = pPortInfo->pName[5];
66
        }
67
 
68
                port = strtoul(temp, NULL, 0);;
69
        szComLen = RISCV_sprintf(chCom, sizeof(chCom),
70
                                 "\\\\.\\COM%d", port) + 1;
71
 
72
 
73
                HANDLE h = CreateFile(chCom, GENERIC_READ | GENERIC_WRITE,
74
                              0, NULL, OPEN_EXISTING,
75
                              FILE_ATTRIBUTE_NORMAL,NULL);
76
 
77
                if (h == INVALID_HANDLE_VALUE) {
78
            pPortInfo++;
79
                    continue;
80
                }
81
 
82
        portInfo.make_dict();
83
        RISCV_sprintf(comName, sizeof(comName), "'COM%d'", port);
84
        portInfo["id"].make_string(comName);
85
                list->add_to_list(&portInfo);
86
 
87
        CloseHandle(h);
88
        pPortInfo++;
89
    }
90
 
91
    delete [] lpPorts;
92
}
93
 
94
int ComPortService::openSerialPort(const char *port, int baud, void *hdl) {
95
    char chCom[20];
96
    char chConfig[64];
97
    HANDLE hFile;
98
    COMMPROP CommProp;
99
    DCB dcb;
100
    COMMTIMEOUTS CommTimeOuts;
101
    DWORD dwStoredFlags;
102
    DWORD  Errors;
103
    COMSTAT  Stat;
104
 
105
    RISCV_sprintf(chCom, sizeof(chCom), "\\\\.\\%s", port);
106
    RISCV_sprintf(chConfig, sizeof(chConfig),
107
                  "baud=%d parity=N data=8 stop=1", baud);
108
 
109
    hFile = CreateFile(chCom,
110
                        GENERIC_READ|GENERIC_WRITE,
111
                        0,//FILE_SHARE_READ|FILE_SHARE_WRITE,
112
                        NULL,
113
                            //OPEN_ALWAYS,
114
                        OPEN_EXISTING,
115
                        FILE_ATTRIBUTE_NORMAL,
116
                        NULL);
117
 
118
    *static_cast<HANDLE *>(hdl) = hFile;
119
    if (hFile == INVALID_HANDLE_VALUE) {
120
        if (GetLastError() == ERROR_ACCESS_DENIED) {
121
            RISCV_error("%s is locked by another device", chCom);
122
        } else {
123
            RISCV_error("Can't open port %s", chCom);
124
        }
125
            return -1;
126
    }
127
 
128
    // Read capabilities:
129
    GetCommProperties(hFile, &CommProp);
130
    FillMemory(&dcb, sizeof(dcb), 0);
131
 
132
    dcb.DCBlength = sizeof(dcb);
133
    if (!BuildCommDCB(chConfig, &dcb)) {
134
        RISCV_error("Can't BuildCommDCB(%s,)", chConfig);
135
        CloseHandle(hFile);
136
        return -1;
137
    }
138
    dcb.fDtrControl = DTR_CONTROL_ENABLE;
139
    dcb.fRtsControl = RTS_CONTROL_ENABLE;
140
 
141
    Sleep(100);
142
    if (!SetCommState(hFile, &dcb)) {
143
        RISCV_error("Can't set port %s state", chCom);
144
        CloseHandle(hFile);
145
        return -1;
146
    }
147
 
148
#if 0
149
    /** ...A value of MAXDWORD , combined with zero values for both
150
     * the ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members,
151
     * specifies that the read operation is to return immediately with the
152
     * characters that have already been received, even if no characters
153
     * have been received...
154
     **/
155
    CommTimeOuts.ReadIntervalTimeout             = MAXDWORD;
156
    CommTimeOuts.ReadTotalTimeoutMultiplier  = 0;
157
    CommTimeOuts.ReadTotalTimeoutConstant    = 0;
158
    CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
159
    CommTimeOuts.WriteTotalTimeoutConstant   = 0;
160
#else
161
    CommTimeOuts.ReadIntervalTimeout             = MAXDWORD;
162
    CommTimeOuts.ReadTotalTimeoutMultiplier  = MAXDWORD;//0;
163
    CommTimeOuts.ReadTotalTimeoutConstant    = 100;
164
    CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
165
    CommTimeOuts.WriteTotalTimeoutConstant   = 0;//1000;
166
#endif
167
 
168
    if(!SetCommTimeouts(hFile, &CommTimeOuts)) {
169
        RISCV_error("Can't set port %s timeouts", chCom);
170
        CloseHandle(hFile);
171
        return -1;
172
    }
173
 
174
    dwStoredFlags = EV_BREAK | EV_CTS  | EV_DSR | EV_ERR | EV_RING |
175
                EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY;
176
    if(!SetCommMask(hFile, dwStoredFlags)) {
177
        RISCV_error("Can't set mask %s", chCom);
178
        CloseHandle(hFile);
179
        return -1;
180
    }
181
 
182
    RISCV_info("Serial port %s opened", chCom);
183
 
184
    RISCV_sleep_ms(100);
185
    ClearCommError(hFile, &Errors, &Stat);
186
    PurgeComm(hFile, PURGE_RXCLEAR | PURGE_TXCLEAR);
187
    PurgeComm(hFile, PURGE_RXABORT | PURGE_TXABORT);
188
 
189
    return 0;
190
}
191
 
192
void ComPortService::closeSerialPort(void *hdl) {
193
    CloseHandle(*static_cast<HANDLE *>(hdl));
194
}
195
 
196
int ComPortService::readSerialPort(void *hdl, char *buf, int bufsz) {
197
    HANDLE hFile = *static_cast<HANDLE *>(hdl);
198
    DWORD dwBytesRead;
199
    BOOL success = ReadFile(hFile, buf, bufsz, &dwBytesRead, NULL);
200
    if (!success) {
201
        return -1;
202
    }
203
    return static_cast<int>(dwBytesRead);
204
}
205
 
206
int ComPortService::writeSerialPort(void *hdl, char *buf, int bufsz) {
207
    DWORD lpdwBytesWrittens;
208
    WriteFile(*static_cast<HANDLE *>(hdl),
209
                buf, bufsz, &lpdwBytesWrittens, NULL);
210
    return (int)lpdwBytesWrittens;
211
}
212
 
213
void ComPortService::cleanSerialPort(void *hdl) {
214
    PurgeComm(*static_cast<HANDLE *>(hdl), PURGE_TXCLEAR|PURGE_RXCLEAR);
215
}
216
 
217
}  // namespace debugger

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.