mirror of
https://github.com/erichelgeson/BlueSCSI.git
synced 2025-01-10 17:30:25 +00:00
Merge pull request #92 from erichelgeson/XCVR
Code for Transceiver Hardware
This commit is contained in:
commit
aa751dc3b8
@ -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
|
||||
|
111
src/BlueSCSI.cpp
111
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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user