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

Subversion Repositories riscv_vhdl

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 sergeykhbr
/*
2
 *  Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
3
 *
4
 *  Licensed under the Apache License, Version 2.0 (the "License");
5
 *  you may not use this file except in compliance with the License.
6
 *  You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *  Unless required by applicable law or agreed to in writing, software
11
 *  distributed under the License is distributed on an "AS IS" BASIS,
12
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *  See the License for the specific language governing permissions and
14
 *  limitations under the License.
15 3 sergeykhbr
 */
16
 
17
#include <iostream>
18
#include <stdio.h>
19
#include <string.h>
20
#include "api_types.h"
21
#include "api_core.h"
22
#include "coreservices/iserial.h"
23
#include "comport.h"
24
 
25
 
26
namespace debugger {
27
 
28
/** Class registration in the Core */
29
REGISTER_CLASS(ComPortService)
30
 
31
ComPortService::ComPortService(const char *name)
32
    : IService(name) {
33
    registerInterface(static_cast<IThread *>(this));
34
    registerInterface(static_cast<ISerial *>(this));
35
    registerInterface(static_cast<IRawListener *>(this));
36
    registerAttribute("Enable", &isEnable_);
37
    registerAttribute("UartSim", &uartSim_);
38
    registerAttribute("LogFile", &logFile_);
39
    registerAttribute("ComPortName", &comPortName_);
40
    registerAttribute("ComPortSpeed", &comPortSpeed_);
41
 
42
    isEnable_.make_boolean(true);
43
    uartSim_.make_string("");
44
    logFile_.make_string("uart0.log");
45 4 sergeykhbr
    logfile_ = NULL;
46 3 sergeykhbr
    comPortName_.make_string("");
47
    comPortSpeed_.make_int64(115200);
48
    portListeners_.make_list(0);
49
    iuartSim_ = 0;
50
    portOpened_ = false;
51
    RISCV_mutex_init(&mutexListeners_);
52 4 sergeykhbr
    prtHandler_ = 0;
53 3 sergeykhbr
}
54
 
55
ComPortService::~ComPortService() {
56
    RISCV_mutex_destroy(&mutexListeners_);
57
    if (logfile_) {
58
        fclose(logfile_);
59
        logfile_ = NULL;
60
    }
61
}
62
 
63
void ComPortService::postinitService() {
64
    const AttributeType *glb = RISCV_get_global_settings();
65
    isSimulation_ = (*glb)["SimEnable"].to_bool();
66
 
67
    if (isSimulation_) {
68
        iuartSim_ = static_cast<ISerial *>(
69
            RISCV_get_service_iface(uartSim_.to_string(), IFACE_SERIAL));
70
        if (!iuartSim_) {
71
            RISCV_error("Can't get serial interface of UART simulator",
72
                        uartSim_.to_string());
73
            return;
74
        } else {
75
            iuartSim_->registerRawListener(static_cast<IRawListener *>(this));
76
        }
77
    }
78
 
79
    if (isEnable_.to_bool()) {
80
        if (!run()) {
81
            RISCV_error("Can't create thread.", NULL);
82
            return;
83
        }
84
    }
85
 
86
    logfile_ = 0;
87
    if (logFile_.size()) {
88
        char tst[256];
89
        RISCV_sprintf(tst, sizeof(tst), "Can't open '%s' file",
90
                      logFile_.to_string());
91
        logfile_ = fopen(logFile_.to_string(), "w");
92
    }
93
}
94
 
95 4 sergeykhbr
void ComPortService::predeleteService() {
96
    if (isSimulation_ && iuartSim_) {
97
        iuartSim_->unregisterRawListener(static_cast<IRawListener *>(this));
98
    }
99
}
100
 
101 3 sergeykhbr
//#define READ_RAWDATA_FROM_FILE
102
void ComPortService::busyLoop() {
103
    char tbuf[4096];
104
    int tbuf_cnt;
105
#ifdef READ_RAWDATA_FROM_FILE
106
    FILE *script = fopen("e:/uart0.log", "r");
107
    char logbuf[1024];
108
    int logbuf_sz;
109
#endif
110
 
111
    while (isEnabled()) {
112 4 sergeykhbr
#ifdef READ_RAWDATA_FROM_FILE
113
        logbuf_sz = fread(logbuf, 1, sizeof(logbuf), script);
114
        if (logbuf_sz) {
115
            for (unsigned i = 0; i < portListeners_.size(); i++) {
116
                IRawListener *ilstn = static_cast<IRawListener *>(
117
                                portListeners_[i].to_iface());
118
                ilstn->updateData(logbuf, logbuf_sz);
119
            }
120
        } else {
121
            fseek(script, 0, SEEK_SET);
122
        }
123
#endif
124 3 sergeykhbr
        if (!isSimulation_ && !portOpened_) {
125 4 sergeykhbr
            AttributeType settings;
126
            settings.make_list(4);
127
            settings[0u].make_int64(comPortSpeed_.to_int());
128
            int err = openPort(comPortName_.to_string(), settings);
129 3 sergeykhbr
            if (err < 0) {
130
                RISCV_error("Openning %s at %d . . .failed",
131
                        comPortName_.to_string(), comPortSpeed_.to_int());
132
                RISCV_sleep_ms(1000);
133
                continue;
134
            } else {
135
                portOpened_ = true;
136
            }
137
        }
138
        // Sending...
139
        tbuf_cnt = 0;
140
        while (!txFifo_.isEmpty()) {
141
            tbuf[tbuf_cnt++] = txFifo_.get();
142
        }
143
        if (tbuf_cnt) {
144
            if (isSimulation_ && iuartSim_) {
145
                iuartSim_->writeData(tbuf, tbuf_cnt);
146 4 sergeykhbr
            } else if (!isSimulation_ && prtHandler_) {
147
                writeSerialPort(&prtHandler_, tbuf, tbuf_cnt);
148 3 sergeykhbr
            }
149
        }
150
 
151
        // Receiveing...
152 4 sergeykhbr
        if (!isSimulation_ && prtHandler_) {
153
            tbuf_cnt = readSerialPort(&prtHandler_, tbuf,
154
                                        sizeof(tbuf) - tbuf_cnt);
155 3 sergeykhbr
            if (tbuf_cnt < 0) {
156 4 sergeykhbr
                closePort();
157 3 sergeykhbr
                portOpened_ = false;
158
                continue;
159
            }
160
        } else if (isSimulation_) {
161
            tbuf_cnt = 0;
162
            while (!rxFifo_.isEmpty()
163
                && tbuf_cnt < static_cast<int>(sizeof(tbuf) - 1)) {
164
                tbuf[tbuf_cnt++] = rxFifo_.get();
165
                tbuf[tbuf_cnt] = '\0';
166
            }
167
        }
168
        if (tbuf_cnt) {
169
            RISCV_mutex_lock(&mutexListeners_);
170
            for (unsigned i = 0; i < portListeners_.size(); i++) {
171
                IRawListener *ilstn = static_cast<IRawListener *>(
172
                                portListeners_[i].to_iface());
173
                ilstn->updateData(tbuf, tbuf_cnt);
174
            }
175
            RISCV_mutex_unlock(&mutexListeners_);
176
            if (logfile_) {
177
                fwrite(tbuf, tbuf_cnt, 1, logfile_);
178
                fflush(logfile_);
179
            }
180
        }
181
 
182
        RISCV_sleep_ms(50);
183
    }
184
}
185
 
186
int ComPortService::writeData(const char *buf, int sz) {
187
    // @todo: mutex
188
    for (int i = 0; i < sz; i++) {
189
        txFifo_.put(buf[i]);
190
    }
191
    return sz;
192
}
193
 
194
 
195
void ComPortService::registerRawListener(IFace *iface) {
196
    AttributeType t1(iface);
197
    RISCV_mutex_lock(&mutexListeners_);
198
    portListeners_.add_to_list(&t1);
199
    RISCV_mutex_unlock(&mutexListeners_);
200
}
201
 
202
void ComPortService::unregisterRawListener(IFace *iface) {
203
    RISCV_mutex_lock(&mutexListeners_);
204
    for (unsigned i = 0; i < portListeners_.size(); i++) {
205
        IFace *itmp = portListeners_[i].to_iface();
206
        if (itmp == iface) {
207
            portListeners_.remove_from_list(i);
208
            break;
209
        }
210
    }
211
    RISCV_mutex_unlock(&mutexListeners_);
212
}
213
 
214
void ComPortService::updateData(const char *buf, int buflen) {
215
    // Data from UART simulation:
216
    for (int i = 0; i < buflen; i++) {
217
        rxFifo_.put(buf[i]);
218
    }
219
}
220
 
221
}  // namespace debugger

powered by: WebSVN 2.1.0

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