Browse Source

Merge pull request #92 from erichelgeson/XCVR

Code for Transceiver Hardware
Eric Helgeson 3 years ago
parent
commit
aa751dc3b8
2 changed files with 117 additions and 21 deletions
  1. 14 13
      platformio.ini
  2. 103 8
      src/BlueSCSI.cpp

+ 14 - 13
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

+ 103 - 8
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
 }