mirror of https://github.com/akuker/RASCSI.git
Basic discrete I/O seems to be partially working
This commit is contained in:
parent
245098be07
commit
61966a577b
|
@ -7,6 +7,8 @@
|
|||
*.vcd
|
||||
*.json
|
||||
*.html
|
||||
*.d
|
||||
*.o
|
||||
rascsi.dat
|
||||
obj
|
||||
bin
|
||||
|
@ -16,3 +18,4 @@ coverage
|
|||
.project
|
||||
.cproject
|
||||
.settings
|
||||
settings.json
|
|
@ -1,45 +0,0 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"cstddef": "cpp",
|
||||
"array": "cpp",
|
||||
"chrono": "cpp",
|
||||
"functional": "cpp",
|
||||
"istream": "cpp",
|
||||
"ostream": "cpp",
|
||||
"ratio": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"deque": "cpp",
|
||||
"vector": "cpp",
|
||||
"compare": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"list": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"limits": "cpp",
|
||||
"new": "cpp",
|
||||
"string": "cpp",
|
||||
"string_view": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"concepts": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"map": "cpp",
|
||||
"exception": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"memory": "cpp",
|
||||
"numbers": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"system_error": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
}
|
||||
}
|
52
cpp/Makefile
52
cpp/Makefile
|
@ -60,7 +60,7 @@ RASDUMP = rasdump
|
|||
SCSIMON = scsimon
|
||||
RASCSI_TEST = rascsi_test
|
||||
REGISTERS_TEST = registers
|
||||
GPIO_TEST = gpiotest
|
||||
SCSILOOP = scsiloop
|
||||
|
||||
SYSTEMD_CONF = /etc/systemd/system/rascsi.service
|
||||
RSYSLOG_CONF = /etc/rsyslog.d/rascsi.conf
|
||||
|
@ -80,7 +80,8 @@ BIN_ALL = \
|
|||
$(BINDIR)/$(RASCSI) \
|
||||
$(BINDIR)/$(RASCTL) \
|
||||
$(BINDIR)/$(SCSIMON) \
|
||||
$(BINDIR)/$(RASDUMP)
|
||||
$(BINDIR)/$(RASDUMP) \
|
||||
$(BINDIR)/$(SCSILOOP)
|
||||
|
||||
SRC_PROTOC = \
|
||||
rascsi_interface.proto
|
||||
|
@ -89,6 +90,7 @@ SRC_PROTOBUF = \
|
|||
rascsi_interface.pb.cpp
|
||||
|
||||
SRC_SHARED = \
|
||||
list_devices.cpp \
|
||||
rascsi_version.cpp \
|
||||
rasutil.cpp \
|
||||
protobuf_util.cpp \
|
||||
|
@ -123,12 +125,14 @@ SRC_RASDUMP += $(shell find ./hal -name '*.cpp')
|
|||
|
||||
SRC_RASCSI_TEST = $(shell find ./test -name '*.cpp')
|
||||
|
||||
SRC_GPIO_TEST = \
|
||||
scsi.cpp \
|
||||
gpiotest.cpp
|
||||
SRC_GPIO_TEST += $(shell find ./hal -name '*.cpp')
|
||||
SRC_SCSILOOP= \
|
||||
scsiloop.cpp \
|
||||
bus.cpp \
|
||||
rasutil.cpp \
|
||||
rascsi_version.cpp
|
||||
SRC_SCSILOOP += $(shell find ./hal -name '*.cpp')
|
||||
|
||||
vpath %.h ./ ./controllers ./devices ./monitor ./hal ./hal/boards ./hal/pi_defs ./rascsi ./rasctl ../BPI-WiringPi2/wiringPi/
|
||||
vpath %.h ./ ./controllers ./devices ./monitor ./hal ./hal/boards ./hal/pi_defs ./rascsi ./rasctl
|
||||
vpath %.cpp ./ ./controllers ./devices ./monitor ./test ./hal ./hal/boards ./hal/pi_defs ./rascsi ./rasctl
|
||||
vpath %.o ./$(OBJDIR)
|
||||
vpath ./$(BINDIR)
|
||||
|
@ -140,18 +144,16 @@ OBJ_RASCTL_CORE := $(addprefix $(OBJDIR)/,$(notdir $(SRC_RASCTL_CORE:%.cpp=%.o))
|
|||
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_SCSILOOP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SCSILOOP:%.cpp=%.o)))
|
||||
OBJ_RASCSI_TEST := $(addprefix $(OBJDIR)/,$(notdir $(SRC_RASCSI_TEST:%.cpp=%.o)))
|
||||
OBJ_SHARED := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SHARED:%.cpp=%.o)))
|
||||
OBJ_PROTOBUF := $(addprefix $(OBJDIR)/,$(notdir $(SRC_PROTOBUF:%.cpp=%.o)))
|
||||
OBJ_GPIO_TEST := $(addprefix $(OBJDIR)/,$(notdir $(SRC_GPIO_TEST:%.cpp=%.o)))
|
||||
|
||||
GEN_PROTOBUF := $(SRC_PROTOBUF) rascsi_interface.pb.h
|
||||
|
||||
LIB_BPI_WIRINGPI := $(OBJDIR)/libwiringPi.a
|
||||
|
||||
# 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_SCSIMON) $(OBJ_RASCSI_TEST))
|
||||
ALL_DEPS := $(patsubst %.o,%.d,$(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_SCSIMON) $(OBJ_SCSILOOP) $(OBJ_RASCSI_TEST))
|
||||
-include $(ALL_DEPS)
|
||||
|
||||
$(OBJDIR) $(BINDIR):
|
||||
|
@ -194,39 +196,39 @@ docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt $(DOC_DIR)/s
|
|||
|
||||
$(SRC_SHARED) $(SRC_RASCSI_CORE) $(SRC_RASCTL_CORE): $(OBJ_PROTOBUF)
|
||||
|
||||
$(BINDIR)/$(RASCSI): $(SRC_PROTOBUF) $(OBJ_RASCSI_CORE) $(OBJ_RASCSI) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(LIB_BPI_WIRINGPI) | $(BINDIR)
|
||||
$(BINDIR)/$(RASCSI): $(SRC_PROTOBUF) $(OBJ_RASCSI_CORE) $(OBJ_RASCSI) $(OBJ_SHARED) $(OBJ_PROTOBUF) | $(BINDIR)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI_CORE) $(OBJ_RASCSI) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(LIB_BPI_WIRINGPI) -lpthread -lpcap -lprotobuf -lstdc++fs
|
||||
|
||||
$(BINDIR)/$(RASCTL): $(SRC_PROTOBUF) $(OBJ_RASCTL_CORE) $(OBJ_RASCTL) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(LIB_BPI_WIRINGPI) | $(BINDIR)
|
||||
$(BINDIR)/$(RASCTL): $(SRC_PROTOBUF) $(OBJ_RASCTL_CORE) $(OBJ_RASCTL) $(OBJ_SHARED) $(OBJ_PROTOBUF) | $(BINDIR)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCTL_CORE) $(OBJ_RASCTL) $(OBJ_SHARED) $(OBJ_PROTOBUF) -lpthread -lprotobuf
|
||||
|
||||
$(BINDIR)/$(RASDUMP): $(OBJ_RASDUMP) $(LIB_BPI_WIRINGPI) | $(BINDIR)
|
||||
$(BINDIR)/$(RASDUMP): $(OBJ_RASDUMP) | $(BINDIR)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASDUMP) $(LIB_BPI_WIRINGPI) -lpthread
|
||||
|
||||
$(BINDIR)/$(SCSIMON): $(OBJ_SCSIMON) $(LIB_BPI_WIRINGPI) | $(BINDIR)
|
||||
$(BINDIR)/$(SCSIMON): $(OBJ_SCSIMON) | $(BINDIR)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_SCSIMON) $(LIB_BPI_WIRINGPI) -lpthread
|
||||
|
||||
$(BINDIR)/$(RASCSI_TEST): $(SRC_PROTOBUF) $(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI_TEST) $(OBJ_RASCTL_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(LIB_BPI_WIRINGPI) | $(BINDIR)
|
||||
$(BINDIR)/$(RASCSI_TEST): $(SRC_PROTOBUF) $(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI_TEST) $(OBJ_RASCTL_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) | $(BINDIR)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(LIB_BPI_WIRINGPI) -lpthread -lpcap -lprotobuf -lstdc++fs -lgmock -lgtest
|
||||
|
||||
$(BINDIR)/$(GPIO_TEST): $(OBJ_GPIO_TEST) $(LIB_BPI_WIRINGPI) | $(BINDIR)
|
||||
echo $(OBJ_GPIO_TEST)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_GPIO_TEST) $(LIB_BPI_WIRINGPI) -lpthread
|
||||
$(BINDIR)/$(SCSILOOP): $(SRC_PROTOBUF) $(OBJ_SCSILOOP) | $(BINDIR)
|
||||
echo SCSILOOP SRC: $(SRC_SCSILOOP)
|
||||
echo SCSILOOP OBJ: $(OBJ_SCSILOOP)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_SCSILOOP) -lpthread
|
||||
|
||||
# Phony rules for building individual utilities
|
||||
.PHONY: $(RASCSI) $(RASCTL) $(RASDUMP) $(SCSIMON) $(GPIO_TEST)
|
||||
.PHONY: $(RASCSI) $(RASCTL) $(RASDUMP) $(SCSIMON) $(SCSILOOP)
|
||||
$(RASCSI) : $(BINDIR)/$(RASCSI)
|
||||
$(RASCTL) : $(BINDIR)/$(RASCTL)
|
||||
$(RASDUMP) : $(BINDIR)/$(RASDUMP)
|
||||
$(SCSIMON) : $(BINDIR)/$(SCSIMON)
|
||||
$(GPIO_TEST) : $(BINDIR)/$(GPIO_TEST)
|
||||
$(SCSILOOP) : $(BINDIR)/$(SCSILOOP)
|
||||
|
||||
|
||||
## clean : Remove all of the object files, intermediate
|
||||
## compiler files and executable files
|
||||
.PHONY: clean
|
||||
clean:
|
||||
make -j1 -C ../BPI-WiringPi2/wiringPi/ clean
|
||||
rm -rf $(OBJDIR) $(BINDIR) $(GEN_PROTOBUF) $(COVERAGE_DIR) $(COVERAGE_FILE)
|
||||
|
||||
## install : Copies all of the man pages to the correct location
|
||||
|
@ -286,12 +288,6 @@ $(MAN_PAGE_DIR)/:
|
|||
echo "-- Creating directory $@"
|
||||
mkdir -p $@
|
||||
|
||||
$(LIB_BPI_WIRINGPI) : | $(OBJDIR)
|
||||
make -j1 -C ../BPI-WiringPi2/wiringPi/ static CC=$(CC) AR=$(AR) RANLIB=$(RANLIB)
|
||||
cp ../BPI-WiringPi2/wiringPi/libwiringPi.a $@
|
||||
|
||||
|
||||
|
||||
## help : Lists information about how to use the makefile
|
||||
# The help rule is based upon the approach from:
|
||||
# https://swcarpentry.github.io/make-novice/08-self-doc/index.html
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
#/bin/sh
|
||||
clear
|
||||
make scsiloop CROSS_COMPILE=arm-linux-gnueabihf- -j8
|
||||
scp ./bin/fullspec/* akuker@10.0.1.116:/home/akuker/
|
260
cpp/gpiotest.cpp
260
cpp/gpiotest.cpp
|
@ -1,260 +0,0 @@
|
|||
|
||||
// Kernel module to access cycle count registers:
|
||||
// https://matthewarcus.wordpress.com/2018/01/27/using-the-cycle-counter-registers-on-the-raspberry-pi-3/
|
||||
|
||||
|
||||
//https://mindplusplus.wordpress.com/2013/05/21/accessing-the-raspberry-pis-1mhz-timer/
|
||||
|
||||
// Reading register from user space:
|
||||
// https://stackoverflow.com/questions/59749160/reading-from-register-of-allwinner-h3-arm-processor
|
||||
|
||||
|
||||
// Maybe kernel patch>
|
||||
//https://yhbt.net/lore/all/20140707085858.GG16262@lukather/T/
|
||||
|
||||
|
||||
//
|
||||
// Access the Raspberry Pi System Timer registers directly.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include "hal/sbc_version.h"
|
||||
#include "hal/systimer.h"
|
||||
#include <sched.h>
|
||||
#include <string>
|
||||
#include "common.h"
|
||||
#include "log.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||
|
||||
#include "hal/gpiobus.h"
|
||||
#include "hal/gpiobus_factory.h"
|
||||
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace spdlog;
|
||||
|
||||
bool InitBus()
|
||||
{
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__);
|
||||
SBC_Version::Init();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void test_timer();
|
||||
void test_gpio();
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Pin the thread to a specific CPU
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void FixCpu(int cpu)
|
||||
{
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__);
|
||||
// Get the number of CPUs
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
sched_getaffinity(0, sizeof(cpu_set_t), &cpuset);
|
||||
int cpus = CPU_COUNT(&cpuset);
|
||||
|
||||
// Set the thread affinity
|
||||
if (cpu < cpus) {
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(cpu, &cpuset);
|
||||
sched_setaffinity(0, sizeof(cpu_set_t), &cpuset);
|
||||
}
|
||||
}
|
||||
|
||||
string current_log_level = "";
|
||||
|
||||
bool SetLogLevel(const string& log_level)
|
||||
{
|
||||
if (log_level == "trace") {
|
||||
set_level(level::trace);
|
||||
}
|
||||
else if (log_level == "debug") {
|
||||
set_level(level::debug);
|
||||
}
|
||||
else if (log_level == "info") {
|
||||
set_level(level::info);
|
||||
}
|
||||
else if (log_level == "warn") {
|
||||
set_level(level::warn);
|
||||
}
|
||||
else if (log_level == "err") {
|
||||
set_level(level::err);
|
||||
}
|
||||
else if (log_level == "critical") {
|
||||
set_level(level::critical);
|
||||
}
|
||||
else if (log_level == "off") {
|
||||
set_level(level::off);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
current_log_level = log_level;
|
||||
|
||||
LOGINFO("Set log level to '%s'", current_log_level.c_str())
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void TerminationHandler(int signum)
|
||||
{
|
||||
// Cleanup();
|
||||
|
||||
exit(signum);
|
||||
}
|
||||
|
||||
|
||||
#include "wiringPi.h"
|
||||
|
||||
void blink(){
|
||||
|
||||
printf("Simple Blink\n");
|
||||
wiringPiSetup();
|
||||
for(int i=0; i<20; i++){
|
||||
pinMode(i,OUTPUT);
|
||||
}
|
||||
|
||||
for(int i=0; i<20; i++){
|
||||
for(int pin=0; pin<20; pin++){
|
||||
printf("Setting pin %d high\n", pin);
|
||||
digitalWrite(pin, HIGH);
|
||||
delay(100);
|
||||
}
|
||||
for(int pin=0; pin<20; pin++){
|
||||
printf("Setting pin %d low\n", pin);
|
||||
digitalWrite(pin, LOW);
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Main processing
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
// added setvbuf to override stdout buffering, so logs are written immediately and not when the process exits.
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
if(argc > 1){
|
||||
SetLogLevel(argv[1]);
|
||||
}else{
|
||||
SetLogLevel("trace");
|
||||
}
|
||||
|
||||
// Create a thread-safe stdout logger to process the log messages
|
||||
auto logger = spdlog::stdout_color_mt("rascsi stdout logger");
|
||||
|
||||
// Signal handler to detach all devices on a KILL or TERM signal
|
||||
struct sigaction termination_handler;
|
||||
termination_handler.sa_handler = TerminationHandler;
|
||||
sigemptyset(&termination_handler.sa_mask);
|
||||
termination_handler.sa_flags = 0;
|
||||
sigaction(SIGINT, &termination_handler, nullptr);
|
||||
sigaction(SIGTERM, &termination_handler, nullptr);
|
||||
|
||||
if (!InitBus()) {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
// blink();
|
||||
// test_timer();
|
||||
test_gpio();
|
||||
|
||||
}
|
||||
|
||||
void test_gpio(){
|
||||
// Force the system timer to initialize
|
||||
SysTimer::instance().SleepNsec(0);
|
||||
|
||||
auto gpio_bus = GPIOBUS_Factory::Create();
|
||||
gpio_bus->Init(TARGET);
|
||||
printf("----------- Done with init()\n");
|
||||
printf("----------- Done with init()\n");
|
||||
printf("----------- Done with init()\n");
|
||||
printf("----------- Done with init()\n");
|
||||
|
||||
for(int i = 0; i< 10; i++){
|
||||
LOGTRACE("%s Blink on", __PRETTY_FUNCTION__);
|
||||
// gpio_bus->SetSignal(gpio_bus->PIN_ACT, true);
|
||||
sleep(1);
|
||||
LOGTRACE("%s Blink off", __PRETTY_FUNCTION__);
|
||||
// gpio_bus->SetSignal(gpio_bus->PIN_ACT, false);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
//gpio_bus->SetDirectionOut();
|
||||
LOGTRACE("%s Data 0x00", __PRETTY_FUNCTION__);
|
||||
gpio_bus->SetDAT(0x0);
|
||||
sleep(1);
|
||||
LOGTRACE("%s Data 0xFF", __PRETTY_FUNCTION__);
|
||||
gpio_bus->SetDAT(0xFF);
|
||||
sleep(1);
|
||||
LOGTRACE("%s Data 0xAA", __PRETTY_FUNCTION__);
|
||||
gpio_bus->SetDAT(0xAA);
|
||||
sleep(1);
|
||||
LOGTRACE("%s Data 0x55", __PRETTY_FUNCTION__);
|
||||
gpio_bus->SetDAT(0x55);
|
||||
}
|
||||
|
||||
void test_timer(){
|
||||
|
||||
uint32_t before = SysTimer::instance().GetTimerLow();
|
||||
sleep(1);
|
||||
uint32_t after = SysTimer::instance().GetTimerLow();
|
||||
|
||||
LOGINFO("first sample: %d %08X", (before - after), (after - before));
|
||||
|
||||
uint64_t sum = 0;
|
||||
int count = 0;
|
||||
for(int i=0; i < 100; i++){
|
||||
before = SysTimer::instance().GetTimerLow();
|
||||
usleep(1000);
|
||||
after = SysTimer::instance().GetTimerLow();
|
||||
sum += (after - before);
|
||||
count ++;
|
||||
}
|
||||
|
||||
LOGINFO("usleep() Average %d", (uint32_t)(sum / count));
|
||||
|
||||
sum = 0;
|
||||
count = 0;
|
||||
for(int i=0; i < 100; i++){
|
||||
before = SysTimer::instance().GetTimerLow();
|
||||
SysTimer::instance().SleepUsec(1000);
|
||||
after = SysTimer::instance().GetTimerLow();
|
||||
sum += (after - before);
|
||||
count ++;
|
||||
}
|
||||
LOGINFO("usleep() Average %d", (uint32_t)(sum / count));
|
||||
|
||||
before = SysTimer::instance().GetTimerLow();
|
||||
SysTimer::instance().SleepNsec(1000000);
|
||||
after = SysTimer::instance().GetTimerLow();
|
||||
LOGINFO("SysTimer::instance().SleepNSec: %d (expected ~1000)", (uint32_t)(after - before));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ bool GPIOBUS::Init(mode_e mode, board_type::rascsi_board_type_e rascsi_type)
|
|||
board = make_shared<board_type::Rascsi_Board_Type>(board_type::board_definition_standard);
|
||||
break;
|
||||
}
|
||||
board = make_shared<board_type::Rascsi_Board_Type>(board_type::board_definition_aibom);
|
||||
LOGINFO("Detected board type: %s", board->connect_desc.c_str());
|
||||
|
||||
// Save operation mode
|
||||
actmode = mode;
|
||||
|
@ -121,24 +121,20 @@ bool GPIOBUS::Init(mode_e mode, board_type::rascsi_board_type_e rascsi_type)
|
|||
}
|
||||
|
||||
// The GPIO hardware needs to be initialized before calling this function.
|
||||
void GPIOBUS::InitializeGpio(){
|
||||
// Set pull up/pull down
|
||||
void GPIOBUS::InitializeGpio()
|
||||
{
|
||||
// Set pull up/pull down
|
||||
LOGTRACE("%s Set pull up/down....", __PRETTY_FUNCTION__);
|
||||
board_type::gpio_pull_up_down_e pullmode ;
|
||||
if (board->signal_control_mode == 0)
|
||||
{
|
||||
board_type::gpio_pull_up_down_e pullmode;
|
||||
if (board->signal_control_mode == 0) {
|
||||
// #if SIGNAL_CONTROL_MODE == 0
|
||||
LOGTRACE("%s GPIO_PULLNONE", __PRETTY_FUNCTION__);
|
||||
pullmode = board_type::gpio_pull_up_down_e::GPIO_PULLNONE;
|
||||
}
|
||||
else if (board->signal_control_mode == 1)
|
||||
{
|
||||
} else if (board->signal_control_mode == 1) {
|
||||
// #elif SIGNAL_CONTROL_MODE == 1
|
||||
LOGTRACE("%s GPIO_PULLUP", __PRETTY_FUNCTION__);
|
||||
pullmode = board_type::gpio_pull_up_down_e ::GPIO_PULLUP;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// #else
|
||||
LOGTRACE("%s GPIO_PULLDOWN", __PRETTY_FUNCTION__);
|
||||
pullmode = board_type::gpio_pull_up_down_e ::GPIO_PULLDOWN;
|
||||
|
@ -170,7 +166,6 @@ void GPIOBUS::InitializeGpio(){
|
|||
// This is used to show that the application is running
|
||||
PinSetSignal(board->pin_enb, board->EnbOff());
|
||||
PinConfig(board->pin_enb, board_type::gpio_direction_e::GPIO_OUTPUT);
|
||||
|
||||
}
|
||||
|
||||
void GPIOBUS::Cleanup()
|
||||
|
@ -284,8 +279,9 @@ void GPIOBUS::Reset()
|
|||
SetMode(board->pin_dp, board_type::gpio_direction_e::GPIO_OUTPUT);
|
||||
}
|
||||
|
||||
// Initialize all signals
|
||||
signals = 0;
|
||||
// Re-read all signals
|
||||
Acquire();
|
||||
// signals = 0;
|
||||
#endif // ifdef __x86_64__ || __X86__
|
||||
}
|
||||
|
||||
|
@ -1116,3 +1112,11 @@ int GPIOBUS::GetCommandByteCount(BYTE opcode)
|
|||
return 6;
|
||||
}
|
||||
}
|
||||
|
||||
const string GPIOBUS::GetConnectDesc()
|
||||
{
|
||||
if (board == nullptr) {
|
||||
return "unknown";
|
||||
}
|
||||
return board->connect_desc;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
// #else
|
||||
// #error Invalid connection type or none specified
|
||||
// #endif
|
||||
|
||||
#define ENABLE_GPIO_TRACE
|
||||
#ifdef ENABLE_GPIO_TRACE
|
||||
#define GPIO_FUNCTION_TRACE LOGTRACE("%s", __PRETTY_FUNCTION__)
|
||||
#else
|
||||
|
@ -352,10 +352,7 @@ class GPIOBUS : public BUS
|
|||
|
||||
static int GetCommandByteCount(BYTE opcode);
|
||||
|
||||
const string GetConnectDesc()
|
||||
{
|
||||
return board->connect_desc;
|
||||
}
|
||||
const string GetConnectDesc();
|
||||
|
||||
#ifdef USE_SEL_EVENT_ENABLE
|
||||
// SEL signal interrupt
|
||||
|
@ -365,7 +362,11 @@ class GPIOBUS : public BUS
|
|||
// Clear SEL signal event
|
||||
#endif // USE_SEL_EVENT_ENABLE
|
||||
|
||||
protected:
|
||||
// TODO: THIS SHOULD BE PROTECTED
|
||||
static vector<board_type::pi_physical_pin_e> SignalTable; // signal table
|
||||
|
||||
// TODO: RESTORE THIS TO PROTECTED!!!
|
||||
// protected:
|
||||
// SCSI I/O signal control
|
||||
virtual void MakeTable() = 0;
|
||||
// Create work data
|
||||
|
@ -397,13 +398,13 @@ class GPIOBUS : public BUS
|
|||
|
||||
mode_e actmode = mode_e::TARGET; // Operation mode
|
||||
|
||||
shared_ptr<board_type::Rascsi_Board_Type> board;
|
||||
shared_ptr<board_type::Rascsi_Board_Type> board = nullptr;
|
||||
|
||||
#if !defined(__x86_64__) && !defined(__X86__)
|
||||
uint32_t baseaddr = 0; // Base address
|
||||
#endif
|
||||
|
||||
static vector<board_type::pi_physical_pin_e> SignalTable; // signal table
|
||||
|
||||
|
||||
#ifdef USE_SEL_EVENT_ENABLE
|
||||
struct gpioevent_request selevreq = {}; // SEL signal event request
|
||||
|
@ -442,7 +443,7 @@ class GPIOBUS : public BUS
|
|||
|
||||
array<uint32_t, 4> gpfsel; // GPFSEL0-4 backup values
|
||||
|
||||
uint32_t signals = 0; // All bus signals
|
||||
|
||||
|
||||
#if SIGNAL_CONTROL_MODE == 0
|
||||
array<array<uint32_t, 256>, 3> tblDatMsk; // Data mask table
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "hal/gpiobus.h"
|
||||
#include "hal/gpiobus_allwinner.h"
|
||||
#include "hal/pi_defs/bpi-gpio.h"
|
||||
#include "hal/systimer.h"
|
||||
#include "log.h"
|
||||
|
||||
extern int wiringPiMode;
|
||||
|
@ -146,12 +147,42 @@ GPIOBUS_Allwinner::BpiBoardsType GPIOBUS_Allwinner::bpiboard[] = {
|
|||
{NULL, 0, 0, 1, 2, 5, 0, NULL, NULL, NULL},
|
||||
};
|
||||
|
||||
std::vector<int> gpio_banks;
|
||||
|
||||
bool GPIOBUS_Allwinner::Init(mode_e mode, board_type::rascsi_board_type_e rascsi_type)
|
||||
{
|
||||
GPIOBUS::Init(mode, rascsi_type);
|
||||
SysTimer::Init();
|
||||
// Hard-coding to banana pi m2 plus for now
|
||||
phys_to_gpio_map = make_shared<Banana_Pi_Gpio_Mapping>(banana_pi_m2p_map);
|
||||
sunxi_setup();
|
||||
for (auto const &pair : phys_to_gpio_map->phys_to_gpio_map) {
|
||||
LOGDEBUG("{ %d, : %d}", (int)pair.first, pair.second)
|
||||
|
||||
int phys_pin = (int)pair.first;
|
||||
if (phys_pin < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int gpio_num = pair.second;
|
||||
|
||||
int gpio_bank = GPIO_BANK(gpio_num);
|
||||
|
||||
if (std::find(gpio_banks.begin(), gpio_banks.end(), gpio_bank) != gpio_banks.end()) {
|
||||
LOGTRACE("Duplicate bank: %d", gpio_bank)
|
||||
|
||||
} else {
|
||||
LOGDEBUG("New bank: %d", gpio_bank);
|
||||
gpio_banks.push_back(gpio_bank);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const &pair : phys_to_gpio_map->phys_to_gpio_map) {
|
||||
LOGDEBUG("{ %d, : %d}", (int)pair.first, pair.second)
|
||||
}
|
||||
|
||||
if (int result = sunxi_setup(); result != SETUP_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// wiringPiSetup();
|
||||
// wiringPiMode = WPI_MODE_GPIO;
|
||||
|
@ -293,32 +324,35 @@ BYTE GPIOBUS_Allwinner::GetDAT()
|
|||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
// LOGDEBUG("0:%02X 1:%02X 2:%02X 3:%02X 4:%02X 5:%02X 6:%02X 7:%02X P:%02X", GetSignal(PIN_DT0),
|
||||
// GetSignal(PIN_DT1),GetSignal(PIN_DT2),GetSignal(PIN_DT3),GetSignal(PIN_DT4),GetSignal(PIN_DT5),GetSignal(PIN_DT6),GetSignal(PIN_DT7),GetSignal(PIN_DP));
|
||||
// // TODO: This is crazy inefficient...
|
||||
// DWORD data =
|
||||
// ((GetSignal(PIN_DT0) ? 0x01: 0x00)<< 0) |
|
||||
// ((GetSignal(PIN_DT1) ? 0x01: 0x00)<< 1) |
|
||||
// ((GetSignal(PIN_DT2) ? 0x01: 0x00)<< 2) |
|
||||
// ((GetSignal(PIN_DT3) ? 0x01: 0x00)<< 3) |
|
||||
// ((GetSignal(PIN_DT4) ? 0x01: 0x00)<< 0) |
|
||||
// ((GetSignal(PIN_DT5) ? 0x01: 0x00)<< 5) |
|
||||
// ((GetSignal(PIN_DT6) ? 0x01: 0x00)<< 6) |
|
||||
// ((GetSignal(PIN_DT7) ? 0x01: 0x00)<< 7);
|
||||
// TODO: This is crazy inefficient...
|
||||
DWORD data = ((GetSignal(board->pin_dt0) ? 0x01 : 0x00) << 0) | ((GetSignal(board->pin_dt1) ? 0x01 : 0x00) << 1) |
|
||||
((GetSignal(board->pin_dt2) ? 0x01 : 0x00) << 2) | ((GetSignal(board->pin_dt3) ? 0x01 : 0x00) << 3) |
|
||||
((GetSignal(board->pin_dt4) ? 0x01 : 0x00) << 0) | ((GetSignal(board->pin_dt5) ? 0x01 : 0x00) << 5) |
|
||||
((GetSignal(board->pin_dt6) ? 0x01 : 0x00) << 6) | ((GetSignal(board->pin_dt7) ? 0x01 : 0x00) << 7);
|
||||
|
||||
// return (BYTE)data;
|
||||
return 0;
|
||||
return (BYTE)data;
|
||||
// return 0;
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::SetDAT(BYTE dat)
|
||||
{
|
||||
// TODO: This is crazy inefficient...
|
||||
// SetSignal(PIN_DT0, dat & (1 << 0));
|
||||
// SetSignal(PIN_DT1, dat & (1 << 1));
|
||||
// SetSignal(PIN_DT2, dat & (1 << 2));
|
||||
// SetSignal(PIN_DT3, dat & (1 << 3));
|
||||
// SetSignal(PIN_DT4, dat & (1 << 4));
|
||||
// SetSignal(PIN_DT5, dat & (1 << 5));
|
||||
// SetSignal(PIN_DT6, dat & (1 << 6));
|
||||
// SetSignal(PIN_DT7, dat & (1 << 7));
|
||||
PinSetSignal(board->pin_dt0, (dat & (1 << 0)) != 0 ? board_type::gpio_high_low_e::GPIO_STATE_HIGH
|
||||
: board_type::gpio_high_low_e::GPIO_STATE_LOW);
|
||||
PinSetSignal(board->pin_dt1, (dat & (1 << 1)) != 0 ? board_type::gpio_high_low_e::GPIO_STATE_HIGH
|
||||
: board_type::gpio_high_low_e::GPIO_STATE_LOW);
|
||||
PinSetSignal(board->pin_dt2, (dat & (1 << 2)) != 0 ? board_type::gpio_high_low_e::GPIO_STATE_HIGH
|
||||
: board_type::gpio_high_low_e::GPIO_STATE_LOW);
|
||||
PinSetSignal(board->pin_dt3, (dat & (1 << 3)) != 0 ? board_type::gpio_high_low_e::GPIO_STATE_HIGH
|
||||
: board_type::gpio_high_low_e::GPIO_STATE_LOW);
|
||||
PinSetSignal(board->pin_dt4, (dat & (1 << 4)) != 0 ? board_type::gpio_high_low_e::GPIO_STATE_HIGH
|
||||
: board_type::gpio_high_low_e::GPIO_STATE_LOW);
|
||||
PinSetSignal(board->pin_dt5, (dat & (1 << 5)) != 0 ? board_type::gpio_high_low_e::GPIO_STATE_HIGH
|
||||
: board_type::gpio_high_low_e::GPIO_STATE_LOW);
|
||||
PinSetSignal(board->pin_dt6, (dat & (1 << 6)) != 0 ? board_type::gpio_high_low_e::GPIO_STATE_HIGH
|
||||
: board_type::gpio_high_low_e::GPIO_STATE_LOW);
|
||||
PinSetSignal(board->pin_dt7, (dat & (1 << 7)) != 0 ? board_type::gpio_high_low_e::GPIO_STATE_HIGH
|
||||
: board_type::gpio_high_low_e::GPIO_STATE_LOW);
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
|
@ -329,12 +363,17 @@ void GPIOBUS_Allwinner::MakeTable(void)
|
|||
|
||||
void GPIOBUS_Allwinner::SetControl(board_type::pi_physical_pin_e pin, board_type::gpio_high_low_e ast)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
if ((int)pin < 0) {
|
||||
return;
|
||||
}
|
||||
GPIOBUS_Allwinner::SetSignal(pin, ast);
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
// LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::SetMode(board_type::pi_physical_pin_e pin, board_type::gpio_direction_e mode)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
int gpio_num = phys_to_gpio_map->phys_to_gpio_map.at(pin);
|
||||
int sunxi_gpio_direction = (mode == board_type::gpio_direction_e::GPIO_INPUT) ? INPUT : OUTPUT;
|
||||
|
||||
|
@ -349,10 +388,12 @@ void GPIOBUS_Allwinner::SetMode(board_type::pi_physical_pin_e pin, board_type::g
|
|||
// LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
bool GPIOBUS_Allwinner::GetSignal(board_type::pi_physical_pin_e pin)
|
||||
bool GPIOBUS_Allwinner::GetSignal(board_type::pi_physical_pin_e pin) const
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
int gpio_num = phys_to_gpio_map->phys_to_gpio_map.at(pin);
|
||||
int sunxi_gpio_state = sunxi_input_gpio(gpio_num);
|
||||
LOGDEBUG("%s GPIO %d is set to %d", __PRETTY_FUNCTION__, gpio_num, sunxi_gpio_state);
|
||||
|
||||
if (sunxi_gpio_state == HIGH) {
|
||||
return true;
|
||||
|
@ -364,8 +405,12 @@ bool GPIOBUS_Allwinner::GetSignal(board_type::pi_physical_pin_e pin)
|
|||
|
||||
void GPIOBUS_Allwinner::SetSignal(board_type::pi_physical_pin_e pin, board_type::gpio_high_low_e ast)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
LOGTRACE("pin(%d) ast(%d)", (int)pin, (int)ast)
|
||||
|
||||
int gpio_num = phys_to_gpio_map->phys_to_gpio_map.at(pin);
|
||||
int sunxi_gpio_state = (ast == board_type::gpio_high_low_e::GPIO_STATE_HIGH) ? HIGH : LOW;
|
||||
LOGTRACE("gpio(%d) sunxi_state(%d)", gpio_num, sunxi_gpio_state)
|
||||
sunxi_output_gpio(gpio_num, sunxi_gpio_state);
|
||||
// LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
// digitalWrite(pin, ast);
|
||||
|
@ -418,9 +463,16 @@ void GPIOBUS_Allwinner::EnableIRQ()
|
|||
|
||||
void GPIOBUS_Allwinner::PinConfig(board_type::pi_physical_pin_e pin, board_type::gpio_direction_e mode)
|
||||
{
|
||||
int gpio_num = phys_to_gpio_map->phys_to_gpio_map.at(pin);
|
||||
int sunxi_gpio_state = (mode == board_type::gpio_direction_e::GPIO_INPUT) ? INPUT : OUTPUT;
|
||||
sunxi_output_gpio(gpio_num, sunxi_gpio_state);
|
||||
GPIO_FUNCTION_TRACE
|
||||
int gpio_num = 0;
|
||||
try {
|
||||
gpio_num = phys_to_gpio_map->phys_to_gpio_map.at(pin);
|
||||
} catch (const std::out_of_range &e) {
|
||||
LOGERROR("%s %d is not a valid pin", __PRETTY_FUNCTION__, (int)pin);
|
||||
}
|
||||
int sunxi_direction = (mode == board_type::gpio_direction_e::GPIO_INPUT) ? INPUT : OUTPUT;
|
||||
sunxi_setup_gpio(gpio_num, sunxi_direction, -1);
|
||||
// sunxi_output_gpio(gpio_num, sunxi_gpio_state);
|
||||
|
||||
// if(mode == board_type::gpio_high_low_e::GPIO_INPUT){
|
||||
// pinMode(pin, INPUT);
|
||||
|
@ -432,6 +484,7 @@ void GPIOBUS_Allwinner::PinConfig(board_type::pi_physical_pin_e pin, board_type:
|
|||
|
||||
void GPIOBUS_Allwinner::PullConfig(board_type::pi_physical_pin_e pin, board_type::gpio_pull_up_down_e mode)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
// Note: this will throw an exception if an invalid pin is specified
|
||||
int gpio_num = phys_to_gpio_map->phys_to_gpio_map.at(pin);
|
||||
|
||||
|
@ -449,12 +502,18 @@ void GPIOBUS_Allwinner::PullConfig(board_type::pi_physical_pin_e pin, board_type
|
|||
LOGERROR("%s INVALID PIN MODE", __PRETTY_FUNCTION__);
|
||||
return;
|
||||
}
|
||||
LOGERROR("%s not implemented!!", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::PinSetSignal(board_type::pi_physical_pin_e pin, board_type::gpio_high_low_e ast)
|
||||
{
|
||||
int gpio_num = phys_to_gpio_map->phys_to_gpio_map.at(pin);
|
||||
GPIO_FUNCTION_TRACE
|
||||
int gpio_num = -1;
|
||||
try {
|
||||
gpio_num = phys_to_gpio_map->phys_to_gpio_map.at(pin);
|
||||
} catch (const std::out_of_range &e) {
|
||||
LOGERROR("%s %d is not a valid pin", __PRETTY_FUNCTION__, (int)pin);
|
||||
exit(1);
|
||||
}
|
||||
int sunxi_gpio_state = (ast == board_type::gpio_high_low_e::GPIO_STATE_HIGH) ? HIGH : LOW;
|
||||
sunxi_output_gpio(gpio_num, sunxi_gpio_state);
|
||||
|
||||
|
@ -470,7 +529,8 @@ void GPIOBUS_Allwinner::DrvConfig(DWORD drive)
|
|||
|
||||
uint32_t GPIOBUS_Allwinner::Acquire()
|
||||
{
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
(void)sunxi_capture_all_gpio();
|
||||
// LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
// Only used for development/debugging purposes. Isn't really applicable
|
||||
// to any real-world RaSCSI application
|
||||
return 0;
|
||||
|
@ -480,8 +540,10 @@ uint32_t GPIOBUS_Allwinner::Acquire()
|
|||
|
||||
uint32_t GPIOBUS_Allwinner::sunxi_readl(volatile uint32_t *addr)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
#ifndef __arm__
|
||||
(void)addr;
|
||||
(void)
|
||||
addr;
|
||||
return 0;
|
||||
#else
|
||||
printf("sunxi_readl\n");
|
||||
|
@ -495,8 +557,10 @@ uint32_t GPIOBUS_Allwinner::sunxi_readl(volatile uint32_t *addr)
|
|||
|
||||
void GPIOBUS_Allwinner::sunxi_writel(volatile uint32_t *addr, uint32_t val)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
#ifndef __arm__
|
||||
(void)addr;
|
||||
(void)
|
||||
addr;
|
||||
(void)val;
|
||||
return;
|
||||
#else
|
||||
|
@ -509,6 +573,7 @@ void GPIOBUS_Allwinner::sunxi_writel(volatile uint32_t *addr, uint32_t val)
|
|||
|
||||
int GPIOBUS_Allwinner::sunxi_setup(void)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
#ifndef __arm__
|
||||
return SETUP_MMAP_FAIL;
|
||||
#else
|
||||
|
@ -525,27 +590,40 @@ int GPIOBUS_Allwinner::sunxi_setup(void)
|
|||
printf("enter to sunxi_setup\n");
|
||||
|
||||
// mmap the GPIO memory registers
|
||||
if ((mem_fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0)
|
||||
if ((mem_fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) {
|
||||
LOGERROR("Error: Unable to open /dev/mem. Are you running as root?")
|
||||
LOGDEBUG("errno: [%08X] %s", errno, strerror(errno));
|
||||
return SETUP_DEVMEM_FAIL;
|
||||
}
|
||||
|
||||
if ((gpio_mem = (uint8_t *)malloc(BLOCK_SIZE + (PAGE_SIZE - 1))) == NULL)
|
||||
return SETUP_MALLOC_FAIL;
|
||||
if ((gpio_mem = (uint8_t *)malloc(BLOCK_SIZE + (PAGE_SIZE - 1))) == NULL) {
|
||||
LOGERROR("Error: Unable to allocate gpio memory. Are you running as root?")
|
||||
LOGDEBUG("errno: [%08X] %s", errno, strerror(errno));
|
||||
return SETUP_DEVMEM_FAIL;
|
||||
}
|
||||
|
||||
if ((uint32_t)gpio_mem % PAGE_SIZE)
|
||||
gpio_mem += PAGE_SIZE - ((uint32_t)gpio_mem % PAGE_SIZE);
|
||||
|
||||
gpio_map = (uint32_t *)mmap((caddr_t)gpio_mem, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, mem_fd,
|
||||
SUNXI_GPIO_BASE);
|
||||
pio_map = gpio_map + (SUNXI_GPIO_REG_OFFSET >> 2);
|
||||
// printf("gpio_mem[%x] gpio_map[%x] pio_map[%x]\n", gpio_mem, gpio_map, pio_map);
|
||||
if ((void *)gpio_map == MAP_FAILED) {
|
||||
LOGERROR("Error: Unable to map gpio memory. Are you running as root?")
|
||||
LOGDEBUG("errno: [%08X] %s", errno, strerror(errno));
|
||||
return SETUP_MMAP_FAIL;
|
||||
}
|
||||
pio_map = gpio_map + (SUNXI_GPIO_REG_OFFSET >> 2);
|
||||
LOGTRACE("gpio_mem[%p] gpio_map[%p] pio_map[%p]", gpio_mem, gpio_map, pio_map)
|
||||
// R_PIO GPIO LMN
|
||||
r_gpio_map =
|
||||
(uint32_t *)mmap((caddr_t)0, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, SUNXI_R_GPIO_BASE);
|
||||
r_pio_map = r_gpio_map + (SUNXI_R_GPIO_REG_OFFSET >> 2);
|
||||
// printf("r_gpio_map[%x] r_pio_map[%x]\n", r_gpio_map, r_pio_map);
|
||||
|
||||
if ((int32_t)gpio_map < 0)
|
||||
if ((void *)r_gpio_map == MAP_FAILED) {
|
||||
LOGERROR("Error: Unable to map r_gpio memory. Are you running as root?")
|
||||
LOGDEBUG("errno: [%08X] %s", errno, strerror(errno));
|
||||
return SETUP_MMAP_FAIL;
|
||||
}
|
||||
r_pio_map = r_gpio_map + (SUNXI_R_GPIO_REG_OFFSET >> 2);
|
||||
LOGTRACE("r_gpio_map[%p] r_pio_map[%p]", r_gpio_map, r_pio_map)
|
||||
|
||||
return SETUP_OK;
|
||||
#endif
|
||||
|
@ -553,8 +631,10 @@ int GPIOBUS_Allwinner::sunxi_setup(void)
|
|||
|
||||
void GPIOBUS_Allwinner::sunxi_set_pullupdn(int gpio, int pud)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
#ifndef __arm__
|
||||
(void)gpio;
|
||||
(void)
|
||||
gpio;
|
||||
(void)pud;
|
||||
return;
|
||||
#else
|
||||
|
@ -562,7 +642,7 @@ void GPIOBUS_Allwinner::sunxi_set_pullupdn(int gpio, int pud)
|
|||
int bank = GPIO_BANK(gpio); // gpio >> 5
|
||||
int index = GPIO_PUL_INDEX(gpio); // (gpio & 0x1f) >> 4
|
||||
int offset = GPIO_PUL_OFFSET(gpio); // (gpio) & 0x0F) << 1
|
||||
printf("sunxi_set_pullupdn\n");
|
||||
LOGDEBUG("%s gpio(%d) bank(%d) index(%d) offset(%d)", __PRETTY_FUNCTION__, gpio, bank, index, offset)
|
||||
|
||||
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *)pio_map)->gpio_bank[bank];
|
||||
/* DK, for PL and PM */
|
||||
|
@ -580,8 +660,10 @@ void GPIOBUS_Allwinner::sunxi_set_pullupdn(int gpio, int pud)
|
|||
|
||||
void GPIOBUS_Allwinner::sunxi_setup_gpio(int gpio, int direction, int pud)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
#ifndef __arm__
|
||||
(void)gpio;
|
||||
(void)
|
||||
gpio;
|
||||
(void)direction;
|
||||
(void)pud;
|
||||
return;
|
||||
|
@ -590,7 +672,8 @@ void GPIOBUS_Allwinner::sunxi_setup_gpio(int gpio, int direction, int pud)
|
|||
int bank = GPIO_BANK(gpio); // gpio >> 5
|
||||
int index = GPIO_CFG_INDEX(gpio); // (gpio & 0x1F) >> 3
|
||||
int offset = GPIO_CFG_OFFSET(gpio); // ((gpio & 0x1F) & 0x7) << 2
|
||||
printf("sunxi_setup_gpio\n");
|
||||
LOGDEBUG("%s gpio(%d) bank(%d) index(%d) offset(%d)", __PRETTY_FUNCTION__, gpio, bank, index, offset)
|
||||
|
||||
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *)pio_map)->gpio_bank[bank];
|
||||
/* DK, for PL and PM */
|
||||
if (bank >= 11) {
|
||||
|
@ -609,7 +692,7 @@ void GPIOBUS_Allwinner::sunxi_setup_gpio(int gpio, int direction, int pud)
|
|||
regval |= (1 << offset);
|
||||
*(&pio->CFG[0] + index) = regval;
|
||||
} else {
|
||||
printf("line:%dgpio number error\n", __LINE__);
|
||||
LOGERROR("line:%dgpio number error\n", __LINE__);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -617,11 +700,12 @@ void GPIOBUS_Allwinner::sunxi_setup_gpio(int gpio, int direction, int pud)
|
|||
// Contribution by Eric Ptak <trouch@trouch.com>
|
||||
int GPIOBUS_Allwinner::sunxi_gpio_function(int gpio)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
uint32_t regval = 0;
|
||||
int bank = GPIO_BANK(gpio); // gpio >> 5
|
||||
int index = GPIO_CFG_INDEX(gpio); // (gpio & 0x1F) >> 3
|
||||
int offset = GPIO_CFG_OFFSET(gpio); // ((gpio & 0x1F) & 0x7) << 2
|
||||
printf("sunxi_gpio_function\n");
|
||||
|
||||
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *)pio_map)->gpio_bank[bank];
|
||||
/* DK, for PL and PM */
|
||||
if (bank >= 11) {
|
||||
|
@ -637,13 +721,18 @@ int GPIOBUS_Allwinner::sunxi_gpio_function(int gpio)
|
|||
|
||||
void GPIOBUS_Allwinner::sunxi_output_gpio(int gpio, int value)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
int bank = GPIO_BANK(gpio); // gpio >> 5
|
||||
int num = GPIO_NUM(gpio); // gpio & 0x1F
|
||||
|
||||
printf("gpio(%d) bank(%d) num(%d)\n", gpio, bank, num);
|
||||
LOGDEBUG("%s gpio(%d) bank(%d) num(%d) value(%d)", __PRETTY_FUNCTION__, gpio, bank, num, value)
|
||||
LOGTRACE("pio_map: %p", pio_map)
|
||||
LOGTRACE("pio_map->gpio_bank: %p", &((sunxi_gpio_reg_t *)pio_map)->gpio_bank[0])
|
||||
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *)pio_map)->gpio_bank[bank];
|
||||
LOGTRACE("pio: %p", pio)
|
||||
/* DK, for PL and PM */
|
||||
if (bank >= 11) {
|
||||
LOGTRACE("bank > 11");
|
||||
bank -= 11;
|
||||
pio = &((sunxi_gpio_reg_t *)r_pio_map)->gpio_bank[bank];
|
||||
}
|
||||
|
@ -654,13 +743,14 @@ void GPIOBUS_Allwinner::sunxi_output_gpio(int gpio, int value)
|
|||
*(&pio->DAT) |= (1 << num);
|
||||
}
|
||||
|
||||
int GPIOBUS_Allwinner::sunxi_input_gpio(int gpio)
|
||||
int GPIOBUS_Allwinner::sunxi_input_gpio(int gpio) const
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
uint32_t regval = 0;
|
||||
int bank = GPIO_BANK(gpio); // gpio >> 5
|
||||
int num = GPIO_NUM(gpio); // gpio & 0x1F
|
||||
|
||||
printf("gpio(%d) bank(%d) num(%d)\n", gpio, bank, num);
|
||||
LOGDEBUG("%s gpio(%d) bank(%d) num(%d)", __PRETTY_FUNCTION__, gpio, bank, num);
|
||||
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *)pio_map)->gpio_bank[bank];
|
||||
/* DK, for PL and PM */
|
||||
if (bank >= 11) {
|
||||
|
@ -674,8 +764,46 @@ int GPIOBUS_Allwinner::sunxi_input_gpio(int gpio)
|
|||
return regval;
|
||||
}
|
||||
|
||||
uint32_t GPIOBUS_Allwinner::sunxi_capture_all_gpio()
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
|
||||
uint32_t value = 0;
|
||||
|
||||
for (auto bank : gpio_banks) {
|
||||
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *)pio_map)->gpio_bank[bank];
|
||||
/* DK, for PL and PM */
|
||||
if (bank >= 11) {
|
||||
pio = &((sunxi_gpio_reg_t *)r_pio_map)->gpio_bank[(bank - 11)];
|
||||
}
|
||||
|
||||
uint32_t regval = *(&pio->DAT);
|
||||
signals[bank] = regval;
|
||||
LOGDEBUG("Bank %d value %08X", bank, regval);
|
||||
}
|
||||
return value;
|
||||
|
||||
// uint32_t regval = 0;
|
||||
// int bank = GPIO_BANK(gpio); // gpio >> 5
|
||||
// int num = GPIO_NUM(gpio); // gpio & 0x1F
|
||||
|
||||
// printf("gpio(%d) bank(%d) num(%d)\n", gpio, bank, num);
|
||||
// sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *)pio_map)->gpio_bank[bank];
|
||||
// /* DK, for PL and PM */
|
||||
// if (bank >= 11) {
|
||||
// bank -= 11;
|
||||
// pio = &((sunxi_gpio_reg_t *)r_pio_map)->gpio_bank[bank];
|
||||
// }
|
||||
|
||||
// regval = *(&pio->DAT);
|
||||
// regval = regval >> num;
|
||||
// regval &= 1;
|
||||
// return regval;
|
||||
}
|
||||
|
||||
int GPIOBUS_Allwinner::bpi_piGpioLayout(void)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
FILE *bpiFd;
|
||||
char buffer[1024];
|
||||
char hardware[1024];
|
||||
|
@ -764,6 +892,7 @@ int GPIOBUS_Allwinner::bpi_piGpioLayout(void)
|
|||
|
||||
void GPIOBUS_Allwinner::set_pullupdn(int gpio, int pud)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
int clk_offset = PULLUPDNCLK_OFFSET + (gpio / 32);
|
||||
int shift = (gpio % 32);
|
||||
|
||||
|
@ -789,6 +918,7 @@ void GPIOBUS_Allwinner::set_pullupdn(int gpio, int pud)
|
|||
|
||||
void GPIOBUS_Allwinner::short_wait(void)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 150; i++) { // wait 150 cycles
|
||||
|
|
|
@ -47,7 +47,8 @@ class GPIOBUS_Allwinner : public GPIOBUS
|
|||
// Get DAT signal
|
||||
void SetDAT(BYTE dat) override;
|
||||
// Set DAT signal
|
||||
protected:
|
||||
// TODO: Restore these back to protected
|
||||
// protected:
|
||||
// SCSI I/O signal control
|
||||
void MakeTable() override;
|
||||
// Create work data
|
||||
|
@ -55,8 +56,7 @@ class GPIOBUS_Allwinner : public GPIOBUS
|
|||
// Set Control Signal
|
||||
void SetMode(board_type::pi_physical_pin_e pin, board_type::gpio_direction_e mode) override;
|
||||
// Set SCSI I/O mode
|
||||
bool GetSignal(board_type::pi_physical_pin_e pin);
|
||||
bool GetSignal(board_type::pi_physical_pin_e pin) const override {(void)pin;return true;}
|
||||
bool GetSignal(board_type::pi_physical_pin_e pin) const override;
|
||||
|
||||
// Get SCSI input signal value
|
||||
void SetSignal(board_type::pi_physical_pin_e pin, board_type::gpio_high_low_e ast) override;
|
||||
|
@ -123,7 +123,7 @@ int bpi_piGpioLayout (void);
|
|||
|
||||
array<uint32_t, 4> gpfsel; // GPFSEL0-4 backup values
|
||||
|
||||
uint32_t signals = 0; // All bus signals
|
||||
array<uint32_t, 12> signals = {0}; // All bus signals
|
||||
|
||||
#ifdef USE_SEL_EVENT_ENABLE
|
||||
struct gpioevent_request selevreq = {}; // SEL signal event request
|
||||
|
@ -153,7 +153,7 @@ void sunxi_writel(volatile uint32_t *addr, uint32_t val);
|
|||
int sunxi_gpio_function(int gpio);
|
||||
|
||||
void sunxi_output_gpio(int gpio, int value);
|
||||
int sunxi_input_gpio(int gpio);
|
||||
int sunxi_input_gpio(int gpio) const;
|
||||
|
||||
int bpi_found = -1;
|
||||
|
||||
|
@ -204,7 +204,7 @@ typedef struct sunxi_gpio_reg {
|
|||
volatile uint32_t *r_gpio_map;
|
||||
|
||||
uint8_t* gpio_mmap_reg;
|
||||
|
||||
uint32_t sunxi_capture_all_gpio();
|
||||
void set_pullupdn(int gpio, int pud);
|
||||
|
||||
// These definitions are from c_gpio.c and should be removed at some point!!
|
||||
|
|
|
@ -50,7 +50,8 @@ class GPIOBUS_Raspberry final : public GPIOBUS
|
|||
// Get DAT signal
|
||||
void SetDAT(BYTE dat) override;
|
||||
// Set DAT signal
|
||||
private:
|
||||
// TODO: Restore this back to private
|
||||
// private:
|
||||
// SCSI I/O signal control
|
||||
void MakeTable() override;
|
||||
// Create work data
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "rascsi_version.h"
|
||||
#include "rasutil.h"
|
||||
#include "list_devices.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "hal/gpiobus_factory.h"
|
||||
#include "hal/sbc_version.h"
|
||||
#include "hal/systimer.h"
|
||||
#include "list_devices.h"
|
||||
#include "rascsi_version.h"
|
||||
#include "rascsi_exceptions.h"
|
||||
#include "protobuf_serializer.h"
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "list_devices.h"
|
||||
#include "rascsi_interface.pb.h"
|
||||
#include "rasutil.h"
|
||||
#include "rasctl_display.h"
|
||||
|
|
|
@ -0,0 +1,965 @@
|
|||
|
||||
// Kernel module to access cycle count registers:
|
||||
// https://matthewarcus.wordpress.com/2018/01/27/using-the-cycle-counter-registers-on-the-raspberry-pi-3/
|
||||
|
||||
// https://mindplusplus.wordpress.com/2013/05/21/accessing-the-raspberry-pis-1mhz-timer/
|
||||
|
||||
// Reading register from user space:
|
||||
// https://stackoverflow.com/questions/59749160/reading-from-register-of-allwinner-h3-arm-processor
|
||||
|
||||
// Maybe kernel patch>
|
||||
// https://yhbt.net/lore/all/20140707085858.GG16262@lukather/T/
|
||||
|
||||
//
|
||||
// Access the Raspberry Pi System Timer registers directly.
|
||||
//
|
||||
#include "hal/sbc_version.h"
|
||||
#include "hal/systimer.h"
|
||||
#include "rascsi_version.h"
|
||||
#include "rasutil.h"
|
||||
#include <fcntl.h>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <sched.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
// #include "common.h"
|
||||
#include "log.h"
|
||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
#include "hal/gpiobus.h"
|
||||
#include "hal/gpiobus_factory.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace spdlog;
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
static const int DEFAULT_PORT = 6868;
|
||||
static const char COMPONENT_SEPARATOR = ':';
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Variable declarations
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
static volatile bool active; // Processing flag
|
||||
// RascsiService service;
|
||||
shared_ptr<GPIOBUS> bus;
|
||||
string current_log_level = "debug"; // Some versions of spdlog do not support get_log_level()
|
||||
string access_token;
|
||||
// DeviceFactory device_factory;
|
||||
// shared_ptr<ControllerManager> controller_manager;
|
||||
// RascsiImage rascsi_image;
|
||||
// shared_ptr<RascsiResponse> rascsi_response;
|
||||
// shared_ptr<RascsiExecutor> executor;
|
||||
// const ProtobufSerializer serializer;
|
||||
|
||||
string connection_type = "hard-coded fullspec";
|
||||
|
||||
void Banner(int argc, char *argv[])
|
||||
{
|
||||
cout << ras_util::Banner("Reloaded");
|
||||
cout << "Connect type: " << connection_type << '\n' << flush;
|
||||
|
||||
if ((argc > 1 && strcmp(argv[1], "-h") == 0) || (argc > 1 && strcmp(argv[1], "--help") == 0)) {
|
||||
cout << "\nUsage: " << argv[0] << " [-idn[:m] FILE] ...\n\n";
|
||||
cout << " n is SCSI device ID (0-7).\n";
|
||||
cout << " m is the optional logical unit (LUN) (0-31).\n";
|
||||
cout << " FILE is a disk image file, \"daynaport\", \"bridge\", \"printer\" or \"services\".\n\n";
|
||||
cout << " Image type is detected based on file extension if no explicit type is specified.\n";
|
||||
cout << " hd1 : SCSI-1 HD image (Non-removable generic SCSI-1 HD image)\n";
|
||||
cout << " hds : SCSI HD image (Non-removable generic SCSI HD image)\n";
|
||||
cout << " hdr : SCSI HD image (Removable generic HD image)\n";
|
||||
cout << " hda : SCSI HD image (Apple compatible image)\n";
|
||||
cout << " hdn : SCSI HD image (NEC compatible image)\n";
|
||||
cout << " hdi : SCSI HD image (Anex86 HD image)\n";
|
||||
cout << " nhd : SCSI HD image (T98Next HD image)\n";
|
||||
cout << " mos : SCSI MO image (MO image)\n";
|
||||
cout << " iso : SCSI CD image (ISO 9660 image)\n" << flush;
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
bool InitBus()
|
||||
{
|
||||
#ifdef USE_SEL_EVENT_ENABLE
|
||||
SBC_Version::Init();
|
||||
#endif
|
||||
|
||||
// GPIOBUS creation
|
||||
bus = GPIOBUS_Factory::Create();
|
||||
|
||||
// controller_manager = make_shared<ControllerManager>(bus);
|
||||
// rascsi_response = make_shared<RascsiResponse>(device_factory, *controller_manager, ScsiController::LUN_MAX);
|
||||
// executor = make_shared<RascsiExecutor>(*rascsi_response, rascsi_image, device_factory, *controller_manager);
|
||||
|
||||
// GPIO Initialization
|
||||
if (!bus->Init(BUS::mode_e::TARGET, board_type::rascsi_board_type_e::BOARD_TYPE_FULLSPEC)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bus->Reset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Cleanup()
|
||||
{
|
||||
// executor->DetachAll();
|
||||
|
||||
// service.Cleanup();
|
||||
|
||||
bus->Cleanup();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
// controller_manager->ResetAllControllers();
|
||||
|
||||
bus->Reset();
|
||||
}
|
||||
|
||||
// bool InitBus()
|
||||
// {
|
||||
// LOGTRACE("%s", __PRETTY_FUNCTION__);
|
||||
// SBC_Version::Init();
|
||||
|
||||
// return true;
|
||||
// }
|
||||
|
||||
void test_timer();
|
||||
void test_gpio();
|
||||
void run_loopback_test();
|
||||
void set_dtd_out();
|
||||
void set_dtd_in();
|
||||
void set_ind_out();
|
||||
void set_ind_in();
|
||||
void set_tad_out();
|
||||
void set_tad_in();
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Pin the thread to a specific CPU
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void FixCpu(int cpu)
|
||||
{
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__);
|
||||
// Get the number of CPUs
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
sched_getaffinity(0, sizeof(cpu_set_t), &cpuset);
|
||||
int cpus = CPU_COUNT(&cpuset);
|
||||
|
||||
// Set the thread affinity
|
||||
if (cpu < cpus) {
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(cpu, &cpuset);
|
||||
sched_setaffinity(0, sizeof(cpu_set_t), &cpuset);
|
||||
}
|
||||
}
|
||||
|
||||
bool SetLogLevel(const string &log_level)
|
||||
{
|
||||
cout << "log level " << endl;
|
||||
if (log_level == "trace") {
|
||||
set_level(level::trace);
|
||||
} else if (log_level == "debug") {
|
||||
set_level(level::debug);
|
||||
} else if (log_level == "info") {
|
||||
set_level(level::info);
|
||||
} else if (log_level == "warn") {
|
||||
set_level(level::warn);
|
||||
} else if (log_level == "err") {
|
||||
set_level(level::err);
|
||||
} else if (log_level == "critical") {
|
||||
set_level(level::critical);
|
||||
} else if (log_level == "off") {
|
||||
set_level(level::off);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
current_log_level = log_level;
|
||||
|
||||
LOGINFO("Set log level to '%s'", current_log_level.c_str())
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TerminationHandler(int signum)
|
||||
{
|
||||
// Cleanup();
|
||||
|
||||
exit(signum);
|
||||
}
|
||||
|
||||
#include "wiringPi.h"
|
||||
|
||||
void blink()
|
||||
{
|
||||
printf("Simple Blink\n");
|
||||
// wiringPiSetup();
|
||||
// for(int i=0; i<20; i++){
|
||||
// pinMode(i,OUTPUT);
|
||||
// }
|
||||
|
||||
// for(int i=0; i<20; i++){
|
||||
// for(int pin=0; pin<20; pin++){
|
||||
// printf("Setting pin %d high\n", pin);
|
||||
// digitalWrite(pin, HIGH);
|
||||
// delay(100);
|
||||
// }
|
||||
// for(int pin=0; pin<20; pin++){
|
||||
// printf("Setting pin %d low\n", pin);
|
||||
// digitalWrite(pin, LOW);
|
||||
// delay(100);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
bool ParseArgument(int argc, char *argv[])
|
||||
{
|
||||
// PbCommand command;
|
||||
// int id = -1;
|
||||
// int unit = -1;
|
||||
// PbDeviceType type = UNDEFINED;
|
||||
// int block_size = 0;
|
||||
string name;
|
||||
string log_level;
|
||||
|
||||
const char *locale = setlocale(LC_MESSAGES, "");
|
||||
if (locale == nullptr || !strcmp(locale, "C")) {
|
||||
locale = "en";
|
||||
}
|
||||
|
||||
opterr = 1;
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "-Iib:d:n:p:r:t:z:D:F:L:P:R:")) != -1) {
|
||||
switch (opt) {
|
||||
// // The two options below are kind of a compound option with two letters
|
||||
// case 'i':
|
||||
// case 'I':
|
||||
// id = -1;
|
||||
// unit = -1;
|
||||
// continue;
|
||||
|
||||
// case 'd':
|
||||
// case 'D': {
|
||||
// if (!ProcessId(optarg, id, unit)) {
|
||||
// return false;
|
||||
// }
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// case 'b': {
|
||||
// if (!GetAsInt(optarg, block_size)) {
|
||||
// cerr << "Invalid block size " << optarg << endl;
|
||||
// return false;
|
||||
// }
|
||||
// continue;
|
||||
// }
|
||||
|
||||
case 'z':
|
||||
locale = optarg;
|
||||
continue;
|
||||
|
||||
// case 'F': {
|
||||
// if (const string result = rascsi_image.SetDefaultFolder(optarg); !result.empty()) {
|
||||
// cerr << result << endl;
|
||||
// return false;
|
||||
// }
|
||||
// continue;
|
||||
// }
|
||||
|
||||
case 'L':
|
||||
log_level = optarg;
|
||||
continue;
|
||||
|
||||
// case 'R':
|
||||
// int depth;
|
||||
// if (!GetAsInt(optarg, depth) || depth < 0) {
|
||||
// cerr << "Invalid image file scan depth " << optarg << endl;
|
||||
// return false;
|
||||
// }
|
||||
// rascsi_image.SetDepth(depth);
|
||||
// continue;
|
||||
|
||||
case 'n':
|
||||
name = optarg;
|
||||
continue;
|
||||
|
||||
// case 'p':
|
||||
// if (!GetAsInt(optarg, port) || port <= 0 || port > 65535) {
|
||||
// cerr << "Invalid port " << optarg << ", port must be between 1 and 65535" << endl;
|
||||
// return false;
|
||||
// }
|
||||
// continue;
|
||||
|
||||
// case 'P':
|
||||
// if (!ReadAccessToken(optarg)) {
|
||||
// return false;
|
||||
// }
|
||||
// continue;
|
||||
|
||||
// case 'r': {
|
||||
// string error = executor->SetReservedIds(optarg);
|
||||
// if (!error.empty()) {
|
||||
// cerr << error << endl;
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// continue;
|
||||
|
||||
// case 't': {
|
||||
// string t = optarg;
|
||||
// transform(t.begin(), t.end(), t.begin(), ::toupper);
|
||||
// if (!PbDeviceType_Parse(t, &type)) {
|
||||
// cerr << "Illegal device type '" << optarg << "'" << endl;
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// continue;
|
||||
|
||||
case 1:
|
||||
// Encountered filename
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (optopt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// // Set up the device data
|
||||
// PbDeviceDefinition *device = command.add_devices();
|
||||
// device->set_id(id);
|
||||
// device->set_unit(unit);
|
||||
// device->set_type(type);
|
||||
// device->set_block_size(block_size);
|
||||
|
||||
// ParseParameters(*device, optarg);
|
||||
|
||||
// if (size_t separator_pos = name.find(COMPONENT_SEPARATOR); separator_pos != string::npos) {
|
||||
// device->set_vendor(name.substr(0, separator_pos));
|
||||
// name = name.substr(separator_pos + 1);
|
||||
// separator_pos = name.find(COMPONENT_SEPARATOR);
|
||||
// if (separator_pos != string::npos) {
|
||||
// device->set_product(name.substr(0, separator_pos));
|
||||
// device->set_revision(name.substr(separator_pos + 1));
|
||||
// }
|
||||
// else {
|
||||
// device->set_product(name);
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// device->set_vendor(name);
|
||||
// }
|
||||
|
||||
// id = -1;
|
||||
// type = UNDEFINED;
|
||||
// block_size = 0;
|
||||
// name = "";
|
||||
}
|
||||
|
||||
if (!log_level.empty()) {
|
||||
SetLogLevel(log_level);
|
||||
}
|
||||
|
||||
// // Attach all specified devices
|
||||
// command.set_operation(ATTACH);
|
||||
|
||||
// if (CommandContext context(locale); !executor->ProcessCmd(context, command)) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// // Display and log the device list
|
||||
// PbServerInfo server_info;
|
||||
// rascsi_response->GetDevices(server_info, rascsi_image.GetDefaultFolder());
|
||||
// const list<PbDevice>& devices = { server_info.devices_info().devices().begin(),
|
||||
// server_info.devices_info().devices().end() }; const string device_list = ListDevices(devices);
|
||||
// LogDevices(device_list);
|
||||
// cout << device_list << flush;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void tony_test();
|
||||
void print_all();
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// added setvbuf to override stdout buffering, so logs are written immediately and not when the process exits.
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
// Output the Banner
|
||||
Banner(argc, argv);
|
||||
|
||||
// ParseArgument() requires the bus to have been initialized first, which requires the root user.
|
||||
// The -v option should be available for any user, which requires special handling.
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (!strcasecmp(argv[i], "-v")) {
|
||||
cout << rascsi_get_version_string() << endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// executor->SetLogLevel(current_log_level);
|
||||
|
||||
// Create a thread-safe stdout logger to process the log messages
|
||||
const auto logger = stdout_color_mt("rascsi stdout logger");
|
||||
set_level(level::trace);
|
||||
|
||||
if (!InitBus()) {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
if (!ParseArgument(argc, argv)) {
|
||||
Cleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Signal handler to detach all devices on a KILL or TERM signal
|
||||
struct sigaction termination_handler;
|
||||
termination_handler.sa_handler = TerminationHandler;
|
||||
sigemptyset(&termination_handler.sa_mask);
|
||||
termination_handler.sa_flags = 0;
|
||||
sigaction(SIGINT, &termination_handler, nullptr);
|
||||
sigaction(SIGTERM, &termination_handler, nullptr);
|
||||
|
||||
// Reset
|
||||
Reset();
|
||||
|
||||
// Set the affinity to a specific processor core
|
||||
FixCpu(3);
|
||||
|
||||
#ifdef USE_SEL_EVENT_ENABLE
|
||||
sched_param schparam;
|
||||
// Scheduling policy setting (highest priority)
|
||||
schparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
|
||||
sched_setscheduler(0, SCHED_FIFO, &schparam);
|
||||
#else
|
||||
cout << "Note: No RaSCSI hardware support, only client interface calls are supported" << endl;
|
||||
#endif
|
||||
|
||||
LOGWARN("THIS WILL DO SOMETHING SOMEDAY");
|
||||
|
||||
LOGDEBUG("DTD OUT %d = %d", (int)bus->board->pin_dtd, (int)bus->board->DtdOut());
|
||||
LOGDEBUG("DTD IN %d = %d", (int)bus->board->pin_dtd, (int)bus->board->DtdIn());
|
||||
LOGDEBUG("IND OUT %d = %d", (int)bus->board->pin_ind, (int)bus->board->IndOut());
|
||||
LOGDEBUG("IND IN %d = %d", (int)bus->board->pin_ind, (int)bus->board->IndIn());
|
||||
LOGDEBUG("TAD OUT %d = %d", (int)bus->board->pin_tad, (int)bus->board->TadOut());
|
||||
LOGDEBUG("TAD IN %d = %d", (int)bus->board->pin_tad, (int)bus->board->TadIn());
|
||||
|
||||
bus->PullConfig(bus->board->pin_dtd, board_type::gpio_pull_up_down_e::GPIO_PULLUP);
|
||||
bus->PullConfig(bus->board->pin_ind, board_type::gpio_pull_up_down_e::GPIO_PULLUP);
|
||||
bus->PullConfig(bus->board->pin_tad, board_type::gpio_pull_up_down_e::GPIO_PULLUP);
|
||||
|
||||
bus->PinConfig(bus->board->pin_dtd, board_type::gpio_direction_e::GPIO_OUTPUT);
|
||||
bus->PinConfig(bus->board->pin_ind, board_type::gpio_direction_e::GPIO_OUTPUT);
|
||||
bus->PinConfig(bus->board->pin_tad, board_type::gpio_direction_e::GPIO_OUTPUT);
|
||||
bus->PinConfig(bus->board->pin_ack, board_type::gpio_direction_e::GPIO_OUTPUT);
|
||||
|
||||
int delay_time = 10000;
|
||||
(void)delay_time;
|
||||
|
||||
set_tad_out();
|
||||
set_dtd_out();
|
||||
set_ind_out();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// for (int i = 0; i < 10; i++) {
|
||||
// bus->SetACK(true);
|
||||
// usleep(delay_time);
|
||||
// bus->SetACK(false);
|
||||
// usleep(delay_time);
|
||||
// }
|
||||
|
||||
run_loopback_test();
|
||||
return 0;
|
||||
|
||||
tony_test();
|
||||
|
||||
LOGDEBUG("bus->Acquire(): %08X", bus->Acquire());
|
||||
SysTimer::SleepUsec(1000);
|
||||
|
||||
LOGDEBUG("IO True");
|
||||
bus->SetIO(true);
|
||||
SysTimer::SleepUsec(1000);
|
||||
LOGDEBUG("bus->Acquire(): %08X", bus->Acquire());
|
||||
|
||||
LOGDEBUG("IO False");
|
||||
bus->SetIO(false);
|
||||
SysTimer::SleepUsec(1000);
|
||||
LOGDEBUG("bus->Acquire(): %08X", bus->Acquire());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// //---------------------------------------------------------------------------
|
||||
// //
|
||||
// // Main processing
|
||||
// //
|
||||
// //---------------------------------------------------------------------------
|
||||
// int main(int argc, char* argv[])
|
||||
// {
|
||||
|
||||
// // added setvbuf to override stdout buffering, so logs are written immediately and not when the process exits.
|
||||
// setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
// if(argc > 1){
|
||||
// SetLogLevel(argv[1]);
|
||||
// }else{
|
||||
// SetLogLevel("trace");
|
||||
// }
|
||||
|
||||
// // Create a thread-safe stdout logger to process the log messages
|
||||
// auto logger = spdlog::stdout_color_mt("rascsi stdout logger");
|
||||
|
||||
// // Signal handler to detach all devices on a KILL or TERM signal
|
||||
// struct sigaction termination_handler;
|
||||
// termination_handler.sa_handler = TerminationHandler;
|
||||
// sigemptyset(&termination_handler.sa_mask);
|
||||
// termination_handler.sa_flags = 0;
|
||||
// sigaction(SIGINT, &termination_handler, nullptr);
|
||||
// sigaction(SIGTERM, &termination_handler, nullptr);
|
||||
|
||||
// if (!InitBus()) {
|
||||
// return EPERM;
|
||||
// }
|
||||
|
||||
// // blink();
|
||||
// // test_timer();
|
||||
// test_gpio();
|
||||
|
||||
// }
|
||||
|
||||
void test_timer()
|
||||
{
|
||||
uint32_t before = SysTimer::GetTimerLow();
|
||||
sleep(1);
|
||||
uint32_t after = SysTimer::GetTimerLow();
|
||||
|
||||
LOGINFO("first sample: %d %08X", (before - after), (after - before));
|
||||
|
||||
uint64_t sum = 0;
|
||||
int count = 0;
|
||||
for (int i = 0; i < 100; i++) {
|
||||
before = SysTimer::GetTimerLow();
|
||||
usleep(1000);
|
||||
after = SysTimer::GetTimerLow();
|
||||
sum += (after - before);
|
||||
count++;
|
||||
}
|
||||
|
||||
LOGINFO("usleep() Average %d", (uint32_t)(sum / count));
|
||||
|
||||
sum = 0;
|
||||
count = 0;
|
||||
for (int i = 0; i < 100; i++) {
|
||||
before = SysTimer::GetTimerLow();
|
||||
SysTimer::SleepUsec(1000);
|
||||
after = SysTimer::GetTimerLow();
|
||||
sum += (after - before);
|
||||
count++;
|
||||
}
|
||||
LOGINFO("usleep() Average %d", (uint32_t)(sum / count));
|
||||
|
||||
before = SysTimer::GetTimerLow();
|
||||
SysTimer::SleepNsec(1000000);
|
||||
after = SysTimer::GetTimerLow();
|
||||
LOGINFO("SysTimer::SleepNSec: %d (expected ~1000)", (uint32_t)(after - before));
|
||||
}
|
||||
|
||||
void tony_test()
|
||||
{
|
||||
LOGWARN("Set everything to HIGH OUTPUT with PULLUP");
|
||||
|
||||
for (auto phys_pin : bus->SignalTable) {
|
||||
LOGTRACE("%s GPIO_PULLUP", __PRETTY_FUNCTION__);
|
||||
|
||||
bus->PullConfig(phys_pin, board_type::gpio_pull_up_down_e::GPIO_PULLUP);
|
||||
bus->PinConfig(phys_pin, board_type::gpio_direction_e::GPIO_OUTPUT);
|
||||
bus->PinSetSignal(phys_pin, board_type::gpio_high_low_e::GPIO_STATE_HIGH);
|
||||
SysTimer::SleepUsec(10000);
|
||||
}
|
||||
// SysTimer::SleepUsec(1000);
|
||||
usleep(1000000);
|
||||
|
||||
LOGWARN("Set everything to LOW OUTPUT with PULLUP");
|
||||
|
||||
for (auto phys_pin : bus->SignalTable) {
|
||||
LOGTRACE("%s GPIO_PULLUP", __PRETTY_FUNCTION__);
|
||||
|
||||
bus->PullConfig(phys_pin, board_type::gpio_pull_up_down_e::GPIO_PULLUP);
|
||||
bus->PinConfig(phys_pin, board_type::gpio_direction_e::GPIO_OUTPUT);
|
||||
bus->PinSetSignal(phys_pin, board_type::gpio_high_low_e::GPIO_STATE_LOW);
|
||||
SysTimer::SleepUsec(10000);
|
||||
}
|
||||
usleep(1000000);
|
||||
|
||||
LOGWARN("Set everything to INPUT");
|
||||
|
||||
for (auto phys_pin : bus->SignalTable) {
|
||||
LOGTRACE("%s GPIO_PULLUP", __PRETTY_FUNCTION__);
|
||||
|
||||
bus->PullConfig(phys_pin, board_type::gpio_pull_up_down_e::GPIO_PULLUP);
|
||||
bus->PinConfig(phys_pin, board_type::gpio_direction_e::GPIO_INPUT);
|
||||
bus->PinSetSignal(phys_pin, board_type::gpio_high_low_e::GPIO_STATE_LOW);
|
||||
SysTimer::SleepUsec(10000);
|
||||
}
|
||||
usleep(1000000);
|
||||
}
|
||||
|
||||
struct loopback_connections_struct {
|
||||
board_type::pi_physical_pin_e this_pin;
|
||||
board_type::pi_physical_pin_e connected_pin;
|
||||
board_type::pi_physical_pin_e dir_ctrl_pin;
|
||||
};
|
||||
typedef loopback_connections_struct loopback_connection;
|
||||
|
||||
std::map<board_type::pi_physical_pin_e, string> pin_name_lookup;
|
||||
std::vector<loopback_connection> loopback_conn_table;
|
||||
|
||||
// This needs to run AFTER GPIOBUS has been initialized. Otherwise, we don't know what type of board
|
||||
// we're using
|
||||
void init_loopback()
|
||||
{
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__);
|
||||
|
||||
shared_ptr<board_type::Rascsi_Board_Type> board_table = bus->board;
|
||||
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_dt0, .connected_pin = board_table->pin_ack, .dir_ctrl_pin = board_table->pin_dtd});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_dt1, .connected_pin = board_table->pin_sel, .dir_ctrl_pin = board_table->pin_dtd});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_dt2, .connected_pin = board_table->pin_atn, .dir_ctrl_pin = board_table->pin_dtd});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_dt3, .connected_pin = board_table->pin_rst, .dir_ctrl_pin = board_table->pin_dtd});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_dt4, .connected_pin = board_table->pin_cd, .dir_ctrl_pin = board_table->pin_dtd});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_dt5, .connected_pin = board_table->pin_io, .dir_ctrl_pin = board_table->pin_dtd});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_dt6, .connected_pin = board_table->pin_msg, .dir_ctrl_pin = board_table->pin_dtd});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_dt7, .connected_pin = board_table->pin_req, .dir_ctrl_pin = board_table->pin_dtd});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_dp, .connected_pin = board_table->pin_bsy, .dir_ctrl_pin = board_table->pin_dtd});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_atn, .connected_pin = board_table->pin_dt2, .dir_ctrl_pin = board_table->pin_ind});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_rst, .connected_pin = board_table->pin_dt3, .dir_ctrl_pin = board_table->pin_ind});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_ack, .connected_pin = board_table->pin_dt0, .dir_ctrl_pin = board_table->pin_ind});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_req, .connected_pin = board_table->pin_dt7, .dir_ctrl_pin = board_table->pin_tad});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_msg, .connected_pin = board_table->pin_dt6, .dir_ctrl_pin = board_table->pin_tad});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_cd, .connected_pin = board_table->pin_dt4, .dir_ctrl_pin = board_table->pin_tad});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_io, .connected_pin = board_table->pin_dt5, .dir_ctrl_pin = board_table->pin_tad});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_bsy, .connected_pin = board_table->pin_dp, .dir_ctrl_pin = board_table->pin_tad});
|
||||
loopback_conn_table.push_back(loopback_connection{
|
||||
.this_pin = board_table->pin_sel, .connected_pin = board_table->pin_dt1, .dir_ctrl_pin = board_table->pin_ind});
|
||||
|
||||
pin_name_lookup[board_table->pin_dt0] = " d0";
|
||||
pin_name_lookup[board_table->pin_dt1] = " d1";
|
||||
pin_name_lookup[board_table->pin_dt2] = " d2";
|
||||
pin_name_lookup[board_table->pin_dt3] = " d3";
|
||||
pin_name_lookup[board_table->pin_dt4] = " d4";
|
||||
pin_name_lookup[board_table->pin_dt5] = " d5";
|
||||
pin_name_lookup[board_table->pin_dt6] = " d6";
|
||||
pin_name_lookup[board_table->pin_dt7] = " d7";
|
||||
pin_name_lookup[board_table->pin_dp] = " dp";
|
||||
pin_name_lookup[board_table->pin_atn] = "atn";
|
||||
pin_name_lookup[board_table->pin_rst] = "rst";
|
||||
pin_name_lookup[board_table->pin_ack] = "ack";
|
||||
pin_name_lookup[board_table->pin_req] = "req";
|
||||
pin_name_lookup[board_table->pin_msg] = "msg";
|
||||
pin_name_lookup[board_table->pin_cd] = " cd";
|
||||
pin_name_lookup[board_table->pin_io] = " io";
|
||||
pin_name_lookup[board_table->pin_bsy] = "bsy";
|
||||
pin_name_lookup[board_table->pin_sel] = "sel";
|
||||
pin_name_lookup[board_table->pin_ind] = "ind";
|
||||
pin_name_lookup[board_table->pin_tad] = "tad";
|
||||
pin_name_lookup[board_table->pin_dtd] = "dtd";
|
||||
pin_name_lookup[board_type::pi_physical_pin_e::PI_PHYS_PIN_NONE] = "NONE";
|
||||
}
|
||||
|
||||
// Debug function that just dumps the status of all of the scsi signals to the console
|
||||
void print_all()
|
||||
{
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (auto cur_gpio : loopback_conn_table) {
|
||||
LOGDEBUG("%s %2d = %s %2d", pin_name_lookup.at(cur_gpio.this_pin).c_str(), (int)cur_gpio.this_pin,
|
||||
pin_name_lookup.at(cur_gpio.connected_pin).c_str(), (int)cur_gpio.connected_pin)
|
||||
}
|
||||
}
|
||||
|
||||
// Set transceivers IC1 and IC2 to OUTPUT
|
||||
void set_dtd_out()
|
||||
{
|
||||
LOGDEBUG("DTD OUT %d = %d", (int)bus->board->pin_dtd, (int)bus->board->DtdOut());
|
||||
bus->PinSetSignal(bus->board->pin_dtd, bus->board->DtdOut());
|
||||
// gpio.output(rascsi_dtd_gpio,gpio.LOW)
|
||||
}
|
||||
|
||||
// Set transceivers IC1 and IC2 to INPUT
|
||||
void set_dtd_in()
|
||||
{
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__);
|
||||
LOGDEBUG("DTD IN %d = %d", (int)bus->board->pin_dtd, (int)bus->board->DtdIn());
|
||||
bus->PinSetSignal(bus->board->pin_dtd, bus->board->DtdIn());
|
||||
// gpio.output(rascsi_dtd_gpio,gpio.HIGH)
|
||||
}
|
||||
// Set transceiver IC4 to OUTPUT
|
||||
void set_ind_out()
|
||||
{
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__);
|
||||
LOGDEBUG("IND OUT %d = %d", (int)bus->board->pin_ind, (int)bus->board->IndOut());
|
||||
bus->PinSetSignal(bus->board->pin_ind, bus->board->IndOut());
|
||||
// gpio.output(rascsi_ind_gpio,gpio.HIGH)
|
||||
}
|
||||
// Set transceiver IC4 to INPUT
|
||||
void set_ind_in()
|
||||
{
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__);
|
||||
LOGDEBUG("IND IN %d = %d", (int)bus->board->pin_ind, (int)bus->board->IndIn());
|
||||
bus->PinSetSignal(bus->board->pin_ind, bus->board->IndIn());
|
||||
// gpio.output(rascsi_ind_gpio,gpio.LOW)
|
||||
}
|
||||
// Set transceiver IC3 to OUTPUT
|
||||
void set_tad_out()
|
||||
{
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__);
|
||||
LOGDEBUG("TAD OUT %d = %d", (int)bus->board->pin_tad, (int)bus->board->TadOut());
|
||||
bus->PinSetSignal(bus->board->pin_tad, bus->board->TadOut());
|
||||
// gpio.output(rascsi_tad_gpio,gpio.HIGH)
|
||||
}
|
||||
// Set transceiver IC3 to INPUT
|
||||
void set_tad_in()
|
||||
{
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__);
|
||||
LOGDEBUG("TAD IN %d = %d", (int)bus->board->pin_tad, (int)bus->board->TadIn());
|
||||
bus->PinSetSignal(bus->board->pin_tad, bus->board->TadIn());
|
||||
// gpio.output(rascsi_tad_gpio,gpio.LOW)
|
||||
}
|
||||
|
||||
// Set the specified transciever to an OUTPUT. All of the other transceivers
|
||||
// will be set to inputs. If a non-existent direction gpio is specified, this
|
||||
// will set all of the transceivers to inputs.
|
||||
void set_output_channel(board_type::pi_physical_pin_e out_gpio)
|
||||
{
|
||||
LOGTRACE("%s tad: %d dtd: %d ind: %d", bus->board->connect_desc.c_str(), (int)bus->board->pin_tad,
|
||||
(int)bus->board->pin_dtd, (int)bus->board->pin_ind);
|
||||
if (out_gpio == bus->board->pin_tad)
|
||||
set_tad_out();
|
||||
else
|
||||
set_tad_in();
|
||||
if (out_gpio == bus->board->pin_dtd)
|
||||
set_dtd_out();
|
||||
else
|
||||
set_dtd_in();
|
||||
if (out_gpio == bus->board->pin_ind)
|
||||
set_ind_out();
|
||||
else
|
||||
set_ind_in();
|
||||
}
|
||||
|
||||
// Initialize the GPIO library, set all of the gpios associated with SCSI signals to outputs and set
|
||||
// all of the direction control gpios to outputs
|
||||
void loopback_setup()
|
||||
{
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__);
|
||||
|
||||
// gpio.setmode(gpio.BOARD)
|
||||
// gpio.setwarnings(False)
|
||||
for (loopback_connection cur_gpio : loopback_conn_table) {
|
||||
if (cur_gpio.this_pin == board_type::pi_physical_pin_e::PI_PHYS_PIN_NONE) {
|
||||
continue;
|
||||
}
|
||||
bus->PinConfig(cur_gpio.this_pin, board_type::gpio_direction_e::GPIO_OUTPUT);
|
||||
bus->PullConfig(cur_gpio.this_pin, board_type::gpio_pull_up_down_e::GPIO_PULLNONE);
|
||||
// gpio.setup(cur_gpio['gpio_num'], gpio.OUT, initial=gpio.HIGH)
|
||||
}
|
||||
// Setup direction control
|
||||
// gpio.setup(rascsi_ind_gpio, gpio.OUT) gpio.setup(rascsi_tad_gpio, gpio.OUT) gpio.setup(rascsi_dtd_gpio, gpio.OUT)
|
||||
|
||||
if (bus->board->pin_ind != board_type::pi_physical_pin_e::PI_PHYS_PIN_NONE) {
|
||||
bus->PinConfig(bus->board->pin_ind, board_type::gpio_direction_e::GPIO_OUTPUT);
|
||||
}
|
||||
if (bus->board->pin_tad != board_type::pi_physical_pin_e::PI_PHYS_PIN_NONE) {
|
||||
bus->PinConfig(bus->board->pin_tad, board_type::gpio_direction_e::GPIO_OUTPUT);
|
||||
}
|
||||
if (bus->board->pin_dtd != board_type::pi_physical_pin_e::PI_PHYS_PIN_NONE) {
|
||||
bus->PinConfig(bus->board->pin_dtd, board_type::gpio_direction_e::GPIO_OUTPUT);
|
||||
}
|
||||
}
|
||||
|
||||
// Main test procedure.This will execute for each of the SCSI pins to make sure its connected
|
||||
// properly.
|
||||
int test_gpio_pin(loopback_connection &gpio_rec)
|
||||
{
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__);
|
||||
|
||||
(void)gpio_rec;
|
||||
int err_count = 0;
|
||||
int sleep_time = 1000000;
|
||||
|
||||
LOGDEBUG("dir ctrl pin: %d", (int)gpio_rec.dir_ctrl_pin);
|
||||
set_output_channel(gpio_rec.dir_ctrl_pin);
|
||||
usleep(sleep_time);
|
||||
|
||||
// Set all GPIOs high (initialize to a known state)
|
||||
for (auto cur_gpio : loopback_conn_table) {
|
||||
bus->PinSetSignal(cur_gpio.this_pin, board_type::gpio_high_low_e::GPIO_STATE_HIGH);
|
||||
}
|
||||
|
||||
usleep(sleep_time);
|
||||
bus->Acquire();
|
||||
|
||||
// ############################################
|
||||
// # set the test gpio low
|
||||
// gpio.output(gpio_rec['gpio_num'], gpio.LOW)
|
||||
LOGTRACE("PinSetSignal %d", (int)gpio_rec.this_pin);
|
||||
bus->PinSetSignal(gpio_rec.this_pin, board_type::gpio_high_low_e::GPIO_STATE_LOW);
|
||||
|
||||
// time.sleep(pin_settle_delay)
|
||||
LOGINFO("Sleep");
|
||||
usleep(sleep_time);
|
||||
LOGINFO("Done");
|
||||
|
||||
LOGTRACE("Acquire");
|
||||
bus->Acquire();
|
||||
// # loop through all of the gpios
|
||||
for (auto cur_gpio : loopback_conn_table) {
|
||||
// all of the gpios should be high except for the test gpio and the connected gpio
|
||||
LOGTRACE("calling bus->GetSignal(%d)", (int)cur_gpio.this_pin);
|
||||
auto cur_val = bus->GetSignal(cur_gpio.this_pin);
|
||||
LOGDEBUG("%d [%s] is %d", (int)cur_gpio.this_pin, pin_name_lookup.at(cur_gpio.this_pin).c_str(), (int)cur_val);
|
||||
|
||||
if (cur_gpio.this_pin == gpio_rec.this_pin) {
|
||||
if (cur_val != false) {
|
||||
LOGERROR("Test commanded GPIO %d [%s] to be low, but it did not respond", (int)cur_gpio.this_pin,
|
||||
pin_name_lookup.at(cur_gpio.this_pin).c_str())
|
||||
err_count++;
|
||||
}
|
||||
} else if (cur_gpio.this_pin == gpio_rec.connected_pin) {
|
||||
if (cur_val != false) {
|
||||
LOGERROR("GPIO %d [%s] should be driven low, but %d [%s] did not affect it", (int)cur_gpio.this_pin,
|
||||
pin_name_lookup.at(cur_gpio.this_pin).c_str(), (int)cur_gpio.connected_pin,
|
||||
pin_name_lookup.at(cur_gpio.connected_pin).c_str());
|
||||
|
||||
err_count++;
|
||||
}
|
||||
} else {
|
||||
if (cur_val != true) {
|
||||
LOGERROR("GPIO %d [%s] was incorrectly pulled low, when it shouldn't be", (int)cur_gpio.this_pin,
|
||||
pin_name_lookup.at(cur_gpio.this_pin).c_str())
|
||||
err_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
exit(1);
|
||||
|
||||
|
||||
// if(cur_val != gpio.HIGH):
|
||||
// print("Error: GPIO " + scsi_signals[gpio_rec['gpio_num']] + " incorrectly pulled " +
|
||||
// scsi_signals[cur_gpio] + " LOW, when it shouldn't have") err_count = err_count+1
|
||||
|
||||
// ############################################
|
||||
// # set the transceivers to input
|
||||
// set_output_channel(rascsi_none)
|
||||
|
||||
// time.sleep(pin_settle_delay)
|
||||
|
||||
// # loop through all of the gpios
|
||||
// for cur_gpio in scsi_signals:
|
||||
// # all of the gpios should be high except for the test gpio
|
||||
// cur_val = gpio.input(cur_gpio)
|
||||
// if( cur_gpio == gpio_rec['gpio_num']):
|
||||
// if(cur_val != gpio.LOW):
|
||||
// print("Error: Test commanded GPIO " + scsi_signals[gpio_rec['gpio_num']] + " to be
|
||||
// low, but it did not respond") err_count = err_count+1
|
||||
// else:
|
||||
// if(cur_val != gpio.HIGH):
|
||||
// print("Error: GPIO " + scsi_signals[gpio_rec['gpio_num']] + " incorrectly pulled " +
|
||||
// scsi_signals[cur_gpio] + " LOW, when it shouldn't have") err_count = err_count+1
|
||||
|
||||
// # Set the transceiver back to output
|
||||
// set_output_channel(gpio_rec['dir_ctrl'])
|
||||
|
||||
// #############################################
|
||||
// # set the test gpio high
|
||||
// gpio.output(gpio_rec['gpio_num'], gpio.HIGH)
|
||||
|
||||
// time.sleep(pin_settle_delay)
|
||||
|
||||
// # loop through all of the gpios
|
||||
// for cur_gpio in scsi_signals:
|
||||
// # all of the gpios should be high
|
||||
// cur_val = gpio.input(cur_gpio)
|
||||
// if( cur_gpio == gpio_rec['gpio_num']):
|
||||
// if(cur_val != gpio.HIGH):
|
||||
// print("Error: Test commanded GPIO " + scsi_signals[gpio_rec['gpio_num']] + " to be
|
||||
// high, but it did not respond") err_count = err_count+1
|
||||
// else:
|
||||
// if(cur_val != gpio.HIGH):
|
||||
// print("Error: GPIO " + scsi_signals[gpio_rec['gpio_num']] + " incorrectly pulled " +
|
||||
// scsi_signals[cur_gpio] + " LOW, when it shouldn't have") err_count = err_count+1
|
||||
return err_count;
|
||||
}
|
||||
|
||||
void run_loopback_test()
|
||||
{
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__);
|
||||
init_loopback();
|
||||
loopback_setup();
|
||||
LOGWARN("DONE WITH LOOPBACK_SETUP()");
|
||||
print_all();
|
||||
LOGWARN("---------------------------------------------------");
|
||||
|
||||
set_output_channel(bus->board->pin_dtd);
|
||||
for(int j = 0; j<5; j++){
|
||||
for(uint8_t i = 0; i< 0xFF; i++){
|
||||
bus->SetDAT(i);
|
||||
usleep(100000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
loopback_connection ack;
|
||||
ack.this_pin = bus->board->pin_ack;
|
||||
ack.connected_pin = bus->board->pin_dt0;
|
||||
ack.dir_ctrl_pin = bus->board->pin_ind;
|
||||
|
||||
test_gpio_pin(ack);
|
||||
|
||||
|
||||
for (auto cur_gpio : loopback_conn_table) {
|
||||
LOGINFO("Testing GPIO %d [%s]..................................", (int)cur_gpio.this_pin,
|
||||
pin_name_lookup.at(cur_gpio.this_pin).c_str());
|
||||
test_gpio_pin(cur_gpio);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue