//--------------------------------------------------------------------------- // // SCSI Target Emulator RaSCSI (*^..^*) // for Raspberry Pi // // Powered by XM6 TypeG Technology. // Copyright (C) 2016-2020 GIMONS // [ GPIO-SCSI bus ] // //--------------------------------------------------------------------------- #if !defined(gpiobus_h) #define gpiobus_h #include "scsi.h" //--------------------------------------------------------------------------- // // Connection method definitions // //--------------------------------------------------------------------------- //#define CONNECT_TYPE_STANDARD // Standard (SCSI logic, standard pin assignment) //#define CONNECT_TYPE_FULLSPEC // Full spec (SCSI logic, standard pin assignment) //#define CONNECT_TYPE_AIBOM // AIBOM version (positive logic, unique pin assignment) //#define CONNECT_TYPE_GAMERNIUM // GAMERnium.com version (standard logic, unique pin assignment) //--------------------------------------------------------------------------- // // Signal control logic and pin assignment customization // //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // // SIGNAL_CONTROL_MODE: Signal control mode selection // You can customize the signal control logic from Version 1.22 // // 0:SCSI logical specification // Conversion board using 74LS641-1 etc. directly connected or published on HP // True : 0V // False : Open collector output (disconnect from bus) // // 1:Negative logic specification (when using conversion board for negative logic -> SCSI logic) // There is no conversion board with this specification at this time // True : 0V -> (CONVERT) -> 0V // False : 3.3V -> (CONVERT) -> Open collector output // // 2:Positive logic specification (when using the conversion board for positive logic -> SCSI logic) // RaSCSI Adapter Rev.C @132sync etc. // // True : 3.3V -> (CONVERT) -> 0V // False : 0V -> (CONVERT) -> Open collector output // //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // // Control signal pin assignment setting // GPIO pin mapping table for control signals. // // Control signal: // PIN_ACT // Signal that indicates the status of processing SCSI command. // PIN_ENB // Signal that indicates the valid signal from start to finish. // PIN_TAD // Signal that indicates the input/output direction of the target signal (BSY,IO,CD,MSG,REG). // PIN_IND // Signal that indicates the input/output direction of the initiator signal (SEL, ATN, RST, ACK). // PIN_DTD // Signal that indicates the input/output direction of the data lines (DT0...DT7,DP). // //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // // Control signal output logic // 0V:FALSE 3.3V:TRUE // // ACT_ON // PIN_ACT signal // ENB_ON // PIN_ENB signal // TAD_IN // PIN_TAD This is the logic when inputting. // IND_IN // PIN_ENB This is the logic when inputting. // DTD_IN // PIN_ENB This is the logic when inputting. // //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // // SCSI signal pin assignment setting // GPIO pin mapping table for SCSI signals. // PIN_DT0~PIN_SEL // //--------------------------------------------------------------------------- #ifdef CONNECT_TYPE_STANDARD // // RaSCSI standard (SCSI logic, standard pin assignment) // #define CONNECT_DESC "STANDARD" // Startup message // Select signal control mode #define SIGNAL_CONTROL_MODE 0 // SCSI logical specification // Control signal pin assignment (-1 means no control) #define PIN_ACT 4 // ACTIVE #define PIN_ENB 5 // ENABLE #define PIN_IND -1 // INITIATOR CTRL DIRECTION #define PIN_TAD -1 // TARGET CTRL DIRECTION #define PIN_DTD -1 // DATA DIRECTION // Control signal output logic #define ACT_ON TRUE // ACTIVE SIGNAL ON #define ENB_ON TRUE // ENABLE SIGNAL ON #define IND_IN FALSE // INITIATOR SIGNAL INPUT #define TAD_IN FALSE // TARGET SIGNAL INPUT #define DTD_IN TRUE // DATA SIGNAL INPUT // SCSI signal pin assignment #define PIN_DT0 10 // Data 0 #define PIN_DT1 11 // Data 1 #define PIN_DT2 12 // Data 2 #define PIN_DT3 13 // Data 3 #define PIN_DT4 14 // Data 4 #define PIN_DT5 15 // Data 5 #define PIN_DT6 16 // Data 6 #define PIN_DT7 17 // Data 7 #define PIN_DP 18 // Data parity #define PIN_ATN 19 // ATN #define PIN_RST 20 // RST #define PIN_ACK 21 // ACK #define PIN_REQ 22 // REQ #define PIN_MSG 23 // MSG #define PIN_CD 24 // CD #define PIN_IO 25 // IO #define PIN_BSY 26 // BSY #define PIN_SEL 27 // SEL #endif #ifdef CONNECT_TYPE_FULLSPEC // // RaSCSI standard (SCSI logic, standard pin assignment) // #define CONNECT_DESC "FULLSPEC" // Startup message // Select signal control mode #define SIGNAL_CONTROL_MODE 0 // SCSI logical specification // Control signal pin assignment (-1 means no control) #define PIN_ACT 4 // ACTIVE #define PIN_ENB 5 // ENABLE #define PIN_IND 6 // INITIATOR CTRL DIRECTION #define PIN_TAD 7 // TARGET CTRL DIRECTION #define PIN_DTD 8 // DATA DIRECTION // Control signal output logic #define ACT_ON TRUE // ACTIVE SIGNAL ON #define ENB_ON TRUE // ENABLE SIGNAL ON #define IND_IN FALSE // INITIATOR SIGNAL INPUT #define TAD_IN FALSE // TARGET SIGNAL INPUT #define DTD_IN TRUE // DATA SIGNAL INPUT // SCSI signal pin assignment #define PIN_DT0 10 // Data 0 #define PIN_DT1 11 // Data 1 #define PIN_DT2 12 // Data 2 #define PIN_DT3 13 // Data 3 #define PIN_DT4 14 // Data 4 #define PIN_DT5 15 // Data 5 #define PIN_DT6 16 // Data 6 #define PIN_DT7 17 // Data 7 #define PIN_DP 18 // Data parity #define PIN_ATN 19 // ATN #define PIN_RST 20 // RST #define PIN_ACK 21 // ACK #define PIN_REQ 22 // REQ #define PIN_MSG 23 // MSG #define PIN_CD 24 // CD #define PIN_IO 25 // IO #define PIN_BSY 26 // BSY #define PIN_SEL 27 // SEL #endif #ifdef CONNECT_TYPE_AIBOM // // RaSCSI Adapter Aibomu version // #define CONNECT_DESC "AIBOM PRODUCTS version" // Startup message // Select signal control mode #define SIGNAL_CONTROL_MODE 2 // SCSI positive logic specification // Control signal output logic #define ACT_ON TRUE // ACTIVE SIGNAL ON #define ENB_ON TRUE // ENABLE SIGNAL ON #define IND_IN FALSE // INITIATOR SIGNAL INPUT #define TAD_IN FALSE // TARGET SIGNAL INPUT #define DTD_IN FALSE // DATA SIGNAL INPUT // Control signal pin assignment (-1 means no control) #define PIN_ACT 4 // ACTIVE #define PIN_ENB 17 // ENABLE #define PIN_IND 27 // INITIATOR CTRL DIRECTION #define PIN_TAD -1 // TARGET CTRL DIRECTION #define PIN_DTD 18 // DATA DIRECTION // SCSI signal pin assignment #define PIN_DT0 6 // Data 0 #define PIN_DT1 12 // Data 1 #define PIN_DT2 13 // Data 2 #define PIN_DT3 16 // Data 3 #define PIN_DT4 19 // Data 4 #define PIN_DT5 20 // Data 5 #define PIN_DT6 26 // Data 6 #define PIN_DT7 21 // Data 7 #define PIN_DP 5 // Data parity #define PIN_ATN 22 // ATN #define PIN_RST 25 // RST #define PIN_ACK 10 // ACK #define PIN_REQ 7 // REQ #define PIN_MSG 9 // MSG #define PIN_CD 11 // CD #define PIN_IO 23 // IO #define PIN_BSY 24 // BSY #define PIN_SEL 8 // SEL #endif #ifdef CONNECT_TYPE_GAMERNIUM // // RaSCSI Adapter GAMERnium.com版 // #define CONNECT_DESC "GAMERnium.com version"// Startup message // Select signal control mode #define SIGNAL_CONTROL_MODE 0 // SCSI logical specification // Control signal output logic #define ACT_ON TRUE // ACTIVE SIGNAL ON #define ENB_ON TRUE // ENABLE SIGNAL ON #define IND_IN FALSE // INITIATOR SIGNAL INPUT #define TAD_IN FALSE // TARGET SIGNAL INPUT #define DTD_IN TRUE // DATA SIGNAL INPUT // Control signal pin assignment (-1 means no control) #define PIN_ACT 14 // ACTIVE #define PIN_ENB 6 // ENABLE #define PIN_IND 7 // INITIATOR CTRL DIRECTION #define PIN_TAD 8 // TARGET CTRL DIRECTION #define PIN_DTD 5 // DATA DIRECTION // SCSI signal pin assignment #define PIN_DT0 21 // Data 0 #define PIN_DT1 26 // Data 1 #define PIN_DT2 20 // Data 2 #define PIN_DT3 19 // Data 3 #define PIN_DT4 16 // Data 4 #define PIN_DT5 13 // Data 5 #define PIN_DT6 12 // Data 6 #define PIN_DT7 11 // Data 7 #define PIN_DP 25 // Data parity #define PIN_ATN 10 // ATN #define PIN_RST 22 // RST #define PIN_ACK 24 // ACK #define PIN_REQ 15 // REQ #define PIN_MSG 17 // MSG #define PIN_CD 18 // CD #define PIN_IO 4 // IO #define PIN_BSY 27 // BSY #define PIN_SEL 23 // SEL #endif //--------------------------------------------------------------------------- // // Constant declarations(GPIO) // //--------------------------------------------------------------------------- #define SYST_OFFSET 0x00003000 #define IRPT_OFFSET 0x0000B200 #define ARMT_OFFSET 0x0000B400 #define PADS_OFFSET 0x00100000 #define GPIO_OFFSET 0x00200000 #define QA7_OFFSET 0x01000000 #define GPIO_INPUT 0 #define GPIO_OUTPUT 1 #define GPIO_PULLNONE 0 #define GPIO_PULLDOWN 1 #define GPIO_PULLUP 2 #define GPIO_FSEL_0 0 #define GPIO_FSEL_1 1 #define GPIO_FSEL_2 2 #define GPIO_FSEL_3 3 #define GPIO_SET_0 7 #define GPIO_CLR_0 10 #define GPIO_LEV_0 13 #define GPIO_EDS_0 16 #define GPIO_REN_0 19 #define GPIO_FEN_0 22 #define GPIO_HEN_0 25 #define GPIO_LEN_0 28 #define GPIO_AREN_0 31 #define GPIO_AFEN_0 34 #define GPIO_PUD 37 #define GPIO_CLK_0 38 #define GPIO_GPPINMUXSD 52 #define GPIO_PUPPDN0 57 #define GPIO_PUPPDN1 58 #define GPIO_PUPPDN3 59 #define GPIO_PUPPDN4 60 #define PAD_0_27 11 #define SYST_CS 0 #define SYST_CLO 1 #define SYST_CHI 2 #define SYST_C0 3 #define SYST_C1 4 #define SYST_C2 5 #define SYST_C3 6 #define ARMT_LOAD 0 #define ARMT_VALUE 1 #define ARMT_CTRL 2 #define ARMT_CLRIRQ 3 #define ARMT_RAWIRQ 4 #define ARMT_MSKIRQ 5 #define ARMT_RELOAD 6 #define ARMT_PREDIV 7 #define ARMT_FREERUN 8 #define IRPT_PND_IRQ_B 0 #define IRPT_PND_IRQ_1 1 #define IRPT_PND_IRQ_2 2 #define IRPT_FIQ_CNTL 3 #define IRPT_ENB_IRQ_1 4 #define IRPT_ENB_IRQ_2 5 #define IRPT_ENB_IRQ_B 6 #define IRPT_DIS_IRQ_1 7 #define IRPT_DIS_IRQ_2 8 #define IRPT_DIS_IRQ_B 9 #define QA7_CORE0_TINTC 16 #define GPIO_IRQ (32 + 20) // GPIO3 #define GPIO_INEDGE ((1 << PIN_BSY) | \ (1 << PIN_SEL) | \ (1 << PIN_ATN) | \ (1 << PIN_ACK) | \ (1 << PIN_RST)) #define GPIO_MCI ((1 << PIN_MSG) | \ (1 << PIN_CD) | \ (1 << PIN_IO)) //--------------------------------------------------------------------------- // // Constant declarations(GIC) // //--------------------------------------------------------------------------- #define ARM_GICD_BASE 0xFF841000 #define ARM_GICC_BASE 0xFF842000 #define ARM_GIC_END 0xFF847FFF #define GICD_CTLR 0x000 #define GICD_IGROUPR0 0x020 #define GICD_ISENABLER0 0x040 #define GICD_ICENABLER0 0x060 #define GICD_ISPENDR0 0x080 #define GICD_ICPENDR0 0x0A0 #define GICD_ISACTIVER0 0x0C0 #define GICD_ICACTIVER0 0x0E0 #define GICD_IPRIORITYR0 0x100 #define GICD_ITARGETSR0 0x200 #define GICD_ICFGR0 0x300 #define GICD_SGIR 0x3C0 #define GICC_CTLR 0x000 #define GICC_PMR 0x001 #define GICC_IAR 0x003 #define GICC_EOIR 0x004 //--------------------------------------------------------------------------- // // Constant declarations(GIC IRQ) // //--------------------------------------------------------------------------- #define GIC_IRQLOCAL0 (16 + 14) #define GIC_GPIO_IRQ (32 + 116) // GPIO3 //--------------------------------------------------------------------------- // // Constant declarations (Control signals) // //--------------------------------------------------------------------------- #define ACT_OFF !ACT_ON #define ENB_OFF !ENB_ON #define TAD_OUT !TAD_IN #define IND_OUT !IND_IN #define DTD_OUT !DTD_IN //--------------------------------------------------------------------------- // // Constant declarations(SCSI) // //--------------------------------------------------------------------------- #define IN GPIO_INPUT #define OUT GPIO_OUTPUT #define ON TRUE #define OFF FALSE //--------------------------------------------------------------------------- // // Constant declarations (bus control timing) // //--------------------------------------------------------------------------- #define GPIO_DATA_SETTLING 100 // Data bus stabilization time (ns) //--------------------------------------------------------------------------- // // Class definition // //--------------------------------------------------------------------------- class GPIOBUS : public BUS { public: // Basic Functions GPIOBUS(); // Constructor virtual ~GPIOBUS(); // Destructor BOOL FASTCALL Init(mode_e mode = TARGET); // Initialization void FASTCALL Reset(); // Reset void FASTCALL Cleanup(); // Cleanup DWORD FASTCALL Aquire(); // Signal acquisition void FASTCALL SetENB(BOOL ast); // Set ENB signal BOOL FASTCALL GetBSY(); // Get BSY signal void FASTCALL SetBSY(BOOL ast); // Set BSY signal BOOL FASTCALL GetSEL(); // Get SEL signal void FASTCALL SetSEL(BOOL ast); // Set SEL signal BOOL FASTCALL GetATN(); // Get ATN signal void FASTCALL SetATN(BOOL ast); // Set ATN signal BOOL FASTCALL GetACK(); // Get ACK signal void FASTCALL SetACK(BOOL ast); // Set ACK signal BOOL FASTCALL GetRST(); // Get RST signal void FASTCALL SetRST(BOOL ast); // Set RST signal BOOL FASTCALL GetMSG(); // Get MSG signal void FASTCALL SetMSG(BOOL ast); // Set MSG signal BOOL FASTCALL GetCD(); // Get CD signal void FASTCALL SetCD(BOOL ast); // Set CD signal BOOL FASTCALL GetIO(); // Get IO signal void FASTCALL SetIO(BOOL ast); // Set IO signal BOOL FASTCALL GetREQ(); // Get REQ signal void FASTCALL SetREQ(BOOL ast); // Set REQ signal BYTE FASTCALL GetDAT(); // Get DAT signal void FASTCALL SetDAT(BYTE dat); // Set DAT signal BOOL FASTCALL GetDP(); // Get Data parity signal int FASTCALL CommandHandShake(BYTE *buf); // Command receive handshake int FASTCALL ReceiveHandShake(BYTE *buf, int count); // Data receive handshake int FASTCALL SendHandShake(BYTE *buf, int count); // Data transmission handshake #ifdef USE_SEL_EVENT_ENABLE // SEL signal interrupt int FASTCALL PollSelectEvent(); // SEL signal event polling void FASTCALL ClearSelectEvent(); // Clear SEL signal event #endif // USE_SEL_EVENT_ENABLE private: // SCSI I/O signal control void FASTCALL MakeTable(); // Create work data void FASTCALL SetControl(int pin, BOOL ast); // Set Control Signal void FASTCALL SetMode(int pin, int mode); // Set SCSI I/O mode BOOL FASTCALL GetSignal(int pin); // Get SCSI input signal value void FASTCALL SetSignal(int pin, BOOL ast); // Set SCSI output signal value BOOL FASTCALL WaitSignal(int pin, BOOL ast); // Wait for a signal to change // Interrupt control void FASTCALL DisableIRQ(); // IRQ Disabled void FASTCALL EnableIRQ(); // IRQ Enabled // GPIO pin functionality settings void FASTCALL PinConfig(int pin, int mode); // GPIO pin direction setting void FASTCALL PullConfig(int pin, int mode); // GPIO pin pull up/down resistor setting void FASTCALL PinSetSignal(int pin, BOOL ast); // Set GPIO output signal void FASTCALL DrvConfig(DWORD drive); // Set GPIO drive strength mode_e actmode; // Operation mode DWORD baseaddr; // Base address int rpitype; // Type of Raspberry Pi volatile DWORD *gpio; // GPIO register volatile DWORD *pads; // PADS register volatile DWORD *level; // GPIO input level volatile DWORD *irpctl; // Interrupt control register #ifndef BAREMETAL volatile DWORD irptenb; // Interrupt enabled state volatile DWORD *qa7regs; // QA7 register volatile int tintcore; // Interupt control target CPU. volatile DWORD tintctl; // Interupt control volatile DWORD giccpmr; // GICC priority setting #endif // BAREMETAL volatile DWORD *gicd; // GIC Interrupt distributor register volatile DWORD *gicc; // GIC CPU interface register DWORD gpfsel[4]; // GPFSEL0-4 backup values DWORD signals; // All bus signals #if defined(USE_SEL_EVENT_ENABLE) && !defined(BAREMETAL) && defined(__linux__) struct gpioevent_request selevreq; // SEL signal event request int epfd; // epoll file descriptor #endif // USE_SEL_EVENT_ENABLE && !BAREMETAL #if SIGNAL_CONTROL_MODE == 0 DWORD tblDatMsk[3][256]; // Data mask table DWORD tblDatSet[3][256]; // Data setting table #else DWORD tblDatMsk[256]; // Data mask table DWORD tblDatSet[256]; // Table setting table #endif static const int SignalTable[19]; // signal table }; //=========================================================================== // // System timer // //=========================================================================== class SysTimer { public: static void FASTCALL Init(DWORD *syst, DWORD *armt); // Initialization static DWORD FASTCALL GetTimerLow(); // Get system timer low byte static DWORD FASTCALL GetTimerHigh(); // Get system timer high byte static void FASTCALL SleepNsec(DWORD nsec); // Sleep for N nanoseconds static void FASTCALL SleepUsec(DWORD usec); // Sleep for N microseconds private: static volatile DWORD *systaddr; // System timer address static volatile DWORD *armtaddr; // ARM timer address static volatile DWORD corefreq; // Core frequency }; #endif // gpiobus_h