diff --git a/platformio.ini b/platformio.ini index f094f3e..6b8bde1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,20 +1,11 @@ ; PlatformIO Project Configuration File https://docs.platformio.org/page/projectconf.html - -[env:genericSTM32F103C8] -platform = ststm32 -board = genericSTM32F103C8 -board_build.mcu = stm32f103c8t6 -board_build.core = maple +[env] framework = arduino lib_deps = greiman/SdFat @ ^2.0.6 upload_protocol = stlink ; Different gcc versions produce much different binaries in terms of speed. platform_packages = platformio/toolchain-gccarmnoneeabi@1.90301.200702 - -build_unflags = - -Os - -DARDUINO_ARCH_STM32F1 build_flags = -w -DARDUINO_GENERIC_STM32F103C @@ -23,11 +14,21 @@ build_flags = -DARDUINO_ARCH_STM32 -DDEBUG_LEVEL=DEBUG_NONE -O2 - -; Work around for clones. -; https://community.platformio.org/t/cannot-upload-to-stm32-bluepill-board-over-stlink-v2/3492/25 +build_unflags = + -Os + -DARDUINO_ARCH_STM32F1 upload_flags = -c set CPUTAPID 0 +[env:STM32F103C8] +platform = ststm32 +board = genericSTM32F103C8 +board_build.mcu = stm32f103c8t6 +board_build.core = maple + +[env:STM32F103C8-XCVR] +extends = env:STM32F103C8 +build_flags = ${env.build_flags} -DXCVR + ; [env:debug] ; build_type = debug ; debug_tool = stlink diff --git a/src/BlueSCSI.cpp b/src/BlueSCSI.cpp index 4ba143d..2ac79b6 100644 --- a/src/BlueSCSI.cpp +++ b/src/BlueSCSI.cpp @@ -50,8 +50,8 @@ #define SCSI_SELECT 0 // 0 for STANDARD // 1 for SHARP X1turbo // 2 for NEC PC98 -#define READ_SPEED_OPTIMIZE 1 // Faster reads -#define WRITE_SPEED_OPTIMIZE 1 // Speeding up writes +#define READ_SPEED_OPTIMIZE 1 // Faster reads +#define WRITE_SPEED_OPTIMIZE 1 // Speeding up writes // SCSI config #define NUM_SCSIID 7 // Maximum number of supported SCSI-IDs (The minimum is 0) @@ -117,8 +117,13 @@ SdFs SD; #define LED PC13 // LED // Image Set Selector +#ifdef XCVR +#define IMAGE_SELECT1 PC14 +#define IMAGE_SELECT2 PC15 +#else #define IMAGE_SELECT1 PA1 #define IMAGE_SELECT2 PB1 +#endif // GPIO register port #define PAREG GPIOA->regs @@ -133,7 +138,7 @@ SdFs SD; #define PB(BIT) (BIT+16) // Virtual pin decoding #define GPIOREG(VPIN) ((VPIN)>=16?PBREG:PAREG) -#define BITMASK(VPIN) (1<<((VPIN)&15)) +#define BITMASK(VPIN) (1<<((VPIN)&15)) #define vATN PA(8) // SCSI:ATN #define vBSY PA(9) // SCSI:BSY @@ -164,6 +169,33 @@ SdFs SD; #define SCSI_PHASE_CHANGE(MASK) { PBREG->BSRR = (MASK); } +#ifdef XCVR +#define TR_TARGET PA1 // Target Transceiver Control Pin +#define TR_DBP PA2 // Data Pins Transceiver Control Pin +#define TR_INITIATOR PA3 // Initiator Transciever Control Pin + +#define vTR_TARGET PA(1) // Target Transceiver Control Pin +#define vTR_DBP PA(2) // Data Pins Transceiver Control Pin +#define vTR_INITIATOR PA(3) // Initiator Transciever Control Pin + +#define TR_INPUT 1 +#define TR_OUTPUT 0 + +// Transceiver control definitions +#define TRANSCEIVER_IO_SET(VPIN,TR_INPUT) { GPIOREG(VPIN)->BSRR = BITMASK(VPIN) << ((TR_INPUT) ? 16 : 0); } + +// Turn on the output only for BSY +#define SCSI_BSY_ACTIVE() { gpio_mode(BSY, GPIO_OUTPUT_PP); SCSI_OUT(vBSY, active) } + +#define SCSI_TARGET_ACTIVE() { gpio_mode(REQ, GPIO_OUTPUT_PP); gpio_mode(MSG, GPIO_OUTPUT_PP); gpio_mode(CD, GPIO_OUTPUT_PP); gpio_mode(IO, GPIO_OUTPUT_PP); gpio_mode(BSY, GPIO_OUTPUT_PP); TRANSCEIVER_IO_SET(vTR_TARGET,TR_OUTPUT);} +// BSY,REQ,MSG,CD,IO Turn off output, BSY is the last input +#define SCSI_TARGET_INACTIVE() { pinMode(REQ, INPUT); pinMode(MSG, INPUT); pinMode(CD, INPUT); pinMode(IO, INPUT); pinMode(BSY, INPUT); TRANSCEIVER_IO_SET(vTR_TARGET,TR_INPUT); } + +#define DB_MODE_OUT 1 // push-pull mode +#define DB_MODE_IN 4 // floating inputs + +#else + // GPIO mode // IN , FLOAT : 4 // IN , PU/PD : 8 @@ -173,11 +205,6 @@ SdFs SD; //#define DB_MODE_OUT 7 #define DB_MODE_IN 8 -// Put DB and DP in output mode -#define SCSI_DB_OUTPUT() { PBREG->CRL=(PBREG->CRL &0xfffffff0)|DB_MODE_OUT; PBREG->CRH = 0x11111111*DB_MODE_OUT; } -// Put DB and DP in input mode -#define SCSI_DB_INPUT() { PBREG->CRL=(PBREG->CRL &0xfffffff0)|DB_MODE_IN ; PBREG->CRH = 0x11111111*DB_MODE_IN; if (DB_MODE_IN == 8) PBREG->BSRR = 0xFF01;} - // Turn on the output only for BSY #define SCSI_BSY_ACTIVE() { gpio_mode(BSY, GPIO_OUTPUT_OD); SCSI_OUT(vBSY, active) } // BSY,REQ,MSG,CD,IO Turn on the output (no change required for OD) @@ -185,6 +212,14 @@ SdFs SD; // BSY,REQ,MSG,CD,IO Turn off output, BSY is the last input #define SCSI_TARGET_INACTIVE() { if (DB_MODE_OUT == 7) SCSI_OUT(vREQ,inactive) else { if (DB_MODE_IN == 8) gpio_mode(REQ, GPIO_INPUT_PU) else gpio_mode(REQ, GPIO_INPUT_FLOATING)} SCSI_PHASE_CHANGE(SCSI_PHASE_DATAOUT); gpio_mode(BSY, GPIO_INPUT_PU); } +#endif + + +// Put DB and DP in output mode +#define SCSI_DB_OUTPUT() { PBREG->CRL=(PBREG->CRL &0xfffffff0)|DB_MODE_OUT; PBREG->CRH = 0x11111111*DB_MODE_OUT; } +// Put DB and DP in input mode +#define SCSI_DB_INPUT() { PBREG->CRL=(PBREG->CRL &0xfffffff0)|DB_MODE_IN ; PBREG->CRH = 0x11111111*DB_MODE_IN; } + // HDDiamge file #define HDIMG_ID_POS 2 // Position to embed ID number #define HDIMG_LUN_POS 3 // Position to embed LUN numbers @@ -416,6 +451,15 @@ void setup() LED_OFF(); +#ifdef XCVR + // Transceiver Pin Initialization + pinMode(TR_TARGET, OUTPUT); + pinMode(TR_INITIATOR, OUTPUT); + pinMode(TR_DBP, OUTPUT); + + TRANSCEIVER_IO_SET(vTR_INITIATOR,TR_INPUT); +#endif + //GPIO(SCSI BUS)Initialization //Port setting register (lower) // GPIOB->regs->CRL |= 0x000000008; // SET INPUT W/ PUPD on PAB-PB0 @@ -425,6 +469,24 @@ void setup() // DB and DP are input modes SCSI_DB_INPUT() +#ifdef XCVR + TRANSCEIVER_IO_SET(vTR_DBP,TR_INPUT); + + // Initiator port + pinMode(ATN, INPUT); + pinMode(BSY, INPUT); + pinMode(ACK, INPUT); + pinMode(RST, INPUT); + pinMode(SEL, INPUT); + TRANSCEIVER_IO_SET(vTR_INITIATOR,TR_INPUT); + + // Target port + pinMode(MSG, INPUT); + pinMode(CD, INPUT); + pinMode(REQ, INPUT); + pinMode(IO, INPUT); + TRANSCEIVER_IO_SET(vTR_TARGET,TR_INPUT); +#else // Input port gpio_mode(ATN, GPIO_INPUT_PU); gpio_mode(BSY, GPIO_INPUT_PU); @@ -438,6 +500,7 @@ void setup() gpio_mode(IO, GPIO_OUTPUT_OD); // Turn off the output port SCSI_TARGET_INACTIVE() +#endif //Occurs when the RST pin state changes from HIGH to LOW //attachInterrupt(RST, onBusReset, FALLING); @@ -788,6 +851,9 @@ inline void writeHandshake(byte d) { // This has a 400ns bus settle delay built in. Not optimal for multi-byte transfers. GPIOB->regs->BSRR = db_bsrr[d]; // setup DB,DBP (160ns) +#ifdef XCVR + TRANSCEIVER_IO_SET(vTR_DBP,TR_OUTPUT) +#endif SCSI_DB_OUTPUT() // (180ns) // ACK.Fall to DB output delay 100ns(MAX) (DTC-510B) SCSI_OUT(vREQ,inactive) // setup wait (30ns) @@ -800,6 +866,9 @@ inline void writeHandshake(byte d) GPIOB->regs->BSRR = DBP(0xff); // DB=0xFF , SCSI_OUT(vREQ,inactive) // REQ.Raise to DB hold time 0ns SCSI_DB_INPUT() // (150ns) +#ifdef XCVR + TRANSCEIVER_IO_SET(vTR_DBP,TR_INPUT) +#endif while( SCSI_IN(vACK)); } @@ -836,6 +905,9 @@ void writeDataLoop(uint32_t blocksize, const byte* srcptr) // Start the first bus cycle. FETCH_BSRR_DB(); REQ_OFF_DB_SET(bsrr_val); +#ifdef XCVR + TRANSCEIVER_IO_SET(vTR_DBP,TR_OUTPUT) +#endif REQ_ON(); FETCH_BSRR_DB(); WAIT_ACK_ACTIVE(); @@ -913,6 +985,9 @@ void writeDataPhaseSD(uint32_t adds, uint32_t len) #endif } SCSI_DB_INPUT() +#ifdef XCVR + TRANSCEIVER_IO_SET(vTR_DBP,TR_INPUT) +#endif } #if WRITE_SPEED_OPTIMIZE @@ -1463,6 +1538,15 @@ void MsgIn2(int msg) */ void loop() { +#ifdef XCVR + // Reset all DB and Target pins, switch transceivers to input + // Precaution against bugs or jumps which don't clean up properly + SCSI_DB_INPUT(); + TRANSCEIVER_IO_SET(vTR_DBP,TR_INPUT) + SCSI_TARGET_INACTIVE(); + TRANSCEIVER_IO_SET(vTR_INITIATOR,TR_INPUT) +#endif + //int msg = 0; m_msg = 0; @@ -1485,6 +1569,7 @@ void loop() goto BusFree; } enableResetJmp(); + // Set BSY to-when selected SCSI_BSY_ACTIVE(); // Turn only BSY output ON, ACTIVE @@ -1494,7 +1579,14 @@ void loop() // Wait until SEL becomes inactive while(isHigh(gpio_read(SEL)) && isLow(gpio_read(BSY))) { } + +#ifdef XCVR + // Reconfigure target pins to output mode, after resetting their values + GPIOB->regs->BSRR = 0x000000E8; // MSG, CD, REQ, IO +// GPIOA->regs->BSRR = 0x00000200; // BSY +#endif SCSI_TARGET_ACTIVE() // (BSY), REQ, MSG, CD, IO output turned on + // if(isHigh(gpio_read(ATN))) { SCSI_PHASE_CHANGE(SCSI_PHASE_MESSAGEOUT); @@ -1703,4 +1795,7 @@ BusFree: //SCSI_OUT(vIO ,inactive) // gpio_write(IO, low); //SCSI_OUT(vBSY,inactive) SCSI_TARGET_INACTIVE() // Turn off BSY, REQ, MSG, CD, IO output +#ifdef XCVR + TRANSCEIVER_IO_SET(vTR_TARGET,TR_INPUT); +#endif }