mirror of
https://github.com/akuker/RASCSI.git
synced 2024-10-05 06:54:44 +00:00
Initial merge of (incomplete) Banana Pi updates (#993)
This commit is contained in:
parent
a403ec3ded
commit
eb71c31cf1
34
cpp/Makefile
34
cpp/Makefile
@ -58,6 +58,7 @@ RASCTL = rasctl
|
||||
RASDUMP = rasdump
|
||||
SCSIMON = scsimon
|
||||
RASCSI_TEST = rascsi_test
|
||||
SCSILOOP = scsiloop
|
||||
|
||||
SYSTEMD_CONF = /etc/systemd/system/rascsi.service
|
||||
RSYSLOG_CONF = /etc/rsyslog.d/rascsi.conf
|
||||
@ -77,7 +78,8 @@ BIN_ALL = \
|
||||
$(BINDIR)/$(RASCSI) \
|
||||
$(BINDIR)/$(RASCTL) \
|
||||
$(BINDIR)/$(SCSIMON) \
|
||||
$(BINDIR)/$(RASDUMP)
|
||||
$(BINDIR)/$(RASDUMP) \
|
||||
$(BINDIR)/$(SCSILOOP)
|
||||
|
||||
SRC_PROTOC = rascsi_interface.proto
|
||||
|
||||
@ -114,8 +116,16 @@ SRC_RASCSI_TEST = $(shell find ./test -name '*.cpp')
|
||||
SRC_RASCSI_TEST += $(shell find ./rasdump -name '*.cpp')
|
||||
SRC_RASCSI_TEST += $(shell find ./monitor -name '*.cpp')
|
||||
|
||||
vpath %.h ./ ./shared ./controllers ./devices ./monitor ./hal ./rascsi ./rasctl ./rasdump
|
||||
vpath %.cpp ./ ./shared ./controllers ./devices ./monitor ./hal ./rascsi ./rasctl ./rasdump ./test
|
||||
SRC_SCSILOOP = scsiloop.cpp
|
||||
SRC_SCSILOOP += $(shell find ./scsiloop -name '*.cpp')
|
||||
SRC_SCSILOOP += $(shell find ./hal -name '*.cpp')
|
||||
|
||||
vpath %.h ./ ./shared ./controllers ./devices ./monitor ./hal \
|
||||
./hal/boards ./hal/pi_defs ./rascsi ./rasctl ./rasdump \
|
||||
./scsiloop
|
||||
vpath %.cpp ./ ./shared ./controllers ./devices ./monitor ./hal \
|
||||
./hal/boards ./hal/pi_defs ./rascsi ./rasctl ./rasdump \
|
||||
./scsiloop ./test
|
||||
vpath %.o ./$(OBJDIR)
|
||||
vpath ./$(BINDIR)
|
||||
|
||||
@ -127,16 +137,21 @@ OBJ_RASCTL := $(addprefix $(OBJDIR)/,$(notdir $(SRC_RASCTL:%.cpp=%.o)))
|
||||
OBJ_RASDUMP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_RASDUMP:%.cpp=%.o)))
|
||||
OBJ_SCSIMON := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SCSIMON:%.cpp=%.o)))
|
||||
OBJ_RASCSI_TEST := $(addprefix $(OBJDIR)/,$(notdir $(SRC_RASCSI_TEST:%.cpp=%.o)))
|
||||
OBJ_SCSILOOP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SCSILOOP:%.cpp=%.o)))
|
||||
OBJ_SHARED := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SHARED:%.cpp=%.o)))
|
||||
OBJ_PROTOBUF := $(addprefix $(OBJDIR)/,$(notdir $(SRC_PROTOBUF:%.cpp=%.o)))
|
||||
OBJ_GENERATED := $(addprefix $(OBJDIR)/,$(notdir $(SRC_GENERATED:%.cpp=%.o)))
|
||||
|
||||
GENERATED_DIR := generated
|
||||
|
||||
# For the unit tests, the following functions will be "wrapped" by the linker, meaning the
|
||||
# __wrap_xxxx() function will be called instead of the real function. These linker flags
|
||||
# should only be used for testing purposes!
|
||||
TEST_WRAPS = -Wl,--wrap=fopen64
|
||||
|
||||
# The following will include all of the auto-generated dependency files (*.d)
|
||||
# if they exist. This will trigger a rebuild of a source file if a header changes
|
||||
ALL_DEPS := $(patsubst %.o,%.d,$(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_RASDUMP) $(OBJ_SCSIMON) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_RASCSI_TEST))
|
||||
ALL_DEPS := $(patsubst %.o,%.d,$(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_RASDUMP) $(OBJ_SCSIMON) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_RASCSI_TEST) $(OBJ_SCSILOOP))
|
||||
-include $(ALL_DEPS)
|
||||
|
||||
$(OBJDIR) $(BINDIR):
|
||||
@ -179,7 +194,7 @@ lcov: test
|
||||
lcov -q -c -d . --include '*/cpp/*' -o $(COVERAGE_FILE) --exclude '*/test/*' --exclude '*/interfaces/*' --exclude '*/rascsi_interface.pb*'
|
||||
genhtml -q -o $(COVERAGE_DIR) --legend $(COVERAGE_FILE)
|
||||
|
||||
docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt $(DOC_DIR)/scsimon_man_page.txt $(DOC_DIR)/rasdump_man_page.txt
|
||||
docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt $(DOC_DIR)/scsimon_man_page.txt $(DOC_DIR)/rasdump_man_page.txt $(DOC_DIR)/scsiloop_man_page.txt
|
||||
|
||||
$(SRC_RASCSI_CORE) $(SRC_RASCTL_CORE) : $(OBJ_GENERATED)
|
||||
|
||||
@ -196,16 +211,19 @@ $(BINDIR)/$(SCSIMON): $(OBJ_SCSIMON) $(OBJ_SHARED) | $(BINDIR)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_SCSIMON) $(OBJ_SHARED)
|
||||
|
||||
$(BINDIR)/$(RASCSI_TEST): $(SRC_GENERATED) $(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI_TEST) $(OBJ_RASCTL_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) | $(BINDIR)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) -lpthread -lpcap -lprotobuf -lstdc++fs -lgmock -lgtest
|
||||
$(CXX) $(CXXFLAGS) $(TEST_WRAPS) -o $@ $(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) -lpthread -lpcap -lprotobuf -lstdc++fs -lgmock -lgtest
|
||||
|
||||
$(BINDIR)/$(SCSILOOP): $(OBJ_SHARED) $(OBJ_SCSILOOP) | $(BINDIR)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_SHARED) $(OBJ_SCSILOOP)
|
||||
|
||||
# Phony rules for building individual utilities
|
||||
.PHONY: $(RASCSI) $(RASCTL) $(RASDUMP) $(SCSIMON) $(RASCSI_TEST)
|
||||
.PHONY: $(RASCSI) $(RASCTL) $(RASDUMP) $(SCSIMON) $(RASCSI_TEST) $(SCSILOOP)
|
||||
$(RASCSI) : $(BINDIR)/$(RASCSI)
|
||||
$(RASCTL) : $(BINDIR)/$(RASCTL)
|
||||
$(RASDUMP) : $(BINDIR)/$(RASDUMP)
|
||||
$(SCSIMON) : $(BINDIR)/$(SCSIMON)
|
||||
$(RASCSI_TEST): $(BINDIR)/$(RASCSI_TEST)
|
||||
$(SCSILOOP) : $(BINDIR)/$(SCSILOOP)
|
||||
|
||||
## clean : Remove all of the object files, intermediate
|
||||
## compiler files and executable files
|
||||
@ -230,10 +248,12 @@ install: \
|
||||
$(MAN_PAGE_DIR)/rascsi.1 \
|
||||
$(MAN_PAGE_DIR)/rasctl.1 \
|
||||
$(MAN_PAGE_DIR)/scsimon.1 \
|
||||
$(MAN_PAGE_DIR)/scsiloop.1 \
|
||||
$(MAN_PAGE_DIR)/rasdump.1 \
|
||||
$(USR_LOCAL_BIN)/$(RASCTL) \
|
||||
$(USR_LOCAL_BIN)/$(RASCSI) \
|
||||
$(USR_LOCAL_BIN)/$(SCSIMON) \
|
||||
$(USR_LOCAL_BIN)/$(SCSILOOP) \
|
||||
$(USR_LOCAL_BIN)/$(RASDUMP) \
|
||||
$(SYSTEMD_CONF) \
|
||||
$(RSYSLOG_CONF) \
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "devices/primary_device.h"
|
||||
#include "abstract_controller.h"
|
||||
|
||||
using namespace scsi_defs;
|
||||
|
||||
void AbstractController::AllocateCmd(size_t size)
|
||||
{
|
||||
if (size > ctrl.cmd.size()) {
|
||||
@ -52,7 +54,7 @@ shared_ptr<PrimaryDevice> AbstractController::GetDeviceForLun(int lun) const {
|
||||
|
||||
void AbstractController::Reset()
|
||||
{
|
||||
SetPhase(BUS::phase_t::busfree);
|
||||
SetPhase(phase_t::busfree);
|
||||
|
||||
ctrl.status = status::GOOD;
|
||||
ctrl.message = 0x00;
|
||||
@ -70,35 +72,35 @@ void AbstractController::Reset()
|
||||
void AbstractController::ProcessPhase()
|
||||
{
|
||||
switch (GetPhase()) {
|
||||
case BUS::phase_t::busfree:
|
||||
case phase_t::busfree:
|
||||
BusFree();
|
||||
break;
|
||||
|
||||
case BUS::phase_t::selection:
|
||||
case phase_t::selection:
|
||||
Selection();
|
||||
break;
|
||||
|
||||
case BUS::phase_t::dataout:
|
||||
case phase_t::dataout:
|
||||
DataOut();
|
||||
break;
|
||||
|
||||
case BUS::phase_t::datain:
|
||||
case phase_t::datain:
|
||||
DataIn();
|
||||
break;
|
||||
|
||||
case BUS::phase_t::command:
|
||||
case phase_t::command:
|
||||
Command();
|
||||
break;
|
||||
|
||||
case BUS::phase_t::status:
|
||||
case phase_t::status:
|
||||
Status();
|
||||
break;
|
||||
|
||||
case BUS::phase_t::msgout:
|
||||
case phase_t::msgout:
|
||||
MsgOut();
|
||||
break;
|
||||
|
||||
case BUS::phase_t::msgin:
|
||||
case phase_t::msgin:
|
||||
MsgIn();
|
||||
break;
|
||||
|
||||
|
@ -14,10 +14,10 @@
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <memory>
|
||||
#include "hal/bus.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class BUS;
|
||||
class AbstractController;
|
||||
class PrimaryDevice;
|
||||
|
||||
|
@ -11,9 +11,11 @@
|
||||
|
||||
#include "shared/scsi.h"
|
||||
|
||||
using namespace scsi_defs;
|
||||
|
||||
class PhaseHandler
|
||||
{
|
||||
BUS::phase_t phase = BUS::phase_t::busfree;
|
||||
phase_t phase = phase_t::busfree;
|
||||
|
||||
public:
|
||||
|
||||
@ -29,18 +31,18 @@ public:
|
||||
virtual void MsgIn() = 0;
|
||||
virtual void MsgOut() = 0;
|
||||
|
||||
virtual BUS::phase_t Process(int) = 0;
|
||||
virtual phase_t Process(int) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
BUS::phase_t GetPhase() const { return phase; }
|
||||
void SetPhase(BUS::phase_t p) { phase = p; }
|
||||
bool IsSelection() const { return phase == BUS::phase_t::selection; }
|
||||
bool IsBusFree() const { return phase == BUS::phase_t::busfree; }
|
||||
bool IsCommand() const { return phase == BUS::phase_t::command; }
|
||||
bool IsStatus() const { return phase == BUS::phase_t::status; }
|
||||
bool IsDataIn() const { return phase == BUS::phase_t::datain; }
|
||||
bool IsDataOut() const { return phase == BUS::phase_t::dataout; }
|
||||
bool IsMsgIn() const { return phase == BUS::phase_t::msgin; }
|
||||
bool IsMsgOut() const { return phase == BUS::phase_t::msgout; }
|
||||
phase_t GetPhase() const { return phase; }
|
||||
void SetPhase(phase_t p) { phase = p; }
|
||||
bool IsSelection() const { return phase == phase_t::selection; }
|
||||
bool IsBusFree() const { return phase == phase_t::busfree; }
|
||||
bool IsCommand() const { return phase == phase_t::command; }
|
||||
bool IsStatus() const { return phase == phase_t::status; }
|
||||
bool IsDataIn() const { return phase == phase_t::datain; }
|
||||
bool IsDataOut() const { return phase == phase_t::dataout; }
|
||||
bool IsMsgIn() const { return phase == phase_t::msgin; }
|
||||
bool IsMsgOut() const { return phase == phase_t::msgout; }
|
||||
};
|
||||
|
@ -52,7 +52,7 @@ void ScsiController::Reset()
|
||||
SetByteTransfer(false);
|
||||
}
|
||||
|
||||
BUS::phase_t ScsiController::Process(int id)
|
||||
phase_t ScsiController::Process(int id)
|
||||
{
|
||||
GetBus().Acquire();
|
||||
|
||||
@ -89,7 +89,7 @@ void ScsiController::BusFree()
|
||||
if (!IsBusFree()) {
|
||||
logger.Trace("Bus free phase");
|
||||
|
||||
SetPhase(BUS::phase_t::busfree);
|
||||
SetPhase(phase_t::busfree);
|
||||
|
||||
GetBus().SetREQ(false);
|
||||
GetBus().SetMSG(false);
|
||||
@ -165,7 +165,7 @@ void ScsiController::Selection()
|
||||
|
||||
logger.Trace("Selection phase");
|
||||
|
||||
SetPhase(BUS::phase_t::selection);
|
||||
SetPhase(phase_t::selection);
|
||||
|
||||
// Raise BSY and respond
|
||||
GetBus().SetBSY(true);
|
||||
@ -188,7 +188,7 @@ void ScsiController::Command()
|
||||
if (!IsCommand()) {
|
||||
logger.Trace("Command phase");
|
||||
|
||||
SetPhase(BUS::phase_t::command);
|
||||
SetPhase(phase_t::command);
|
||||
|
||||
GetBus().SetMSG(false);
|
||||
GetBus().SetCD(true);
|
||||
@ -307,7 +307,7 @@ void ScsiController::Status()
|
||||
s << "Status Phase, status is $" << setfill('0') << setw(2) << hex << static_cast<int>(GetStatus());
|
||||
logger.Trace(s.str());
|
||||
|
||||
SetPhase(BUS::phase_t::status);
|
||||
SetPhase(phase_t::status);
|
||||
|
||||
// Signal line operated by the target
|
||||
GetBus().SetMSG(false);
|
||||
@ -331,7 +331,7 @@ void ScsiController::MsgIn()
|
||||
if (!IsMsgIn()) {
|
||||
logger.Trace("Message In phase");
|
||||
|
||||
SetPhase(BUS::phase_t::msgin);
|
||||
SetPhase(phase_t::msgin);
|
||||
|
||||
GetBus().SetMSG(true);
|
||||
GetBus().SetCD(true);
|
||||
@ -356,7 +356,7 @@ void ScsiController::MsgOut()
|
||||
scsi.msb = {};
|
||||
}
|
||||
|
||||
SetPhase(BUS::phase_t::msgout);
|
||||
SetPhase(phase_t::msgout);
|
||||
|
||||
GetBus().SetMSG(true);
|
||||
GetBus().SetCD(true);
|
||||
@ -389,7 +389,7 @@ void ScsiController::DataIn()
|
||||
|
||||
logger.Trace("Entering Data In phase");
|
||||
|
||||
SetPhase(BUS::phase_t::datain);
|
||||
SetPhase(phase_t::datain);
|
||||
|
||||
GetBus().SetMSG(false);
|
||||
GetBus().SetCD(false);
|
||||
@ -419,7 +419,7 @@ void ScsiController::DataOut()
|
||||
|
||||
logger.Trace("Data Out phase");
|
||||
|
||||
SetPhase(BUS::phase_t::dataout);
|
||||
SetPhase(phase_t::dataout);
|
||||
|
||||
// Signal line operated by the target
|
||||
GetBus().SetMSG(false);
|
||||
@ -537,7 +537,7 @@ void ScsiController::Send()
|
||||
logger.Trace("Moving to next phase: " + string(BUS::GetPhaseStrRaw(GetPhase())));
|
||||
switch (GetPhase()) {
|
||||
// Message in phase
|
||||
case BUS::phase_t::msgin:
|
||||
case phase_t::msgin:
|
||||
// Completed sending response to extended message of IDENTIFY message
|
||||
if (scsi.atnmsg) {
|
||||
// flag off
|
||||
@ -552,13 +552,13 @@ void ScsiController::Send()
|
||||
break;
|
||||
|
||||
// Data-in Phase
|
||||
case BUS::phase_t::datain:
|
||||
case phase_t::datain:
|
||||
// status phase
|
||||
Status();
|
||||
break;
|
||||
|
||||
// status phase
|
||||
case BUS::phase_t::status:
|
||||
case phase_t::status:
|
||||
// Message in phase
|
||||
SetLength(1);
|
||||
SetBlocks(1);
|
||||
@ -605,7 +605,7 @@ void ScsiController::Receive()
|
||||
// Processing after receiving data (by phase)
|
||||
logger.Trace("Phase: " + string(BUS::GetPhaseStrRaw(GetPhase())));
|
||||
switch (GetPhase()) {
|
||||
case BUS::phase_t::dataout:
|
||||
case phase_t::dataout:
|
||||
if (GetBlocks() == 0) {
|
||||
// End with this buffer
|
||||
result = XferOut(false);
|
||||
@ -615,7 +615,7 @@ void ScsiController::Receive()
|
||||
}
|
||||
break;
|
||||
|
||||
case BUS::phase_t::msgout:
|
||||
case phase_t::msgout:
|
||||
SetMessage(GetBuffer()[0]);
|
||||
if (!XferMsg(GetMessage())) {
|
||||
// Immediately free the bus if message output fails
|
||||
@ -646,15 +646,15 @@ void ScsiController::Receive()
|
||||
|
||||
// Move to next phase
|
||||
switch (GetPhase()) {
|
||||
case BUS::phase_t::command:
|
||||
case phase_t::command:
|
||||
ProcessCommand();
|
||||
break;
|
||||
|
||||
case BUS::phase_t::msgout:
|
||||
case phase_t::msgout:
|
||||
ProcessMessage();
|
||||
break;
|
||||
|
||||
case BUS::phase_t::dataout:
|
||||
case phase_t::dataout:
|
||||
// Block-oriented data have been handled above
|
||||
DataOutNonBlockOriented();
|
||||
|
||||
@ -694,11 +694,11 @@ void ScsiController::ReceiveBytes()
|
||||
// Processing after receiving data (by phase)
|
||||
logger.Trace("Phase: " + string(BUS::GetPhaseStrRaw(GetPhase())));
|
||||
switch (GetPhase()) {
|
||||
case BUS::phase_t::dataout:
|
||||
case phase_t::dataout:
|
||||
result = XferOut(false);
|
||||
break;
|
||||
|
||||
case BUS::phase_t::msgout:
|
||||
case phase_t::msgout:
|
||||
SetMessage(GetBuffer()[0]);
|
||||
if (!XferMsg(GetMessage())) {
|
||||
// Immediately free the bus if message output fails
|
||||
@ -722,15 +722,15 @@ void ScsiController::ReceiveBytes()
|
||||
|
||||
// Move to next phase
|
||||
switch (GetPhase()) {
|
||||
case BUS::phase_t::command:
|
||||
case phase_t::command:
|
||||
ProcessCommand();
|
||||
break;
|
||||
|
||||
case BUS::phase_t::msgout:
|
||||
case phase_t::msgout:
|
||||
ProcessMessage();
|
||||
break;
|
||||
|
||||
case BUS::phase_t::dataout:
|
||||
case phase_t::dataout:
|
||||
Status();
|
||||
break;
|
||||
|
||||
@ -1046,4 +1046,4 @@ void ScsiController::Sleep()
|
||||
SysTimer::SleepUsec(MIN_EXEC_TIME - time);
|
||||
}
|
||||
execstart = 0;
|
||||
}
|
||||
}
|
@ -60,7 +60,7 @@ public:
|
||||
|
||||
void Reset() override;
|
||||
|
||||
BUS::phase_t Process(int) override;
|
||||
phase_t Process(int) override;
|
||||
|
||||
int GetEffectiveLun() const override;
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) 2022 Uwe Seimet
|
||||
// Copyright (C) 2022 akuker
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@ -30,7 +31,7 @@ int BUS::GetCommandByteCount(uint8_t opcode)
|
||||
// Phase Acquisition
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BUS::phase_t BUS::GetPhase()
|
||||
phase_t BUS::GetPhase()
|
||||
{
|
||||
// Selection Phase
|
||||
if (GetSEL()) {
|
||||
@ -66,7 +67,7 @@ const char* BUS::GetPhaseStrRaw(phase_t current_phase) {
|
||||
// This determines the phase based upon the Msg, C/D and I/O signals.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
const array<BUS::phase_t, 8> BUS::phase_table = {
|
||||
const array<phase_t, 8> BUS::phase_table = {
|
||||
// | MSG|C/D|I/O |
|
||||
phase_t::dataout, // | 0 | 0 | 0 |
|
||||
phase_t::datain, // | 0 | 0 | 1 |
|
||||
@ -83,7 +84,7 @@ const array<BUS::phase_t, 8> BUS::phase_table = {
|
||||
// Phase string to phase mapping
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
const unordered_map<BUS::phase_t, const char*> BUS::phase_str_mapping = {
|
||||
const unordered_map<phase_t, const char*> BUS::phase_str_mapping = {
|
||||
{ phase_t::busfree, "busfree" },
|
||||
{ phase_t::arbitration, "arbitration" },
|
||||
{ phase_t::selection, "selection" },
|
||||
|
177
cpp/hal/bus.h
177
cpp/hal/bus.h
@ -9,116 +9,105 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/data_sample.h"
|
||||
#include "hal/pin_control.h"
|
||||
#include "shared/config.h"
|
||||
#include "shared/scsi.h"
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
using namespace std;
|
||||
|
||||
class BUS
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations (bus control timing)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
// SCSI Bus timings taken from:
|
||||
// https://www.staff.uni-mainz.de/tacke/scsi/SCSI2-05.html
|
||||
const static int SCSI_DELAY_ARBITRATION_DELAY_NS = 2400;
|
||||
const static int SCSI_DELAY_ASSERTION_PERIOD_NS = 90;
|
||||
const static int SCSI_DELAY_BUS_CLEAR_DELAY_NS = 800;
|
||||
const static int SCSI_DELAY_BUS_FREE_DELAY_NS = 800;
|
||||
const static int SCSI_DELAY_BUS_SET_DELAY_NS = 1800;
|
||||
const static int SCSI_DELAY_BUS_SETTLE_DELAY_NS = 400;
|
||||
const static int SCSI_DELAY_CABLE_SKEW_DELAY_NS = 10;
|
||||
const static int SCSI_DELAY_DATA_RELEASE_DELAY_NS = 400;
|
||||
const static int SCSI_DELAY_DESKEW_DELAY_NS = 45;
|
||||
const static int SCSI_DELAY_DISCONNECTION_DELAY_US = 200;
|
||||
const static int SCSI_DELAY_HOLD_TIME_NS = 45;
|
||||
const static int SCSI_DELAY_NEGATION_PERIOD_NS = 90;
|
||||
const static int SCSI_DELAY_POWER_ON_TO_SELECTION_TIME_S = 10; // (recommended)
|
||||
const static int SCSI_DELAY_RESET_TO_SELECTION_TIME_US = 250 * 1000; // (recommended)
|
||||
const static int SCSI_DELAY_RESET_HOLD_TIME_US = 25;
|
||||
const static int SCSI_DELAY_SELECTION_ABORT_TIME_US = 200;
|
||||
const static int SCSI_DELAY_SELECTION_TIMEOUT_DELAY_NS = 250 * 1000; // (recommended)
|
||||
const static int SCSI_DELAY_FAST_ASSERTION_PERIOD_NS = 30;
|
||||
const static int SCSI_DELAY_FAST_CABLE_SKEW_DELAY_NS = 5;
|
||||
const static int SCSI_DELAY_FAST_DESKEW_DELAY_NS = 20;
|
||||
const static int SCSI_DELAY_FAST_HOLD_TIME_NS = 10;
|
||||
const static int SCSI_DELAY_FAST_NEGATION_PERIOD_NS = 30;
|
||||
|
||||
// The DaynaPort SCSI Link do a short delay in the middle of transfering
|
||||
// a packet. This is the number of uS that will be delayed between the
|
||||
// header and the actual data.
|
||||
const static int SCSI_DELAY_SEND_DATA_DAYNAPORT_US = 100;
|
||||
|
||||
|
||||
class bus_exception : public runtime_error
|
||||
{
|
||||
public:
|
||||
// Operation modes definition
|
||||
enum class mode_e {
|
||||
TARGET = 0,
|
||||
INITIATOR = 1,
|
||||
MONITOR = 2,
|
||||
};
|
||||
using runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
// Phase definitions
|
||||
enum class phase_t : int {
|
||||
busfree,
|
||||
arbitration,
|
||||
selection,
|
||||
reselection,
|
||||
command,
|
||||
datain,
|
||||
dataout,
|
||||
status,
|
||||
msgin,
|
||||
msgout,
|
||||
reserved
|
||||
};
|
||||
|
||||
BUS() = default;
|
||||
virtual ~BUS() = default;
|
||||
class BUS : public PinControl
|
||||
{
|
||||
public:
|
||||
// Operation modes definition
|
||||
enum class mode_e {
|
||||
TARGET = 0,
|
||||
INITIATOR = 1,
|
||||
MONITOR = 2,
|
||||
};
|
||||
|
||||
static int GetCommandByteCount(uint8_t);
|
||||
|
||||
virtual bool Init(mode_e mode) = 0;
|
||||
virtual void Reset() = 0;
|
||||
virtual void Cleanup() = 0;
|
||||
phase_t GetPhase();
|
||||
virtual bool Init(mode_e mode) = 0;
|
||||
virtual void Reset() = 0;
|
||||
virtual void Cleanup() = 0;
|
||||
phase_t GetPhase();
|
||||
|
||||
static phase_t GetPhase(int mci)
|
||||
{
|
||||
return phase_table[mci];
|
||||
}
|
||||
static phase_t GetPhase(int mci)
|
||||
{
|
||||
return phase_table[mci];
|
||||
}
|
||||
|
||||
// Get the string phase name, based upon the raw data
|
||||
static const char* GetPhaseStrRaw(phase_t current_phase);
|
||||
// Get the string phase name, based upon the raw data
|
||||
static const char *GetPhaseStrRaw(phase_t current_phase);
|
||||
virtual int GetMode(int pin) = 0;
|
||||
|
||||
// Extract as specific pin field from a raw data capture
|
||||
static inline uint32_t GetPinRaw(uint32_t raw_data, uint32_t pin_num)
|
||||
{
|
||||
return ((raw_data >> pin_num) & 1);
|
||||
}
|
||||
virtual uint32_t Acquire() = 0;
|
||||
virtual unique_ptr<DataSample> GetSample(uint64_t timestamp = 0) = 0;
|
||||
virtual int CommandHandShake(vector<uint8_t> &) = 0;
|
||||
virtual int ReceiveHandShake(uint8_t *buf, int count) = 0;
|
||||
virtual int SendHandShake(uint8_t *buf, int count, int delay_after_bytes) = 0;
|
||||
|
||||
virtual bool GetBSY() const = 0;
|
||||
virtual void SetBSY(bool ast) = 0;
|
||||
// SEL signal event polling
|
||||
virtual bool PollSelectEvent() = 0;
|
||||
|
||||
virtual bool GetSEL() const = 0;
|
||||
virtual void SetSEL(bool ast) = 0;
|
||||
// Clear SEL signal event
|
||||
virtual void ClearSelectEvent() = 0;
|
||||
|
||||
virtual bool GetATN() const = 0;
|
||||
virtual void SetATN(bool ast) = 0;
|
||||
virtual bool GetSignal(int pin) const = 0;
|
||||
// Get SCSI input signal value
|
||||
virtual void SetSignal(int pin, bool ast) = 0;
|
||||
// Set SCSI output signal value
|
||||
static const int SEND_NO_DELAY = -1;
|
||||
// Passed into SendHandShake when we don't want to delay
|
||||
private:
|
||||
static const array<phase_t, 8> phase_table;
|
||||
|
||||
virtual bool GetACK() const = 0;
|
||||
virtual void SetACK(bool ast) = 0;
|
||||
|
||||
virtual bool GetRST() const = 0;
|
||||
virtual void SetRST(bool ast) = 0;
|
||||
|
||||
virtual bool GetMSG() const = 0;
|
||||
virtual void SetMSG(bool ast) = 0;
|
||||
|
||||
virtual bool GetCD() const = 0;
|
||||
virtual void SetCD(bool ast) = 0;
|
||||
|
||||
virtual bool GetIO() = 0;
|
||||
virtual void SetIO(bool ast) = 0;
|
||||
|
||||
virtual bool GetREQ() const = 0;
|
||||
virtual void SetREQ(bool ast) = 0;
|
||||
|
||||
virtual uint8_t GetDAT() = 0;
|
||||
virtual void SetDAT(uint8_t dat) = 0;
|
||||
virtual bool GetDP() const = 0; // Get parity signal
|
||||
|
||||
virtual uint32_t Acquire() = 0;
|
||||
virtual int CommandHandShake(vector<uint8_t>&) = 0;
|
||||
virtual int ReceiveHandShake(uint8_t *buf, int count) = 0;
|
||||
virtual int SendHandShake(uint8_t *buf, int count, int delay_after_bytes) = 0;
|
||||
|
||||
#ifdef USE_SEL_EVENT_ENABLE
|
||||
// SEL signal event polling
|
||||
virtual bool PollSelectEvent() = 0;
|
||||
|
||||
// Clear SEL signal event
|
||||
virtual void ClearSelectEvent() = 0;
|
||||
#endif
|
||||
|
||||
virtual bool GetSignal(int pin) const = 0;
|
||||
// Get SCSI input signal value
|
||||
virtual void SetSignal(int pin, bool ast) = 0;
|
||||
// Set SCSI output signal value
|
||||
static const int SEND_NO_DELAY = -1;
|
||||
// Passed into SendHandShake when we don't want to delay
|
||||
private:
|
||||
static const array<phase_t, 8> phase_table;
|
||||
|
||||
static const unordered_map<phase_t, const char *> phase_str_mapping;
|
||||
static const unordered_map<phase_t, const char *> phase_str_mapping;
|
||||
};
|
||||
|
87
cpp/hal/connection_type/connection_aibom.h
Normal file
87
cpp/hal/connection_type/connection_aibom.h
Normal file
@ -0,0 +1,87 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI Reloaded
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2020 GIMONS
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/pi_defs/bpi-m2p.h"
|
||||
#include <string>
|
||||
|
||||
//
|
||||
// RaSCSI Adapter Aibom version
|
||||
//
|
||||
|
||||
const std::string CONNECT_DESC = "AIBOM PRODUCTS version"; // Startup message
|
||||
|
||||
// Select signal control mode
|
||||
const static int SIGNAL_CONTROL_MODE = 2; // SCSI positive logic specification
|
||||
|
||||
// Control signal output logic
|
||||
#define ACT_ON ON // ACTIVE SIGNAL ON
|
||||
#define ENB_ON ON // ENABLE SIGNAL ON
|
||||
#define IND_IN OFF // INITIATOR SIGNAL INPUT
|
||||
#define TAD_IN OFF // TARGET SIGNAL INPUT
|
||||
#define DTD_IN OFF // DATA SIGNAL INPUT
|
||||
|
||||
// Control signal pin assignment (-1 means no control)
|
||||
const static int PIN_ACT = 4; // ACTIVE
|
||||
const static int PIN_ENB = 17; // ENABLE
|
||||
const static int PIN_IND = 27; // INITIATOR CTRL DIRECTION
|
||||
const static int PIN_TAD = -1; // TARGET CTRL DIRECTION
|
||||
const static int PIN_DTD = 18; // DATA DIRECTION
|
||||
|
||||
// SCSI signal pin assignment
|
||||
const static int PIN_DT0 = 6; // Data 0
|
||||
const static int PIN_DT1 = 12; // Data 1
|
||||
const static int PIN_DT2 = 13; // Data 2
|
||||
const static int PIN_DT3 = 16; // Data 3
|
||||
const static int PIN_DT4 = 19; // Data 4
|
||||
const static int PIN_DT5 = 20; // Data 5
|
||||
const static int PIN_DT6 = 26; // Data 6
|
||||
const static int PIN_DT7 = 21; // Data 7
|
||||
const static int PIN_DP = 5; // Data parity
|
||||
const static int PIN_ATN = 22; // ATN
|
||||
const static int PIN_RST = 25; // RST
|
||||
const static int PIN_ACK = 10; // ACK
|
||||
const static int PIN_REQ = 7; // REQ
|
||||
const static int PIN_MSG = 9; // MSG
|
||||
const static int PIN_CD = 11; // CD
|
||||
const static int PIN_IO = 23; // IO
|
||||
const static int PIN_BSY = 24; // BSY
|
||||
const static int PIN_SEL = 8; // SEL
|
||||
|
||||
// Warning: The Allwinner/Banana Pi GPIO numbers DO NOT correspond to
|
||||
// the Raspberry Pi GPIO numbers.
|
||||
// For example, Pin 7 is GPIO4 on a Raspberry Pi. Its GPIO 6 on a Banana Pi
|
||||
// For Banana Pi, the pins are specified by physical pin number, NOT GPIO number
|
||||
// (The Macro's convert the pin number to logical BPi GPIO number)
|
||||
const static int BPI_PIN_ACT = BPI_M2P_07; // ACTIVE
|
||||
const static int BPI_PIN_ENB = BPI_M2P_11; // ENABLE
|
||||
const static int BPI_PIN_IND = BPI_M2P_13; // INITIATOR CTRL DIRECTION
|
||||
const static int BPI_PIN_TAD = -1; // TARGET CTRL DIRECTION
|
||||
const static int BPI_PIN_DTD = BPI_M2P_12; // DATA DIRECTION
|
||||
|
||||
const static int BPI_PIN_DT0 = BPI_M2P_31; // Data 0
|
||||
const static int BPI_PIN_DT1 = BPI_M2P_32; // Data 1
|
||||
const static int BPI_PIN_DT2 = BPI_M2P_33; // Data 2
|
||||
const static int BPI_PIN_DT3 = BPI_M2P_36; // Data 3
|
||||
const static int BPI_PIN_DT4 = BPI_M2P_35; // Data 4
|
||||
const static int BPI_PIN_DT5 = BPI_M2P_38; // Data 5
|
||||
const static int BPI_PIN_DT6 = BPI_M2P_37; // Data 6
|
||||
const static int BPI_PIN_DT7 = BPI_M2P_40; // Data 7
|
||||
const static int BPI_PIN_DP = BPI_M2P_29; // Data parity
|
||||
const static int BPI_PIN_ATN = BPI_M2P_15; // ATN
|
||||
const static int BPI_PIN_RST = BPI_M2P_22; // RST
|
||||
const static int BPI_PIN_ACK = BPI_M2P_19; // ACK
|
||||
const static int BPI_PIN_REQ = BPI_M2P_26; // REQ
|
||||
const static int BPI_PIN_MSG = BPI_M2P_21; // MSG
|
||||
const static int BPI_PIN_CD = BPI_M2P_23; // CD
|
||||
const static int BPI_PIN_IO = BPI_M2P_16; // IO
|
||||
const static int BPI_PIN_BSY = BPI_M2P_18; // BSY
|
||||
const static int BPI_PIN_SEL = BPI_M2P_24; // SEL
|
87
cpp/hal/connection_type/connection_fullspec.h
Normal file
87
cpp/hal/connection_type/connection_fullspec.h
Normal file
@ -0,0 +1,87 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI Reloaded
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2020 GIMONS
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/pi_defs/bpi-m2p.h"
|
||||
#include <string>
|
||||
|
||||
//
|
||||
// RaSCSI standard (SCSI logic, standard pin assignment)
|
||||
//
|
||||
|
||||
const std::string CONNECT_DESC = "FULLSPEC"; // Startup message
|
||||
|
||||
// Select signal control mode
|
||||
const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification
|
||||
|
||||
// Control signal pin assignment (-1 means no control)
|
||||
const static int PIN_ACT = 4; // ACTIVE
|
||||
const static int PIN_ENB = 5; // ENABLE
|
||||
const static int PIN_IND = 6; // INITIATOR CTRL DIRECTION
|
||||
const static int PIN_TAD = 7; // TARGET CTRL DIRECTION
|
||||
const static int PIN_DTD = 8; // DATA DIRECTION
|
||||
|
||||
// Control signal output logic
|
||||
#define ACT_ON ON // ACTIVE SIGNAL ON
|
||||
#define ENB_ON ON // ENABLE SIGNAL ON
|
||||
#define IND_IN OFF // INITIATOR SIGNAL INPUT
|
||||
#define TAD_IN OFF // TARGET SIGNAL INPUT
|
||||
#define DTD_IN ON // DATA SIGNAL INPUT
|
||||
|
||||
// SCSI signal pin assignment
|
||||
const static int PIN_DT0 = 10; // Data 0
|
||||
const static int PIN_DT1 = 11; // Data 1
|
||||
const static int PIN_DT2 = 12; // Data 2
|
||||
const static int PIN_DT3 = 13; // Data 3
|
||||
const static int PIN_DT4 = 14; // Data 4
|
||||
const static int PIN_DT5 = 15; // Data 5
|
||||
const static int PIN_DT6 = 16; // Data 6
|
||||
const static int PIN_DT7 = 17; // Data 7
|
||||
const static int PIN_DP = 18; // Data parity
|
||||
const static int PIN_ATN = 19; // ATN
|
||||
const static int PIN_RST = 20; // RST
|
||||
const static int PIN_ACK = 21; // ACK
|
||||
const static int PIN_REQ = 22; // REQ
|
||||
const static int PIN_MSG = 23; // MSG
|
||||
const static int PIN_CD = 24; // CD
|
||||
const static int PIN_IO = 25; // IO
|
||||
const static int PIN_BSY = 26; // BSY
|
||||
const static int PIN_SEL = 27; // SEL
|
||||
|
||||
// Warning: The Allwinner/Banana Pi GPIO numbers DO NOT correspond to
|
||||
// the Raspberry Pi GPIO numbers.
|
||||
// For example, Pin 7 is GPIO4 on a Raspberry Pi. Its GPIO 6 on a Banana Pi
|
||||
// For Banana Pi, the pins are specified by physical pin number, NOT GPIO number
|
||||
// (The Macro's convert the pin number to logical BPi GPIO number)
|
||||
const static int BPI_PIN_ACT = BPI_M2P_07; // ACTIVE
|
||||
const static int BPI_PIN_ENB = BPI_M2P_29; // ENABLE
|
||||
const static int BPI_PIN_IND = BPI_M2P_31; // INITIATOR CTRL DIRECTION
|
||||
const static int BPI_PIN_TAD = BPI_M2P_26; // TARGET CTRL DIRECTION
|
||||
const static int BPI_PIN_DTD = BPI_M2P_24; // DATA DIRECTION
|
||||
|
||||
const static int BPI_PIN_DT0 = BPI_M2P_19; // Data 0
|
||||
const static int BPI_PIN_DT1 = BPI_M2P_23; // Data 1
|
||||
const static int BPI_PIN_DT2 = BPI_M2P_32; // Data 2
|
||||
const static int BPI_PIN_DT3 = BPI_M2P_33; // Data 3
|
||||
const static int BPI_PIN_DT4 = BPI_M2P_08; // Data 4
|
||||
const static int BPI_PIN_DT5 = BPI_M2P_10; // Data 5
|
||||
const static int BPI_PIN_DT6 = BPI_M2P_36; // Data 6
|
||||
const static int BPI_PIN_DT7 = BPI_M2P_11; // Data 7
|
||||
const static int BPI_PIN_DP = BPI_M2P_12; // Data parity
|
||||
const static int BPI_PIN_ATN = BPI_M2P_35; // ATN
|
||||
const static int BPI_PIN_RST = BPI_M2P_38; // RST
|
||||
const static int BPI_PIN_ACK = BPI_M2P_40; // ACK
|
||||
const static int BPI_PIN_REQ = BPI_M2P_15; // REQ
|
||||
const static int BPI_PIN_MSG = BPI_M2P_16; // MSG
|
||||
const static int BPI_PIN_CD = BPI_M2P_18; // CD
|
||||
const static int BPI_PIN_IO = BPI_M2P_22; // IO
|
||||
const static int BPI_PIN_BSY = BPI_M2P_37; // BSY
|
||||
const static int BPI_PIN_SEL = BPI_M2P_13; // SEL
|
87
cpp/hal/connection_type/connection_gamernium.h
Normal file
87
cpp/hal/connection_type/connection_gamernium.h
Normal file
@ -0,0 +1,87 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI Reloaded
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2020 GIMONS
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/pi_defs/bpi-m2p.h"
|
||||
#include <string>
|
||||
|
||||
//
|
||||
// RaSCSI Adapter GAMERnium.com version
|
||||
//
|
||||
|
||||
const std::string CONNECT_DESC = "GAMERnium.com version"; // Startup message
|
||||
|
||||
// Select signal control mode
|
||||
const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification
|
||||
|
||||
// Control signal output logic
|
||||
#define ACT_ON ON // ACTIVE SIGNAL ON
|
||||
#define ENB_ON ON // ENABLE SIGNAL ON
|
||||
#define IND_IN OFF // INITIATOR SIGNAL INPUT
|
||||
#define TAD_IN OFF // TARGET SIGNAL INPUT
|
||||
#define DTD_IN ON // DATA SIGNAL INPUT
|
||||
|
||||
// Control signal pin assignment (-1 means no control)
|
||||
const static int PIN_ACT = 14; // ACTIVE
|
||||
const static int PIN_ENB = 6; // ENABLE
|
||||
const static int PIN_IND = 7; // INITIATOR CTRL DIRECTION
|
||||
const static int PIN_TAD = 8; // TARGET CTRL DIRECTION
|
||||
const static int PIN_DTD = 5; // DATA DIRECTION
|
||||
|
||||
// SCSI signal pin assignment
|
||||
const static int PIN_DT0 = 21; // Data 0
|
||||
const static int PIN_DT1 = 26; // Data 1
|
||||
const static int PIN_DT2 = 20; // Data 2
|
||||
const static int PIN_DT3 = 19; // Data 3
|
||||
const static int PIN_DT4 = 16; // Data 4
|
||||
const static int PIN_DT5 = 13; // Data 5
|
||||
const static int PIN_DT6 = 12; // Data 6
|
||||
const static int PIN_DT7 = 11; // Data 7
|
||||
const static int PIN_DP = 25; // Data parity
|
||||
const static int PIN_ATN = 10; // ATN
|
||||
const static int PIN_RST = 22; // RST
|
||||
const static int PIN_ACK = 24; // ACK
|
||||
const static int PIN_REQ = 15; // REQ
|
||||
const static int PIN_MSG = 17; // MSG
|
||||
const static int PIN_CD = 18; // CD
|
||||
const static int PIN_IO = 4; // IO
|
||||
const static int PIN_BSY = 27; // BSY
|
||||
const static int PIN_SEL = 23; // SEL
|
||||
|
||||
// Warning: The Allwinner/Banana Pi GPIO numbers DO NOT correspond to
|
||||
// the Raspberry Pi GPIO numbers.
|
||||
// For example, Pin 7 is GPIO4 on a Raspberry Pi. Its GPIO 6 on a Banana Pi
|
||||
// For Banana Pi, the pins are specified by physical pin number, NOT GPIO number
|
||||
// (The Macro's convert the pin number to logical BPi GPIO number)
|
||||
const static int BPI_PIN_ACT = BPI_M2P_08; // ACTIVE
|
||||
const static int BPI_PIN_ENB = BPI_M2P_31; // ENABLE
|
||||
const static int BPI_PIN_IND = BPI_M2P_04; // INITIATOR CTRL DIRECTION
|
||||
const static int BPI_PIN_TAD = BPI_M2P_24; // TARGET CTRL DIRECTION
|
||||
const static int BPI_PIN_DTD = BPI_M2P_29; // DATA DIRECTION
|
||||
|
||||
const static int BPI_PIN_DT0 = BPI_M2P_40; // Data 0
|
||||
const static int BPI_PIN_DT1 = BPI_M2P_37; // Data 1
|
||||
const static int BPI_PIN_DT2 = BPI_M2P_38; // Data 2
|
||||
const static int BPI_PIN_DT3 = BPI_M2P_35; // Data 3
|
||||
const static int BPI_PIN_DT4 = BPI_M2P_36; // Data 4
|
||||
const static int BPI_PIN_DT5 = BPI_M2P_33; // Data 5
|
||||
const static int BPI_PIN_DT6 = BPI_M2P_32; // Data 6
|
||||
const static int BPI_PIN_DT7 = BPI_M2P_23; // Data 7
|
||||
const static int BPI_PIN_DP = BPI_M2P_22; // Data parity
|
||||
const static int BPI_PIN_ATN = BPI_M2P_19; // ATN
|
||||
const static int BPI_PIN_RST = BPI_M2P_15; // RST
|
||||
const static int BPI_PIN_ACK = BPI_M2P_18; // ACK
|
||||
const static int BPI_PIN_REQ = BPI_M2P_10; // REQ
|
||||
const static int BPI_PIN_MSG = BPI_M2P_11; // MSG
|
||||
const static int BPI_PIN_CD = BPI_M2P_12; // CD
|
||||
const static int BPI_PIN_IO = BPI_M2P_07; // IO
|
||||
const static int BPI_PIN_BSY = BPI_M2P_13; // BSY
|
||||
const static int BPI_PIN_SEL = BPI_M2P_16; // SEL
|
87
cpp/hal/connection_type/connection_standard.h
Normal file
87
cpp/hal/connection_type/connection_standard.h
Normal file
@ -0,0 +1,87 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI Reloaded
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2020 GIMONS
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/pi_defs/bpi-m2p.h"
|
||||
#include <string>
|
||||
|
||||
//
|
||||
// RaSCSI standard (SCSI logic, standard pin assignment)
|
||||
//
|
||||
|
||||
const std::string CONNECT_DESC = "STANDARD"; // Startup message
|
||||
|
||||
// Select signal control mode
|
||||
const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification
|
||||
|
||||
// Control signal pin assignment (-1 means no control)
|
||||
const static int PIN_ACT = 4; // ACTIVE
|
||||
const static int PIN_ENB = 5; // ENABLE
|
||||
const static int PIN_IND = -1; // INITIATOR CTRL DIRECTION
|
||||
const static int PIN_TAD = -1; // TARGET CTRL DIRECTION
|
||||
const static int PIN_DTD = -1; // DATA DIRECTION
|
||||
|
||||
// Control signal output logic
|
||||
#define ACT_ON ON // ACTIVE SIGNAL ON
|
||||
#define ENB_ON ON // ENABLE SIGNAL ON
|
||||
#define IND_IN OFF // INITIATOR SIGNAL INPUT
|
||||
#define TAD_IN OFF // TARGET SIGNAL INPUT
|
||||
#define DTD_IN ON // DATA SIGNAL INPUT
|
||||
|
||||
// SCSI signal pin assignment
|
||||
const static int PIN_DT0 = 10; // Data 0
|
||||
const static int PIN_DT1 = 11; // Data 1
|
||||
const static int PIN_DT2 = 12; // Data 2
|
||||
const static int PIN_DT3 = 13; // Data 3
|
||||
const static int PIN_DT4 = 14; // Data 4
|
||||
const static int PIN_DT5 = 15; // Data 5
|
||||
const static int PIN_DT6 = 16; // Data 6
|
||||
const static int PIN_DT7 = 17; // Data 7
|
||||
const static int PIN_DP = 18; // Data parity
|
||||
const static int PIN_ATN = 19; // ATN
|
||||
const static int PIN_RST = 20; // RST
|
||||
const static int PIN_ACK = 21; // ACK
|
||||
const static int PIN_REQ = 22; // REQ
|
||||
const static int PIN_MSG = 23; // MSG
|
||||
const static int PIN_CD = 24; // CD
|
||||
const static int PIN_IO = 25; // IO
|
||||
const static int PIN_BSY = 26; // BSY
|
||||
const static int PIN_SEL = 27; // SEL
|
||||
|
||||
// Warning: The Allwinner/Banana Pi GPIO numbers DO NOT correspond to
|
||||
// the Raspberry Pi GPIO numbers.
|
||||
// For example, Pin 7 is GPIO4 on a Raspberry Pi. Its GPIO 6 on a Banana Pi
|
||||
// For Banana Pi, the pins are specified by physical pin number, NOT GPIO number
|
||||
// (The Macro's convert the pin number to logical BPi GPIO number)
|
||||
const static int BPI_PIN_ACT = BPI_M2P_07; // ACTIVE
|
||||
const static int BPI_PIN_ENB = BPI_M2P_29; // ENABLE
|
||||
const static int BPI_PIN_IND = -1; // INITIATOR CTRL DIRECTION
|
||||
const static int BPI_PIN_TAD = -1; // TARGET CTRL DIRECTION
|
||||
const static int BPI_PIN_DTD = -1; // DATA DIRECTION
|
||||
|
||||
const static int BPI_PIN_DT0 = BPI_M2P_19; // Data 0
|
||||
const static int BPI_PIN_DT1 = BPI_M2P_23; // Data 1
|
||||
const static int BPI_PIN_DT2 = BPI_M2P_32; // Data 2
|
||||
const static int BPI_PIN_DT3 = BPI_M2P_33; // Data 3
|
||||
const static int BPI_PIN_DT4 = BPI_M2P_08; // Data 4
|
||||
const static int BPI_PIN_DT5 = BPI_M2P_10; // Data 5
|
||||
const static int BPI_PIN_DT6 = BPI_M2P_36; // Data 6
|
||||
const static int BPI_PIN_DT7 = BPI_M2P_11; // Data 7
|
||||
const static int BPI_PIN_DP = BPI_M2P_12; // Data parity
|
||||
const static int BPI_PIN_ATN = BPI_M2P_35; // ATN
|
||||
const static int BPI_PIN_RST = BPI_M2P_38; // RST
|
||||
const static int BPI_PIN_ACK = BPI_M2P_40; // ACK
|
||||
const static int BPI_PIN_REQ = BPI_M2P_15; // REQ
|
||||
const static int BPI_PIN_MSG = BPI_M2P_16; // MSG
|
||||
const static int BPI_PIN_CD = BPI_M2P_18; // CD
|
||||
const static int BPI_PIN_IO = BPI_M2P_22; // IO
|
||||
const static int BPI_PIN_BSY = BPI_M2P_37; // BSY
|
||||
const static int BPI_PIN_SEL = BPI_M2P_13; // SEL
|
40
cpp/hal/data_sample.cpp
Normal file
40
cpp/hal/data_sample.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI Reloaded
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2022 akuker
|
||||
//
|
||||
// [ SCSI Bus Monitor ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "hal/bus.h"
|
||||
#include "hal/data_sample.h"
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string DataSample::GetPhaseStr() const
|
||||
{
|
||||
return BUS::GetPhaseStrRaw(GetPhase());
|
||||
}
|
||||
|
||||
phase_t DataSample::GetPhase() const
|
||||
{
|
||||
// Selection Phase
|
||||
if (GetSEL()) {
|
||||
return phase_t::selection;
|
||||
}
|
||||
|
||||
// Bus busy phase
|
||||
if (!GetBSY()) {
|
||||
return phase_t::busfree;
|
||||
}
|
||||
|
||||
// Get target phase from bus signal line
|
||||
uint32_t mci = GetMSG() ? 0x04 : 0x00;
|
||||
mci |= GetCD() ? 0x02 : 0x00;
|
||||
mci |= GetIO() ? 0x01 : 0x00;
|
||||
return BUS::GetPhase(mci);
|
||||
}
|
54
cpp/hal/data_sample.h
Normal file
54
cpp/hal/data_sample.h
Normal file
@ -0,0 +1,54 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI Reloaded
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2022 akuker
|
||||
//
|
||||
// [ Logical representation of a single data sample ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared/scsi.h"
|
||||
#include <string>
|
||||
|
||||
using namespace scsi_defs;
|
||||
|
||||
class DataSample
|
||||
{
|
||||
public:
|
||||
virtual bool GetBSY() const = 0;
|
||||
virtual bool GetSEL() const = 0;
|
||||
virtual bool GetATN() const = 0;
|
||||
virtual bool GetACK() const = 0;
|
||||
virtual bool GetRST() const = 0;
|
||||
virtual bool GetMSG() const = 0;
|
||||
virtual bool GetCD() const = 0;
|
||||
virtual bool GetIO() const = 0;
|
||||
virtual bool GetREQ() const = 0;
|
||||
virtual bool GetACT() const = 0;
|
||||
virtual uint8_t GetDAT() const = 0;
|
||||
virtual bool GetDP() const = 0;
|
||||
|
||||
virtual uint32_t GetRawCapture() const = 0;
|
||||
|
||||
phase_t GetPhase() const;
|
||||
virtual bool GetSignal(int pin) const = 0;
|
||||
|
||||
uint64_t GetTimestamp() const
|
||||
{
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
string GetPhaseStr() const;
|
||||
|
||||
virtual ~DataSample() = default;
|
||||
|
||||
explicit DataSample(uint64_t in_timestamp) : timestamp{in_timestamp} {}
|
||||
DataSample() = default;
|
||||
|
||||
private:
|
||||
uint64_t timestamp = 0;
|
||||
};
|
64
cpp/hal/data_sample_bananam2p.cpp
Normal file
64
cpp/hal/data_sample_bananam2p.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI Reloaded
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2022 akuker
|
||||
//
|
||||
// [ SCSI Bus Monitor ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "data_sample_bananam2p.h"
|
||||
#include "hal/sunxi_utils.h"
|
||||
#include <cstdint>
|
||||
|
||||
uint8_t DataSample_BananaM2p::GetDAT() const
|
||||
{
|
||||
uint8_t ret_val = 0;
|
||||
ret_val |= GetSignal(BPI_PIN_DT0) ? 0x01 : 0x00; // NOSONAR: GCC 10 doesn't fully support std::byte
|
||||
ret_val |= GetSignal(BPI_PIN_DT1) ? 0x02 : 0x00; // NOSONAR: GCC 10 doesn't fully support std::byte
|
||||
ret_val |= GetSignal(BPI_PIN_DT2) ? 0x04 : 0x00; // NOSONAR: GCC 10 doesn't fully support std::byte
|
||||
ret_val |= GetSignal(BPI_PIN_DT3) ? 0x08 : 0x00; // NOSONAR: GCC 10 doesn't fully support std::byte
|
||||
ret_val |= GetSignal(BPI_PIN_DT4) ? 0x10 : 0x00; // NOSONAR: GCC 10 doesn't fully support std::byte
|
||||
ret_val |= GetSignal(BPI_PIN_DT5) ? 0x20 : 0x00; // NOSONAR: GCC 10 doesn't fully support std::byte
|
||||
ret_val |= GetSignal(BPI_PIN_DT6) ? 0x40 : 0x00; // NOSONAR: GCC 10 doesn't fully support std::byte
|
||||
ret_val |= GetSignal(BPI_PIN_DT7) ? 0x80 : 0x00; // NOSONAR: GCC 10 doesn't fully support std::byte
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
bool DataSample_BananaM2p::GetSignal(int pin) const
|
||||
{
|
||||
int bank = SunXI::GPIO_BANK(pin);
|
||||
int num = SunXI::GPIO_NUM(pin);
|
||||
|
||||
return (bool)((data[bank] >> num) & 0x1);
|
||||
}
|
||||
|
||||
// This will return the Banana Pi data in the "Raspberry Pi" data format.
|
||||
uint32_t DataSample_BananaM2p::GetRawCapture() const
|
||||
{
|
||||
uint32_t rpi_data = 0;
|
||||
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_BSY)) << PIN_BSY;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_SEL)) << PIN_SEL;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_ATN)) << PIN_ATN;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_ACK)) << PIN_ACK;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_RST)) << PIN_RST;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_MSG)) << PIN_MSG;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_CD)) << PIN_CD;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_IO)) << PIN_IO;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_REQ)) << PIN_REQ;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_ACT)) << PIN_ACT;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_DP)) << PIN_DP;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_DT0)) << PIN_DT0;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_DT1)) << PIN_DT1;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_DT2)) << PIN_DT2;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_DT3)) << PIN_DT3;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_DT4)) << PIN_DT4;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_DT5)) << PIN_DT5;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_DT6)) << PIN_DT6;
|
||||
rpi_data |= ((uint32_t)GetSignal(BPI_PIN_DT7)) << PIN_DT7;
|
||||
|
||||
return rpi_data;
|
||||
}
|
94
cpp/hal/data_sample_bananam2p.h
Normal file
94
cpp/hal/data_sample_bananam2p.h
Normal file
@ -0,0 +1,94 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI Reloaded
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2022 akuker
|
||||
//
|
||||
// [ Logical representation of a single data sample ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/data_sample.h"
|
||||
#include "shared/scsi.h"
|
||||
#include <array>
|
||||
|
||||
#if defined CONNECT_TYPE_STANDARD
|
||||
#include "hal/connection_type/connection_standard.h"
|
||||
#elif defined CONNECT_TYPE_FULLSPEC
|
||||
#include "hal/connection_type/connection_fullspec.h"
|
||||
#elif defined CONNECT_TYPE_AIBOM
|
||||
#include "hal/connection_type/connection_aibom.h"
|
||||
#elif defined CONNECT_TYPE_GAMERNIUM
|
||||
#include "hal/connection_type/connection_gamernium.h"
|
||||
#else
|
||||
#error Invalid connection type or none specified
|
||||
#endif
|
||||
|
||||
class DataSample_BananaM2p final : public DataSample
|
||||
{
|
||||
public:
|
||||
bool GetSignal(int pin) const override;
|
||||
|
||||
bool GetBSY() const override
|
||||
{
|
||||
return GetSignal(BPI_PIN_BSY);
|
||||
}
|
||||
bool GetSEL() const override
|
||||
{
|
||||
return GetSignal(BPI_PIN_SEL);
|
||||
}
|
||||
bool GetATN() const override
|
||||
{
|
||||
return GetSignal(BPI_PIN_ATN);
|
||||
}
|
||||
bool GetACK() const override
|
||||
{
|
||||
return GetSignal(BPI_PIN_ACK);
|
||||
}
|
||||
bool GetRST() const override
|
||||
{
|
||||
return GetSignal(BPI_PIN_RST);
|
||||
}
|
||||
bool GetMSG() const override
|
||||
{
|
||||
return GetSignal(BPI_PIN_MSG);
|
||||
}
|
||||
bool GetCD() const override
|
||||
{
|
||||
return GetSignal(BPI_PIN_CD);
|
||||
}
|
||||
bool GetIO() const override
|
||||
{
|
||||
return GetSignal(BPI_PIN_IO);
|
||||
}
|
||||
bool GetREQ() const override
|
||||
{
|
||||
return GetSignal(BPI_PIN_REQ);
|
||||
}
|
||||
bool GetACT() const override
|
||||
{
|
||||
return GetSignal(BPI_PIN_ACT);
|
||||
}
|
||||
bool GetDP() const override
|
||||
{
|
||||
return GetSignal(BPI_PIN_DP);
|
||||
}
|
||||
|
||||
uint8_t GetDAT() const override;
|
||||
|
||||
uint32_t GetRawCapture() const override;
|
||||
|
||||
DataSample_BananaM2p(const array<uint32_t, 12> &in_data, uint64_t in_timestamp)
|
||||
: DataSample{in_timestamp}, data{in_data}
|
||||
{
|
||||
}
|
||||
DataSample_BananaM2p() = default;
|
||||
|
||||
~DataSample_BananaM2p() override = default;
|
||||
|
||||
private:
|
||||
array<uint32_t, 12> data = {0};
|
||||
};
|
14
cpp/hal/data_sample_raspberry.cpp
Normal file
14
cpp/hal/data_sample_raspberry.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI Reloaded
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2022 akuker
|
||||
//
|
||||
// [ SCSI Bus Monitor ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "shared/scsi.h"
|
||||
#include "data_sample.h"
|
||||
|
109
cpp/hal/data_sample_raspberry.h
Normal file
109
cpp/hal/data_sample_raspberry.h
Normal file
@ -0,0 +1,109 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI Reloaded
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2022 akuker
|
||||
//
|
||||
// [ Logical representation of a single data sample ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/data_sample.h"
|
||||
#include "shared/scsi.h"
|
||||
|
||||
#if defined CONNECT_TYPE_STANDARD
|
||||
#include "hal/connection_type/connection_standard.h"
|
||||
#elif defined CONNECT_TYPE_FULLSPEC
|
||||
#include "hal/connection_type/connection_fullspec.h"
|
||||
#elif defined CONNECT_TYPE_AIBOM
|
||||
#include "hal/connection_type/connection_aibom.h"
|
||||
#elif defined CONNECT_TYPE_GAMERNIUM
|
||||
#include "hal/connection_type/connection_gamernium.h"
|
||||
#else
|
||||
#error Invalid connection type or none specified
|
||||
#endif
|
||||
|
||||
class DataSample_Raspberry final : public DataSample
|
||||
{
|
||||
public:
|
||||
bool GetSignal(int pin) const override
|
||||
{
|
||||
return (bool)((data >> pin) & 1);
|
||||
};
|
||||
|
||||
bool GetBSY() const override
|
||||
{
|
||||
return GetSignal(PIN_BSY);
|
||||
}
|
||||
bool GetSEL() const override
|
||||
{
|
||||
return GetSignal(PIN_SEL);
|
||||
}
|
||||
bool GetATN() const override
|
||||
{
|
||||
return GetSignal(PIN_ATN);
|
||||
}
|
||||
bool GetACK() const override
|
||||
{
|
||||
return GetSignal(PIN_ACK);
|
||||
}
|
||||
bool GetRST() const override
|
||||
{
|
||||
return GetSignal(PIN_RST);
|
||||
}
|
||||
bool GetMSG() const override
|
||||
{
|
||||
return GetSignal(PIN_MSG);
|
||||
}
|
||||
bool GetCD() const override
|
||||