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 2

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

Line No. Rev Author Line
1 2 sergeykhbr
/**
2
 * @file
3
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      COM-port class implementation.
6
 */
7
 
8
#include <iostream>
9
#include <stdio.h>
10
#include <string.h>
11
#include "api_types.h"
12
#include "api_core.h"
13
#include "coreservices/iserial.h"
14
#include "coreservices/isignal.h"
15
#include "comport.h"
16
 
17
 
18
namespace debugger {
19
 
20
/** Class registration in the Core */
21
REGISTER_CLASS(ComPortService)
22
 
23
ComPortService::ComPortService(const char *name)
24
    : IService(name) {
25
    registerInterface(static_cast<IThread *>(this));
26
    registerInterface(static_cast<ISerial *>(this));
27
    registerInterface(static_cast<IRawListener *>(this));
28
    registerAttribute("Enable", &isEnable_);
29
    registerAttribute("UartSim", &uartSim_);
30
    registerAttribute("LogFile", &logFile_);
31
    registerAttribute("ComPortName", &comPortName_);
32
    registerAttribute("ComPortSpeed", &comPortSpeed_);
33
 
34
    isEnable_.make_boolean(true);
35
    uartSim_.make_string("");
36
    logFile_.make_string("uart0.log");
37
    comPortName_.make_string("");
38
    comPortSpeed_.make_int64(115200);
39
    portListeners_.make_list(0);
40
    iuartSim_ = 0;
41
    portOpened_ = false;
42
    RISCV_mutex_init(&mutexListeners_);
43
}
44
 
45
ComPortService::~ComPortService() {
46
    RISCV_mutex_destroy(&mutexListeners_);
47
    if (logfile_) {
48
        fclose(logfile_);
49
        logfile_ = NULL;
50
    }
51
}
52
 
53
void ComPortService::postinitService() {
54
    const AttributeType *glb = RISCV_get_global_settings();
55
    isSimulation_ = (*glb)["SimEnable"].to_bool();
56
 
57
    if (isSimulation_) {
58
        iuartSim_ = static_cast<ISerial *>(
59
            RISCV_get_service_iface(uartSim_.to_string(), IFACE_SERIAL));
60
        if (!iuartSim_) {
61
            RISCV_error("Can't get serial interface of UART simulator",
62
                        uartSim_.to_string());
63
            return;
64
        } else {
65
            iuartSim_->registerRawListener(static_cast<IRawListener *>(this));
66
        }
67
    }
68
 
69
    if (isEnable_.to_bool()) {
70
        if (!run()) {
71
            RISCV_error("Can't create thread.", NULL);
72
            return;
73
        }
74
    }
75
 
76
    logfile_ = 0;
77
    if (logFile_.size()) {
78
        char tst[256];
79
        RISCV_sprintf(tst, sizeof(tst), "Can't open '%s' file",
80
                      logFile_.to_string());
81
        logfile_ = fopen(logFile_.to_string(), "w");
82
    }
83
}
84
 
85
void ComPortService::busyLoop() {
86
    char tbuf[4096];
87
    int tbuf_cnt;
88
 
89
    while (isEnabled()) {
90
        if (!isSimulation_ && !portOpened_) {
91
            int err = openSerialPort(comPortName_.to_string(),
92
                comPortSpeed_.to_int(), &hPort_);
93
            if (err < 0) {
94
                RISCV_error("Openning %s at %d . . .failed",
95
                        comPortName_.to_string(), comPortSpeed_.to_int());
96
                RISCV_sleep_ms(1000);
97
                continue;
98
            } else {
99
                portOpened_ = true;
100
            }
101
        }
102
        // Sending...
103
        tbuf_cnt = 0;
104
        while (!txFifo_.isEmpty()) {
105
            tbuf[tbuf_cnt++] = txFifo_.get();
106
        }
107
        if (tbuf_cnt) {
108
            if (isSimulation_ && iuartSim_) {
109
                iuartSim_->writeData(tbuf, tbuf_cnt);
110
            } else if (!isSimulation_ && hPort_) {
111
                writeSerialPort(&hPort_, tbuf, tbuf_cnt);
112
            }
113
        }
114
 
115
        // Receiveing...
116
        if (!isSimulation_ && hPort_) {
117
            tbuf_cnt = readSerialPort(&hPort_, tbuf, sizeof(tbuf) - tbuf_cnt);
118
            if (tbuf_cnt < 0) {
119
                closeSerialPort(&hPort_);
120
                portOpened_ = false;
121
                continue;
122
            }
123
        } else if (isSimulation_) {
124
            tbuf_cnt = 0;
125
            while (!rxFifo_.isEmpty()
126
                && tbuf_cnt < static_cast<int>(sizeof(tbuf) - 1)) {
127
                tbuf[tbuf_cnt++] = rxFifo_.get();
128
                tbuf[tbuf_cnt] = '\0';
129
            }
130
        }
131
        if (tbuf_cnt) {
132
            RISCV_mutex_lock(&mutexListeners_);
133
            for (unsigned i = 0; i < portListeners_.size(); i++) {
134
                IRawListener *ilstn = static_cast<IRawListener *>(
135
                                portListeners_[i].to_iface());
136
                ilstn->updateData(tbuf, tbuf_cnt);
137
            }
138
            RISCV_mutex_unlock(&mutexListeners_);
139
            if (logfile_) {
140
                fwrite(tbuf, tbuf_cnt, 1, logfile_);
141
                fflush(logfile_);
142
            }
143
        }
144
 
145
        RISCV_sleep_ms(50);
146
    }
147
}
148
 
149
int ComPortService::writeData(const char *buf, int sz) {
150
    // @todo: mutex
151
    for (int i = 0; i < sz; i++) {
152
        txFifo_.put(buf[i]);
153
    }
154
    return sz;
155
}
156
 
157
 
158
void ComPortService::registerRawListener(IFace *iface) {
159
    AttributeType t1(iface);
160
    RISCV_mutex_lock(&mutexListeners_);
161
    portListeners_.add_to_list(&t1);
162
    RISCV_mutex_unlock(&mutexListeners_);
163
}
164
 
165
void ComPortService::unregisterRawListener(IFace *iface) {
166
    RISCV_mutex_lock(&mutexListeners_);
167
    for (unsigned i = 0; i < portListeners_.size(); i++) {
168
        IFace *itmp = portListeners_[i].to_iface();
169
        if (itmp == iface) {
170
            portListeners_.remove_from_list(i);
171
            break;
172
        }
173
    }
174
    RISCV_mutex_unlock(&mutexListeners_);
175
}
176
 
177
void ComPortService::updateData(const char *buf, int buflen) {
178
    // Data from UART simulation:
179
    for (int i = 0; i < buflen; i++) {
180
        rxFifo_.put(buf[i]);
181
    }
182
}
183
 
184
}  // namespace debugger

powered by: WebSVN 2.1.0

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