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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [socsim_plugin/] [uart.cpp] - Diff between revs 2 and 4

Show entire file | Details | Blame | View Log

Rev 2 Rev 4
Line 1... Line 1...
/**
/*
 * @file
 *  Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
 *
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
 *  Licensed under the Apache License, Version 2.0 (the "License");
 * @brief      UART functional model.
 *  you may not use this file except in compliance with the License.
 
 *  You may obtain a copy of the License at
 
 *
 
 *      http://www.apache.org/licenses/LICENSE-2.0
 
 *
 
 *  Unless required by applicable law or agreed to in writing, software
 
 *  distributed under the License is distributed on an "AS IS" BASIS,
 
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
 *  See the License for the specific language governing permissions and
 
 *  limitations under the License.
 */
 */
 
 
#include "api_core.h"
#include "api_core.h"
#include "uart.h"
#include "uart.h"
 
 
Line 22... Line 31...
 
 
 
 
UART::UART(const char *name)  : IService(name) {
UART::UART(const char *name)  : IService(name) {
    registerInterface(static_cast<IMemoryOperation *>(this));
    registerInterface(static_cast<IMemoryOperation *>(this));
    registerInterface(static_cast<ISerial *>(this));
    registerInterface(static_cast<ISerial *>(this));
    registerAttribute("BaseAddress", &baseAddress_);
 
    registerAttribute("Length", &length_);
 
    registerAttribute("IrqLine", &irqLine_);
 
    registerAttribute("IrqControl", &irqctrl_);
    registerAttribute("IrqControl", &irqctrl_);
 
    registerAttribute("AutoTestEna", &autoTestEna_);
 
    registerAttribute("TestCases", &testCases_);
 
 
    baseAddress_.make_uint64(0);
 
    length_.make_uint64(0);
 
    irqLine_.make_uint64(0);
 
    irqctrl_.make_string("");
 
    listeners_.make_list(0);
    listeners_.make_list(0);
    RISCV_mutex_init(&mutexListeners_);
    RISCV_mutex_init(&mutexListeners_);
 
 
    memset(&regs_, 0, sizeof(regs_));
    memset(&regs_, 0, sizeof(regs_));
    regs_.status = UART_STATUS_TX_EMPTY | UART_STATUS_RX_EMPTY;
    regs_.status = UART_STATUS_TX_EMPTY | UART_STATUS_RX_EMPTY;
 
 
    p_rx_wr_ = rxfifo_;
    p_rx_wr_ = rxfifo_;
    p_rx_rd_ = rxfifo_;
    p_rx_rd_ = rxfifo_;
    rx_total_ = 0;
    rx_total_ = 0;
 
    pautotest_ = NULL;
}
}
 
 
UART::~UART() {
UART::~UART() {
    RISCV_mutex_destroy(&mutexListeners_);
    RISCV_mutex_destroy(&mutexListeners_);
 
    if (pautotest_) {
 
        delete pautotest_;
 
    }
}
}
 
 
void UART::postinitService() {
void UART::postinitService() {
    iwire_ = static_cast<IWire *>(
    iwire_ = static_cast<IWire *>(
        RISCV_get_service_iface(irqctrl_.to_string(), IFACE_WIRE));
        RISCV_get_service_port_iface(irqctrl_[0u].to_string(),
 
                                     irqctrl_[1].to_string(),
 
                                     IFACE_WIRE));
    if (!iwire_) {
    if (!iwire_) {
        RISCV_error("Can't find IWire interface %s", irqctrl_.to_string());
        RISCV_error("Can't find IWire interface %s", irqctrl_[0u].to_string());
 
    }
 
    if (autoTestEna_.to_bool()) {
 
        pautotest_ = new AutoTest(static_cast<ISerial *>(this), &testCases_);
    }
    }
}
}
 
 
int UART::writeData(const char *buf, int sz) {
int UART::writeData(const char *buf, int sz) {
    if (sz > (RX_FIFO_SIZE - rx_total_)) {
    if (sz > (RX_FIFO_SIZE - rx_total_)) {
Line 67... Line 80...
            p_rx_wr_ = rxfifo_;
            p_rx_wr_ = rxfifo_;
        }
        }
    }
    }
 
 
    if (regs_.status & UART_CONTROL_RX_IRQ_ENA) {
    if (regs_.status & UART_CONTROL_RX_IRQ_ENA) {
        iwire_->raiseLine(irqLine_.to_int());
        iwire_->raiseLine();
    }
    }
    return sz;
    return sz;
}
}
 
 
void UART::registerRawListener(IFace *listener) {
void UART::registerRawListener(IFace *listener) {
Line 91... Line 104...
            break;
            break;
        }
        }
    }
    }
}
}
 
 
void UART::b_transport(Axi4TransactionType *trans) {
void UART::getListOfPorts(AttributeType *list) {
 
    list->make_list(0);
 
}
 
 
 
int UART::openPort(const char *port, AttributeType settings) {
 
    return 0;
 
}
 
 
 
void UART::closePort() {
 
}
 
 
 
 
 
ETransStatus UART::b_transport(Axi4TransactionType *trans) {
    uint64_t mask = (length_.to_uint64() - 1);
    uint64_t mask = (length_.to_uint64() - 1);
    uint64_t off = ((trans->addr - getBaseAddress()) & mask) / 4;
    uint64_t off = ((trans->addr - getBaseAddress()) & mask) / 4;
    char wrdata;
    char wrdata;
    trans->response = MemResp_Valid;
    trans->response = MemResp_Valid;
    if (trans->action == MemAction_Write) {
    if (trans->action == MemAction_Write) {
Line 163... Line 188...
            default:
            default:
                trans->rpayload.b32[i] = ~0;
                trans->rpayload.b32[i] = ~0;
            }
            }
        }
        }
    }
    }
 
    return TRANS_OK;
 
}
 
 
 
/**
 
 * CPU validation purpose. Reaction on keyboard interrupt:
 
 */
 
 
 
UART::AutoTest::AutoTest(ISerial *parent, AttributeType *tests) {
 
    parent_ = parent;
 
    tests_ = *tests;
 
    testcnt_ = 0;
 
    IClock *iclk = static_cast<IClock *>(
 
            RISCV_get_service_iface("core0", IFACE_CLOCK));
 
    if (iclk && tests_.is_list() && tests_.size()) {
 
        const AttributeType &t0 = tests_[testcnt_];
 
        if (t0.size() == 2) {
 
            iclk->registerStepCallback(static_cast<IClockListener *>(this),
 
                                       t0[0u].to_uint64());
 
        }
 
    }
 
}
 
 
 
void UART::AutoTest::stepCallback(uint64_t t) {
 
    const AttributeType &tn = tests_[testcnt_];
 
    char msg[64];
 
    int msglen = 0;
 
    const char *pbuf = tn[1].to_string();
 
    for (unsigned i = 0; i < tn[1].size(); i++) {
 
        if (pbuf[i] == '\\' && pbuf[i+1] == 'r') {
 
            ++i;
 
            msg[msglen++] = '\r';
 
            msg[msglen] = '\0';
 
            continue;
 
        } else if (pbuf[i] == '\\' && pbuf[i+1] == 'n') {
 
            ++i;
 
            msg[msglen++] = '\n';
 
            msg[msglen] = '\0';
 
            continue;
 
        }
 
        msg[msglen++] = pbuf[i];
 
        msg[msglen] = '\0';
 
    }
 
    parent_->writeData(msg, msglen);
 
 
 
    if (++testcnt_ < tests_.size()) {
 
        const AttributeType &t0 = tests_[testcnt_];
 
        IClock *iclk = static_cast<IClock *>(
 
                RISCV_get_service_iface("core0", IFACE_CLOCK));
 
        iclk->registerStepCallback(static_cast<IClockListener *>(this),
 
                                   t0[0u].to_uint64());
 
    }
}
}
 
 
}  // namespace debugger
}  // namespace debugger
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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