diff --git a/src/raspberrypi/.gitignore b/src/raspberrypi/.gitignore index c5fb48ae..00676775 100644 --- a/src/raspberrypi/.gitignore +++ b/src/raspberrypi/.gitignore @@ -6,7 +6,9 @@ *.layout *.log rascsi -scsimon +scsishark rasctl sasidump rasdump +log.* + diff --git a/src/raspberrypi/Makefile b/src/raspberrypi/Makefile index 71c0f07c..6f6785bf 100644 --- a/src/raspberrypi/Makefile +++ b/src/raspberrypi/Makefile @@ -28,7 +28,7 @@ RASCSI = rascsi RASCTL = rasctl RASDUMP = rasdump SASIDUMP = sasidump -SCSIMON = scsimon +SCSISHARK = scsishark USR_LOCAL_BIN = /usr/local/bin MAN_PAGE_DIR = /usr/share/man/man1 @@ -37,7 +37,7 @@ DOC_DIR = ../../doc #BIN_ALL = $(RASCSI) $(RASCTL) $(RASDUMP) $(SASIDUMP) $(SCSIMON) # Temporarily remove the RASDUMP and RASDUMP tools, since they're not needed # for my specific use case. If you need them - add them back in! -BIN_ALL = $(RASCSI) $(RASCTL) +BIN_ALL = $(RASCSI) $(RASCTL) $(SCSISHARK) SRC_RASCSI = \ @@ -50,6 +50,16 @@ SRC_RASCSI = \ filepath.cpp \ fileio.cpp +SRC_SCSISHARK = \ + scsishark.cpp \ + scsi.cpp \ + disk.cpp \ + gpiobus.cpp \ + ctapdriver.cpp \ + cfilesystem.cpp \ + filepath.cpp \ + fileio.cpp + SRC_RASCTL = \ rasctl.cpp @@ -71,9 +81,9 @@ OBJ_RASCSI := $(SRC_RASCSI:%.cpp=%.o) OBJ_RASCTL := $(SRC_RASCTL:%.cpp=%.o) OBJ_RASDUMP := $(SRC_RASDUMP:%.cpp=%.o) OBJ_SASIDUMP := $(SRC_SASIDUMP:%.cpp=%.o) -OBJ_SCSIMON := $(SRC_SCSIMON:%.cpp=%.o) +OBJ_SCSISHARK := $(SRC_SCSISHARK:%.cpp=%.o) #OBJ_ALL := $(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_RASDUMP) $(OBJ_SASIDUMP) $(OBJ_SCSIMON) -OBJ_ALL := $(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_RASDUMP) $(OBJ_SASIDUMP) +OBJ_ALL := $(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_RASDUMP) $(OBJ_SASIDUMP) $(OBJ_SCSISHARK) %.o: %.cpp $(CXX) $(CXXFLAGS) -c $< -o $@ @@ -88,19 +98,19 @@ ALL: all docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt $(RASCSI): $(OBJ_RASCSI) - $(CXX) -o $@ $(OBJ_RASCSI) -lpthread + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI) -lpthread $(RASCTL): $(OBJ_RASCTL) - $(CXX) -o $@ $(OBJ_RASCTL) + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCTL) $(RASDUMP): $(OBJ_RASDUMP) - $(CXX) -o $@ $(OBJ_RASDUMP) + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASDUMP) $(SASIDUMP): $(OBJ_SASIDUMP) - $(CXX) -o $@ $(OBJ_SASIDUMP) + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_SASIDUMP) -$(SCSIMON): $(OBJ_SCSIMON) - $(CXX) $(CXXFLAGS) -o $@ $(OBJ_SCSIMON) -lpthread +$(SCSISHARK): $(OBJ_SCSISHARK) + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_SCSISHARK) -lpthread clean: rm -f $(OBJ_ALL) $(BIN_ALL) @@ -122,3 +132,5 @@ $(DOC_DIR)/%_man_page.txt : $(DOC_DIR)/%.1 .PHONY: Debug Debug: all +.PHONY: Debug-scsishark +Debug-scsishark: $(SCSISHARK) diff --git a/src/raspberrypi/disk.cpp b/src/raspberrypi/disk.cpp index d1b9467b..483487a0 100644 --- a/src/raspberrypi/disk.cpp +++ b/src/raspberrypi/disk.cpp @@ -43,7 +43,6 @@ // Disk // //=========================================================================== -//#define DISK_LOG #ifdef RASCSI #define BENDER_SIGNATURE "RaSCSI" @@ -6324,9 +6323,7 @@ BUS::phase_t FASTCALL SASIDEV::Process() // For the monitor tool, we shouldn't need to reset. We're just logging information // Reset if (ctrl.bus->GetRST()) { -#if defined(DISK_LOG) spdlog::info( "RESET signal received"); -#endif // DISK_LOG // Reset the controller Reset(); @@ -6394,9 +6391,7 @@ void FASTCALL SASIDEV::BusFree() // Phase change if (ctrl.phase != BUS::busfree) { -#if defined(DISK_LOG) spdlog::info( "Bus free phase"); -#endif // DISK_LOG // Phase Setting ctrl.phase = BUS::busfree; @@ -6444,16 +6439,14 @@ void FASTCALL SASIDEV::Selection() return; } -#if defined(DISK_LOG) - spdlog::info( + spdlog::trace( "Selection Phase ID=%d (with device)", ctrl.id); -#endif // DISK_LOG // Phase change ctrl.phase = BUS::selection; - // Raiase BSY and respond - ctrl.bus->SetBSY(TRUE); + // Raise BSY and respond + ctrl.bus->SetBSY(TRUE); return; } @@ -6481,7 +6474,7 @@ void FASTCALL SASIDEV::Command() if (ctrl.phase != BUS::command) { #if defined(DISK_LOG) - spdlog::info( "Command Phase"); + spdlog::trace( "[ID %d] Moving to command Phase", ctrl.id); #endif // DISK_LOG // Phase Setting @@ -7903,7 +7896,7 @@ void FASTCALL SASIDEV::FlushUnit() } } -#ifdef DISK_LOG +#if 0 //--------------------------------------------------------------------------- // // Get the current phase as a string @@ -8016,9 +8009,7 @@ BUS::phase_t FASTCALL SCSIDEV::Process() // Reset if (ctrl.bus->GetRST()) { -#if defined(DISK_LOG) - spdlog::info( "RESET信号受信"); -#endif // DISK_LOG + spdlog::info( "RESET phase"); // Reset the controller Reset(); @@ -8142,18 +8133,17 @@ void FASTCALL SCSIDEV::Selection() // invalid if IDs do not match id = 1 << ctrl.id; if ((ctrl.bus->GetDAT() & id) == 0) { + spdlog::trace("[ID {}] ID doesn't match {}",ctrl.id,id); return; } // End if there is no valid unit if (!HasUnit()) { + spdlog::trace("[ID {}] No unit attached",ctrl.id); return; } - -#if defined(DISK_LOG) - spdlog::info( - "Selection Phase ID=%d (with device)", ctrl.id); -#endif // DISK_LOG + + spdlog::trace("Selection Phase ID={} (with device)", ctrl.id); // Phase setting ctrl.phase = BUS::selection; diff --git a/src/raspberrypi/gpiobus.cpp b/src/raspberrypi/gpiobus.cpp index 31d6acfd..538c59d0 100644 --- a/src/raspberrypi/gpiobus.cpp +++ b/src/raspberrypi/gpiobus.cpp @@ -65,7 +65,7 @@ DWORD bcm_host_get_peripheral_address(void) char buf[1024]; size_t len = sizeof(buf); DWORD address; - + if (sysctlbyname("hw.model", buf, &len, NULL, 0) || strstr(buf, "ARM1176JZ-S") != buf) { // Failed to get CPU model || Not BCM2835 @@ -88,7 +88,7 @@ extern uint32_t RPi_IO_Base_Addr; // Core frequency extern uint32_t RPi_Core_Freq; -#ifdef USE_SEL_EVENT_ENABLE +#ifdef USE_SEL_EVENT_ENABLE //--------------------------------------------------------------------------- // // Interrupt control function @@ -521,7 +521,7 @@ DWORD FASTCALL GPIOBUS::Aquire() // Invert if negative logic (internal processing is unified to positive logic) signals = ~signals; #endif // SIGNAL_CONTROL_MODE - + return signals; } @@ -552,6 +552,10 @@ BOOL FASTCALL GPIOBUS::GetBSY() //--------------------------------------------------------------------------- void FASTCALL GPIOBUS::SetBSY(BOOL ast) { + if(actmode == MONITOR){ + return; + } + // Set BSY signal SetSignal(PIN_BSY, ast); @@ -601,6 +605,10 @@ BOOL FASTCALL GPIOBUS::GetSEL() //--------------------------------------------------------------------------- void FASTCALL GPIOBUS::SetSEL(BOOL ast) { + if(actmode == MONITOR){ + return; + } + if (actmode == INITIATOR && ast) { // Turn on ACTIVE signal SetControl(PIN_ACT, ACT_ON); @@ -627,6 +635,10 @@ BOOL FASTCALL GPIOBUS::GetATN() //--------------------------------------------------------------------------- void FASTCALL GPIOBUS::SetATN(BOOL ast) { + if(actmode == MONITOR){ + return; + } + SetSignal(PIN_ATN, ast); } @@ -647,9 +659,33 @@ BOOL FASTCALL GPIOBUS::GetACK() //--------------------------------------------------------------------------- void FASTCALL GPIOBUS::SetACK(BOOL ast) { + if(actmode == MONITOR){ + return; + } + SetSignal(PIN_ACK, ast); } +//--------------------------------------------------------------------------- +// +// Get ACK signal +// +//--------------------------------------------------------------------------- +BOOL FASTCALL GPIOBUS::GetACT() +{ + return GetSignal(PIN_ACT); +} + +//--------------------------------------------------------------------------- +// +// Set ACK signal +// +//--------------------------------------------------------------------------- +void FASTCALL GPIOBUS::SetACT(BOOL ast) +{ + SetSignal(PIN_ACT, ast); +} + //--------------------------------------------------------------------------- // // Get RST signal @@ -667,6 +703,10 @@ BOOL FASTCALL GPIOBUS::GetRST() //--------------------------------------------------------------------------- void FASTCALL GPIOBUS::SetRST(BOOL ast) { + if(actmode == MONITOR){ + return; + } + SetSignal(PIN_RST, ast); } @@ -687,6 +727,10 @@ BOOL FASTCALL GPIOBUS::GetMSG() //--------------------------------------------------------------------------- void FASTCALL GPIOBUS::SetMSG(BOOL ast) { + if(actmode == MONITOR){ + return; + } + SetSignal(PIN_MSG, ast); } @@ -707,6 +751,10 @@ BOOL FASTCALL GPIOBUS::GetCD() //--------------------------------------------------------------------------- void FASTCALL GPIOBUS::SetCD(BOOL ast) { + if(actmode == MONITOR){ + return; + } + SetSignal(PIN_CD, ast); } @@ -757,6 +805,10 @@ BOOL FASTCALL GPIOBUS::GetIO() //--------------------------------------------------------------------------- void FASTCALL GPIOBUS::SetIO(BOOL ast) { + if(actmode == MONITOR){ + return; + } + SetSignal(PIN_IO, ast); if (actmode == TARGET) { @@ -805,6 +857,10 @@ BOOL FASTCALL GPIOBUS::GetREQ() //--------------------------------------------------------------------------- void FASTCALL GPIOBUS::SetREQ(BOOL ast) { + if(actmode == MONITOR){ + return; + } + SetSignal(PIN_REQ, ast); } @@ -838,6 +894,10 @@ BYTE FASTCALL GPIOBUS::GetDAT() //--------------------------------------------------------------------------- void FASTCALL GPIOBUS::SetDAT(BYTE dat) { + if(actmode == MONITOR){ + return; + } + // Write to port #if SIGNAL_CONTROL_MODE == 0 DWORD fsel; @@ -1155,7 +1215,7 @@ int FASTCALL GPIOBUS::SendHandShake(BYTE *buf, int count) } // Already waiting for REQ assertion - + // Assert the ACK signal SetSignal(PIN_ACK, ON); @@ -1399,7 +1459,7 @@ void FASTCALL GPIOBUS::SetMode(int pin, int mode) gpio[index] = data; gpfsel[index] = data; } - + //--------------------------------------------------------------------------- // // Get input signal value @@ -1409,7 +1469,7 @@ BOOL FASTCALL GPIOBUS::GetSignal(int pin) { return (signals >> pin) & 1; } - + //--------------------------------------------------------------------------- // // Set output signal value diff --git a/src/raspberrypi/gpiobus.h b/src/raspberrypi/gpiobus.h index 340c9585..9d269e15 100644 --- a/src/raspberrypi/gpiobus.h +++ b/src/raspberrypi/gpiobus.h @@ -140,6 +140,7 @@ #define PIN_IO 25 // IO #define PIN_BSY 26 // BSY #define PIN_SEL 27 // SEL + #endif #ifdef CONNECT_TYPE_FULLSPEC @@ -276,6 +277,26 @@ #define PIN_SEL 23 // SEL #endif +#define ALL_SCSI_PINS \ + ((1< + +//--------------------------------------------------------------------------- +// +// Constant declarations +// +//--------------------------------------------------------------------------- +#define FPRT(fp, ...) fprintf(fp, __VA_ARGS__ ) + +//--------------------------------------------------------------------------- +// +// Variable declarations +// +//--------------------------------------------------------------------------- +static BYTE prev_value[32] = {0xFF}; +static volatile BOOL running; // Running flag +static volatile BOOL active; // Processing flag +GPIOBUS *bus; // GPIO Bus +typedef struct data_capture{ + DWORD data; + timeval timestamp; +} data_capture_t; + + +#define MAX_BUFF_SIZE 1000000 + +data_capture data_buffer[MAX_BUFF_SIZE]; +int data_idx = 0; + +// Symbol definition for the VCD file +// These are just arbitrary symbols. They can be anything allowed by the VCD file format, +// as long as they're consistently used. +#define SYMBOL_PIN_DAT '#' +#define SYMBOL_PIN_ATN '+' +#define SYMBOL_PIN_RST '$' +#define SYMBOL_PIN_ACK '%' +#define SYMBOL_PIN_REQ '^' +#define SYMBOL_PIN_MSG '&' +#define SYMBOL_PIN_CD '*' +#define SYMBOL_PIN_IO '(' +#define SYMBOL_PIN_BSY ')' +#define SYMBOL_PIN_SEL '-' + + +//--------------------------------------------------------------------------- +// +// Signal Processing +// +//--------------------------------------------------------------------------- +void KillHandler(int sig) +{ + // Stop instruction + running = FALSE; +} + +//--------------------------------------------------------------------------- +// +// Banner Output +// +//--------------------------------------------------------------------------- +void Banner(int argc, char* argv[]) +{ + FPRT(stdout,"SCSI Shark Capture Tool - part of RaSCSI(*^..^*) "); + FPRT(stdout,"version %01d.%01d%01d(%s, %s)\n", + (int)((VERSION >> 8) & 0xf), + (int)((VERSION >> 4) & 0xf), + (int)((VERSION ) & 0xf), + __DATE__, + __TIME__); + FPRT(stdout,"Powered by XM6 TypeG Technology / "); + FPRT(stdout,"Copyright (C) 2016-2020 GIMONS\n"); + FPRT(stdout,"Copyright (C) 2020 akuker\n"); + FPRT(stdout,"Connect type : %s\n", CONNECT_DESC); + + FPRT(stdout,"\nPress CTRL-C to stop collecting data.\n"); + FPRT(stdout," log.csv - CSV listing of the data collected\n"); + FPRT(stdout," log.vcd - Value Change Dump file that can be opened with GTKWave\n"); + + if ((argc > 1 && strcmp(argv[1], "-h") == 0) || + (argc > 1 && strcmp(argv[1], "--help") == 0)){ + FPRT(stdout,"\n"); + FPRT(stdout,"Usage: %s ...\n\n", argv[0]); + + exit(0); + } +} + +//--------------------------------------------------------------------------- +// +// Initialization +// +//--------------------------------------------------------------------------- +BOOL Init() +{ + // Interrupt handler settings + if (signal(SIGINT, KillHandler) == SIG_ERR) { + return FALSE; + } + if (signal(SIGHUP, KillHandler) == SIG_ERR) { + return FALSE; + } + if (signal(SIGTERM, KillHandler) == SIG_ERR) { + return FALSE; + } + + // GPIOBUS creation + bus = new GPIOBUS(); + + // GPIO Initialization + if (!bus->Init()) { + return FALSE; + } + + // Bus Reset + bus->Reset(); + + // Other + running = FALSE; + active = FALSE; + + return TRUE; +} + +BOOL get_pin_value(DWORD data, int pin) +{ + return (data >> pin) & 1; +} + +BYTE get_data_field(DWORD data) +{ + DWORD data_out; + data_out = + ((data >> (PIN_DT0 - 0)) & (1 << 0)) | + ((data >> (PIN_DT1 - 1)) & (1 << 1)) | + ((data >> (PIN_DT2 - 2)) & (1 << 2)) | + ((data >> (PIN_DT3 - 3)) & (1 << 3)) | + ((data >> (PIN_DT4 - 4)) & (1 << 4)) | + ((data >> (PIN_DT5 - 5)) & (1 << 5)) | + ((data >> (PIN_DT6 - 6)) & (1 << 6)) | + ((data >> (PIN_DT7 - 7)) & (1 << 7)); + + return (BYTE)data_out; +} + + +void vcd_output_if_changed_bool(FILE *fp, DWORD data, int pin, char symbol) +{ + BOOL new_value = get_pin_value(data,pin); + if(prev_value[pin] != new_value) + { + prev_value[pin] = new_value; + fprintf(fp, "%d%c\n", new_value, symbol); + } +} + +void vcd_output_if_changed_byte(FILE *fp, DWORD data, int pin, char symbol) +{ + BYTE new_value = get_data_field(data); + if(prev_value[pin] != new_value) + { + prev_value[pin] = new_value; + fprintf(fp, "b%d%d%d%d%d%d%d%d %c\n", + get_pin_value(data,PIN_DT0), + get_pin_value(data,PIN_DT1), + get_pin_value(data,PIN_DT2), + get_pin_value(data,PIN_DT3), + get_pin_value(data,PIN_DT4), + get_pin_value(data,PIN_DT5), + get_pin_value(data,PIN_DT6), + get_pin_value(data,PIN_DT7), symbol); + } +} + + +void create_value_change_dump() +{ + time_t rawtime; + struct tm * timeinfo; + int i = 0; + timeval time_diff; + char timestamp[256]; + FILE *fp; + timeval start_time = data_buffer[0].timestamp; + printf("Creating Value Change Dump file (log.vcd)\n"); + fp = fopen("log.vcd","w"); + + // Get the current time + time (&rawtime); + timeinfo = localtime(&rawtime); + strftime (timestamp,sizeof(timestamp),"%d-%m-%Y %H-%M-%S",timeinfo); + + fprintf(fp, "$date\n"); + fprintf(fp, "%s\n", timestamp); + fprintf(fp, "$end\n"); + fprintf(fp, "$version\n"); + fprintf(fp, " VCD generator tool version info text.\n"); + fprintf(fp, "$end\n"); + fprintf(fp, "$comment\n"); + fprintf(fp, " Any comment text.\n"); + fprintf(fp, "$end\n"); + fprintf(fp, "$timescale 1 us $end\n"); + fprintf(fp, "$scope module logic $end\n"); + fprintf(fp, "$var wire 1 %c BSY $end\n", SYMBOL_PIN_BSY); + fprintf(fp, "$var wire 1 %c SEL $end\n", SYMBOL_PIN_SEL); + fprintf(fp, "$var wire 1 %c CD $end\n", SYMBOL_PIN_CD); + fprintf(fp, "$var wire 1 %c IO $end\n", SYMBOL_PIN_IO); + fprintf(fp, "$var wire 1 %c MSG $end\n", SYMBOL_PIN_MSG); + fprintf(fp, "$var wire 1 %c REQ $end\n", SYMBOL_PIN_REQ); + fprintf(fp, "$var wire 1 %c ACK $end\n", SYMBOL_PIN_ACK); + fprintf(fp, "$var wire 1 %c ATN $end\n", SYMBOL_PIN_ATN); + fprintf(fp, "$var wire 1 %c RST $end\n", SYMBOL_PIN_RST); + fprintf(fp, "$var wire 8 %c data $end\n", SYMBOL_PIN_DAT); + fprintf(fp, "$upscope $end\n"); + fprintf(fp, "$enddefinitions $end\n"); + + // Initial values - default to zeros + fprintf(fp, "$dumpvars\n"); + fprintf(fp, "0%c\n", SYMBOL_PIN_BSY); + fprintf(fp, "0%c\n", SYMBOL_PIN_SEL); + fprintf(fp, "0%c\n", SYMBOL_PIN_CD); + fprintf(fp, "0%c\n", SYMBOL_PIN_IO); + fprintf(fp, "0%c\n", SYMBOL_PIN_MSG); + fprintf(fp, "0%c\n", SYMBOL_PIN_REQ); + fprintf(fp, "0%c\n", SYMBOL_PIN_ACK); + fprintf(fp, "0%c\n", SYMBOL_PIN_ATN); + fprintf(fp, "0%c\n", SYMBOL_PIN_RST); + fprintf(fp, "b00000000 %c\n", SYMBOL_PIN_DAT); + fprintf(fp, "$end\n"); + + while(i < data_idx) + { + timersub(&(data_buffer[i].timestamp), &start_time, &time_diff); + fprintf(fp, "#%ld\n",((time_diff.tv_sec*1000000) + time_diff.tv_usec)); + vcd_output_if_changed_bool(fp, data_buffer[i].data, PIN_BSY, SYMBOL_PIN_BSY); + vcd_output_if_changed_bool(fp, data_buffer[i].data, PIN_SEL, SYMBOL_PIN_SEL); + vcd_output_if_changed_bool(fp, data_buffer[i].data, PIN_CD, SYMBOL_PIN_CD); + vcd_output_if_changed_bool(fp, data_buffer[i].data, PIN_IO, SYMBOL_PIN_IO); + vcd_output_if_changed_bool(fp, data_buffer[i].data, PIN_MSG, SYMBOL_PIN_MSG); + vcd_output_if_changed_bool(fp, data_buffer[i].data, PIN_REQ, SYMBOL_PIN_REQ); + vcd_output_if_changed_bool(fp, data_buffer[i].data, PIN_ACK, SYMBOL_PIN_ACK); + vcd_output_if_changed_bool(fp, data_buffer[i].data, PIN_ATN, SYMBOL_PIN_ATN); + vcd_output_if_changed_bool(fp, data_buffer[i].data, PIN_RST, SYMBOL_PIN_RST); + vcd_output_if_changed_byte(fp, data_buffer[i].data, PIN_DT0, SYMBOL_PIN_DAT); + i++; + } + fclose(fp); +} + + + +void create_comma_separated_file() +{ + int i = 0; + timeval time_diff; + FILE *fp; + timeval start_time = data_buffer[0].timestamp; + + printf("Creating log.csv\n"); + fp = fopen("log.csv","w"); + + fprintf(fp, "idx,raw,timestamp,BSY,SEL,C/D,I/O,MSG,,REQ,ACK,ATN,RST,Data\n"); + + while(i < data_idx) + { + timersub(&(data_buffer[i].timestamp), &start_time, &time_diff); + fprintf(fp, "%d,%08lX,%ld.%ld,",data_idx, data_buffer[i].data, time_diff.tv_sec, time_diff.tv_usec); + fprintf(fp, "%d,", get_pin_value(data_buffer[i].data, PIN_BSY)); + fprintf(fp, "%d,", get_pin_value(data_buffer[i].data, PIN_SEL)); + fprintf(fp, "%d,", get_pin_value(data_buffer[i].data, PIN_CD)); + fprintf(fp, "%d,", get_pin_value(data_buffer[i].data, PIN_IO)); + fprintf(fp, "%d,", get_pin_value(data_buffer[i].data, PIN_MSG)); + fprintf(fp, "%d,", get_pin_value(data_buffer[i].data, PIN_REQ)); + fprintf(fp, "%d,", get_pin_value(data_buffer[i].data, PIN_ACK)); + fprintf(fp, "%d,", get_pin_value(data_buffer[i].data, PIN_ATN)); + fprintf(fp, "%d,", get_pin_value(data_buffer[i].data, PIN_RST)); + fprintf(fp, "%02X,", get_data_field(data_buffer[i].data)); + fprintf(fp, "\n"); + i++; + } + fclose(fp); +} + + + +//--------------------------------------------------------------------------- +// +// Cleanup +// +//--------------------------------------------------------------------------- +void Cleanup() +{ + + printf("In cleanup....\n"); + create_comma_separated_file(); + create_value_change_dump(); + + // Cleanup the Bus + bus->Cleanup(); + + // Discard the GPIOBUS object + delete bus; + +} + +//--------------------------------------------------------------------------- +// +// Reset +// +//--------------------------------------------------------------------------- +void Reset() +{ + // Reset the bus + bus->Reset(); +} + +//--------------------------------------------------------------------------- +// +// Pin the thread to a specific CPU +// +//--------------------------------------------------------------------------- +void FixCpu(int cpu) +{ + cpu_set_t cpuset; + int cpus; + + // Get the number of CPUs + CPU_ZERO(&cpuset); + sched_getaffinity(0, sizeof(cpu_set_t), &cpuset); + 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); + } +} + +static DWORD high_bits = 0x0; +static DWORD low_bits = 0xFFFFFFFF; + + +//--------------------------------------------------------------------------- +// +// Main processing +// +//--------------------------------------------------------------------------- +#ifdef BAREMETAL +extern "C" +int startrascsi(void) +{ + int argc = 0; + char** argv = NULL; +#else +int main(int argc, char* argv[]) +{ +#endif // BAREMETAL + DWORD prev_high = high_bits; + DWORD prev_low = low_bits; + DWORD prev_sample = 0xFFFFFFFF; + DWORD this_sample = 0; + int ret; + struct sched_param schparam; + + spdlog::set_level(spdlog::level::trace); + spdlog::trace("Entering the function with {0:x}{1:X} arguments", argc,20); + // Output the Banner + Banner(argc, argv); + memset(data_buffer,0,sizeof(data_buffer)); + + // Initialize + ret = 0; + if (!Init()) { + ret = EPERM; + goto init_exit; + } + + // Reset + Reset(); + + // Set the affinity to a specific processor core + FixCpu(3); + + // Scheduling policy setting (highest priority) + schparam.sched_priority = sched_get_priority_max(SCHED_FIFO); + sched_setscheduler(0, SCHED_FIFO, &schparam); + + // Start execution + running = TRUE; + bus->SetACT(FALSE); + + spdlog::trace("Going into running mode {}", 1); + printf("ALL_SCSI_PINS %08X\n",ALL_SCSI_PINS); + // Main Loop + while (running) { + // Work initialization + this_sample = (bus->Aquire() & ALL_SCSI_PINS); + + if(this_sample != prev_sample) + { + + // This is intended to be a debug check to see if every pin is set + // high and low at some point. + high_bits |= this_sample; + low_bits &= this_sample; + + if ((high_bits != prev_high) || (low_bits != prev_low)) + { + printf(" %08lX %08lX\n",high_bits, low_bits); + } + prev_high = high_bits; + prev_low = low_bits; + + //printf("%d Sample %08lX\n", data_idx, this_sample); + data_buffer[data_idx].data = this_sample; + (void)gettimeofday(&(data_buffer[data_idx].timestamp), NULL); + data_idx = (data_idx + 1) % MAX_BUFF_SIZE; + prev_sample = this_sample; + } + + continue; + } + + // Cleanup + Cleanup(); + +init_exit: + exit(ret); +}