mirror of
https://github.com/dkgrizzly/GreenSCSI.git
synced 2024-06-13 17:29:35 +00:00
Compare commits
12 Commits
v1.0-20220
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
8012d85d23 | ||
|
a09d5dbf13 | ||
|
d420244da9 | ||
|
c5c4c51667 | ||
|
bc114096ac | ||
|
41455971d4 | ||
|
1205f4ad6e | ||
|
382052a5a0 | ||
|
1714acb3a2 | ||
|
8d84bc8ece | ||
|
0abf96bd82 | ||
|
4ab58d0fff |
BIN
GreenSCSI Manual.pdf
Normal file
BIN
GreenSCSI Manual.pdf
Normal file
Binary file not shown.
10
README.md
10
README.md
|
@ -2,15 +2,15 @@
|
|||
![DeadBug assembly of a Teensy 3.5 directly on a 50 pin SCSI header!](/GreenSCSI-DeadBug.jpg "GreenSCSI Teensy 3.5 Dead Bug")
|
||||
|
||||
|
||||
GreenSCSI, BlueSCSI & ArdSCSino are hardware that reproduces SCSI devices (hard disks) with Arduino like devices.
|
||||
GreenSCSI, BlueSCSI & ArdSCSino are hardware that reproduce SCSI devices (hard disks) with Arduino like devices.
|
||||
|
||||
`GreenSCSI` created by https://github.com/dkgrizzly[dkgrizzly] is a fork of `BlueSCSI` which adds:
|
||||
`GreenSCSI` created by https://github.com/dkgrizzly [dkgrizzly] is a fork of `BlueSCSI` which adds:
|
||||
|
||||
* Teensy 3.5 (Kinetis K64...) support
|
||||
* Better LUN handling
|
||||
|
||||
`BlueSCSI` created by https://github.com/erichelgeson[erichelgeson] is a fork of `ArdSCSino-stm32`
|
||||
`BlueSCSI` created by https://github.com/erichelgeson [erichelgeson] is a fork of `ArdSCSino-stm32`
|
||||
|
||||
`ArdSCSino-stm32` created by https://github.com/ztto/ArdSCSino-stm32[ztto] is the STM32 version of `ArdSCSino`
|
||||
`ArdSCSino-stm32` created by https://github.com/ztto/ArdSCSino-stm32 [ztto] is the STM32 version of `ArdSCSino`
|
||||
|
||||
`ArdSCSino` created by https://twitter.com/h_koma2[Tambo (TNB Seisakusho)]
|
||||
`ArdSCSino` created by https://twitter.com/h_koma2 [Tambo (TNB Seisakusho)]
|
||||
|
|
4202
case/GreenSCSI-bottom.stl
Normal file
4202
case/GreenSCSI-bottom.stl
Normal file
File diff suppressed because it is too large
Load Diff
1402
case/GreenSCSI-top.stl
Normal file
1402
case/GreenSCSI-top.stl
Normal file
File diff suppressed because it is too large
Load Diff
220
hardware/mvp/GreenSCSI-cache.lib
Normal file
220
hardware/mvp/GreenSCSI-cache.lib
Normal file
|
@ -0,0 +1,220 @@
|
|||
EESchema-LIBRARY Version 2.4
|
||||
#encoding utf-8
|
||||
#
|
||||
# Connector_Generic_Conn_01x02
|
||||
#
|
||||
DEF Connector_Generic_Conn_01x02 J 0 40 Y N 1 F N
|
||||
F0 "J" 0 100 50 H V C CNN
|
||||
F1 "Connector_Generic_Conn_01x02" 0 -200 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
Connector*:*_1x??_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -50 -95 0 -105 1 1 6 N
|
||||
S -50 5 0 -5 1 1 6 N
|
||||
S -50 50 50 -150 1 1 10 f
|
||||
X Pin_1 1 -200 0 150 R 50 50 1 1 P
|
||||
X Pin_2 2 -200 -100 150 R 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Connector_Generic_Conn_01x04
|
||||
#
|
||||
DEF Connector_Generic_Conn_01x04 J 0 40 Y N 1 F N
|
||||
F0 "J" 0 200 50 H V C CNN
|
||||
F1 "Connector_Generic_Conn_01x04" 0 -300 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
Connector*:*_1x??_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -50 -195 0 -205 1 1 6 N
|
||||
S -50 -95 0 -105 1 1 6 N
|
||||
S -50 5 0 -5 1 1 6 N
|
||||
S -50 105 0 95 1 1 6 N
|
||||
S -50 150 50 -250 1 1 10 f
|
||||
X Pin_1 1 -200 100 150 R 50 50 1 1 P
|
||||
X Pin_2 2 -200 0 150 R 50 50 1 1 P
|
||||
X Pin_3 3 -200 -100 150 R 50 50 1 1 P
|
||||
X Pin_4 4 -200 -200 150 R 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Connector_Generic_Conn_01x22
|
||||
#
|
||||
DEF Connector_Generic_Conn_01x22 J 0 40 Y N 1 F N
|
||||
F0 "J" 0 1100 50 H V C CNN
|
||||
F1 "Connector_Generic_Conn_01x22" 0 -1200 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
Connector*:*_1x??_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -50 -1095 0 -1105 1 1 6 N
|
||||
S -50 -995 0 -1005 1 1 6 N
|
||||
S -50 -895 0 -905 1 1 6 N
|
||||
S -50 -795 0 -805 1 1 6 N
|
||||
S -50 -695 0 -705 1 1 6 N
|
||||
S -50 -595 0 -605 1 1 6 N
|
||||
S -50 -495 0 -505 1 1 6 N
|
||||
S -50 -395 0 -405 1 1 6 N
|
||||
S -50 -295 0 -305 1 1 6 N
|
||||
S -50 -195 0 -205 1 1 6 N
|
||||
S -50 -95 0 -105 1 1 6 N
|
||||
S -50 5 0 -5 1 1 6 N
|
||||
S -50 105 0 95 1 1 6 N
|
||||
S -50 205 0 195 1 1 6 N
|
||||
S -50 305 0 295 1 1 6 N
|
||||
S -50 405 0 395 1 1 6 N
|
||||
S -50 505 0 495 1 1 6 N
|
||||
S -50 605 0 595 1 1 6 N
|
||||
S -50 705 0 695 1 1 6 N
|
||||
S -50 805 0 795 1 1 6 N
|
||||
S -50 905 0 895 1 1 6 N
|
||||
S -50 1005 0 995 1 1 6 N
|
||||
S -50 1050 50 -1150 1 1 10 f
|
||||
X Pin_1 1 -200 1000 150 R 50 50 1 1 P
|
||||
X Pin_10 10 -200 100 150 R 50 50 1 1 P
|
||||
X Pin_11 11 -200 0 150 R 50 50 1 1 P
|
||||
X Pin_12 12 -200 -100 150 R 50 50 1 1 P
|
||||
X Pin_13 13 -200 -200 150 R 50 50 1 1 P
|
||||
X Pin_14 14 -200 -300 150 R 50 50 1 1 P
|
||||
X Pin_15 15 -200 -400 150 R 50 50 1 1 P
|
||||
X Pin_16 16 -200 -500 150 R 50 50 1 1 P
|
||||
X Pin_17 17 -200 -600 150 R 50 50 1 1 P
|
||||
X Pin_18 18 -200 -700 150 R 50 50 1 1 P
|
||||
X Pin_19 19 -200 -800 150 R 50 50 1 1 P
|
||||
X Pin_2 2 -200 900 150 R 50 50 1 1 P
|
||||
X Pin_20 20 -200 -900 150 R 50 50 1 1 P
|
||||
X Pin_21 21 -200 -1000 150 R 50 50 1 1 P
|
||||
X Pin_22 22 -200 -1100 150 R 50 50 1 1 P
|
||||
X Pin_3 3 -200 800 150 R 50 50 1 1 P
|
||||
X Pin_4 4 -200 700 150 R 50 50 1 1 P
|
||||
X Pin_5 5 -200 600 150 R 50 50 1 1 P
|
||||
X Pin_6 6 -200 500 150 R 50 50 1 1 P
|
||||
X Pin_7 7 -200 400 150 R 50 50 1 1 P
|
||||
X Pin_8 8 -200 300 150 R 50 50 1 1 P
|
||||
X Pin_9 9 -200 200 150 R 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Connector_Generic_Conn_02x25_Odd_Even
|
||||
#
|
||||
DEF Connector_Generic_Conn_02x25_Odd_Even J 0 40 Y N 1 F N
|
||||
F0 "J" 50 1300 50 H V C CNN
|
||||
F1 "Connector_Generic_Conn_02x25_Odd_Even" 50 -1300 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
Connector*:*_2x??_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -50 -1195 0 -1205 1 1 6 N
|
||||
S -50 -1095 0 -1105 1 1 6 N
|
||||
S -50 -995 0 -1005 1 1 6 N
|
||||
S -50 -895 0 -905 1 1 6 N
|
||||
S -50 -795 0 -805 1 1 6 N
|
||||
S -50 -695 0 -705 1 1 6 N
|
||||
S -50 -595 0 -605 1 1 6 N
|
||||
S -50 -495 0 -505 1 1 6 N
|
||||
S -50 -395 0 -405 1 1 6 N
|
||||
S -50 -295 0 -305 1 1 6 N
|
||||
S -50 -195 0 -205 1 1 6 N
|
||||
S -50 -95 0 -105 1 1 6 N
|
||||
S -50 5 0 -5 1 1 6 N
|
||||
S -50 105 0 95 1 1 6 N
|
||||
S -50 205 0 195 1 1 6 N
|
||||
S -50 305 0 295 1 1 6 N
|
||||
S -50 405 0 395 1 1 6 N
|
||||
S -50 505 0 495 1 1 6 N
|
||||
S -50 605 0 595 1 1 6 N
|
||||
S -50 705 0 695 1 1 6 N
|
||||
S -50 805 0 795 1 1 6 N
|
||||
S -50 905 0 895 1 1 6 N
|
||||
S -50 1005 0 995 1 1 6 N
|
||||
S -50 1105 0 1095 1 1 6 N
|
||||
S -50 1205 0 1195 1 1 6 N
|
||||
S -50 1250 150 -1250 1 1 10 f
|
||||
S 150 -1195 100 -1205 1 1 6 N
|
||||
S 150 -1095 100 -1105 1 1 6 N
|
||||
S 150 -995 100 -1005 1 1 6 N
|
||||
S 150 -895 100 -905 1 1 6 N
|
||||
S 150 -795 100 -805 1 1 6 N
|
||||
S 150 -695 100 -705 1 1 6 N
|
||||
S 150 -595 100 -605 1 1 6 N
|
||||
S 150 -495 100 -505 1 1 6 N
|
||||
S 150 -395 100 -405 1 1 6 N
|
||||
S 150 -295 100 -305 1 1 6 N
|
||||
S 150 -195 100 -205 1 1 6 N
|
||||
S 150 -95 100 -105 1 1 6 N
|
||||
S 150 5 100 -5 1 1 6 N
|
||||
S 150 105 100 95 1 1 6 N
|
||||
S 150 205 100 195 1 1 6 N
|
||||
S 150 305 100 295 1 1 6 N
|
||||
S 150 405 100 395 1 1 6 N
|
||||
S 150 505 100 495 1 1 6 N
|
||||
S 150 605 100 595 1 1 6 N
|
||||
S 150 705 100 695 1 1 6 N
|
||||
S 150 805 100 795 1 1 6 N
|
||||
S 150 905 100 895 1 1 6 N
|
||||
S 150 1005 100 995 1 1 6 N
|
||||
S 150 1105 100 1095 1 1 6 N
|
||||
S 150 1205 100 1195 1 1 6 N
|
||||
X Pin_1 1 -200 1200 150 R 50 50 1 1 P
|
||||
X Pin_10 10 300 800 150 L 50 50 1 1 P
|
||||
X Pin_11 11 -200 700 150 R 50 50 1 1 P
|
||||
X Pin_12 12 300 700 150 L 50 50 1 1 P
|
||||
X Pin_13 13 -200 600 150 R 50 50 1 1 P
|
||||
X Pin_14 14 300 600 150 L 50 50 1 1 P
|
||||
X Pin_15 15 -200 500 150 R 50 50 1 1 P
|
||||
X Pin_16 16 300 500 150 L 50 50 1 1 P
|
||||
X Pin_17 17 -200 400 150 R 50 50 1 1 P
|
||||
X Pin_18 18 300 400 150 L 50 50 1 1 P
|
||||
X Pin_19 19 -200 300 150 R 50 50 1 1 P
|
||||
X Pin_2 2 300 1200 150 L 50 50 1 1 P
|
||||
X Pin_20 20 300 300 150 L 50 50 1 1 P
|
||||
X Pin_21 21 -200 200 150 R 50 50 1 1 P
|
||||
X Pin_22 22 300 200 150 L 50 50 1 1 P
|
||||
X Pin_23 23 -200 100 150 R 50 50 1 1 P
|
||||
X Pin_24 24 300 100 150 L 50 50 1 1 P
|
||||
X Pin_25 25 -200 0 150 R 50 50 1 1 P
|
||||
X Pin_26 26 300 0 150 L 50 50 1 1 P
|
||||
X Pin_27 27 -200 -100 150 R 50 50 1 1 P
|
||||
X Pin_28 28 300 -100 150 L 50 50 1 1 P
|
||||
X Pin_29 29 -200 -200 150 R 50 50 1 1 P
|
||||
X Pin_3 3 -200 1100 150 R 50 50 1 1 P
|
||||
X Pin_30 30 300 -200 150 L 50 50 1 1 P
|
||||
X Pin_31 31 -200 -300 150 R 50 50 1 1 P
|
||||
X Pin_32 32 300 -300 150 L 50 50 1 1 P
|
||||
X Pin_33 33 -200 -400 150 R 50 50 1 1 P
|
||||
X Pin_34 34 300 -400 150 L 50 50 1 1 P
|
||||
X Pin_35 35 -200 -500 150 R 50 50 1 1 P
|
||||
X Pin_36 36 300 -500 150 L 50 50 1 1 P
|
||||
X Pin_37 37 -200 -600 150 R 50 50 1 1 P
|
||||
X Pin_38 38 300 -600 150 L 50 50 1 1 P
|
||||
X Pin_39 39 -200 -700 150 R 50 50 1 1 P
|
||||
X Pin_4 4 300 1100 150 L 50 50 1 1 P
|
||||
X Pin_40 40 300 -700 150 L 50 50 1 1 P
|
||||
X Pin_41 41 -200 -800 150 R 50 50 1 1 P
|
||||
X Pin_42 42 300 -800 150 L 50 50 1 1 P
|
||||
X Pin_43 43 -200 -900 150 R 50 50 1 1 P
|
||||
X Pin_44 44 300 -900 150 L 50 50 1 1 P
|
||||
X Pin_45 45 -200 -1000 150 R 50 50 1 1 P
|
||||
X Pin_46 46 300 -1000 150 L 50 50 1 1 P
|
||||
X Pin_47 47 -200 -1100 150 R 50 50 1 1 P
|
||||
X Pin_48 48 300 -1100 150 L 50 50 1 1 P
|
||||
X Pin_49 49 -200 -1200 150 R 50 50 1 1 P
|
||||
X Pin_5 5 -200 1000 150 R 50 50 1 1 P
|
||||
X Pin_50 50 300 -1200 150 L 50 50 1 1 P
|
||||
X Pin_6 6 300 1000 150 L 50 50 1 1 P
|
||||
X Pin_7 7 -200 900 150 R 50 50 1 1 P
|
||||
X Pin_8 8 300 900 150 L 50 50 1 1 P
|
||||
X Pin_9 9 -200 800 150 R 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
#End Library
|
2038
hardware/mvp/GreenSCSI.kicad_pcb
Normal file
2038
hardware/mvp/GreenSCSI.kicad_pcb
Normal file
File diff suppressed because it is too large
Load Diff
33
hardware/mvp/GreenSCSI.pro
Normal file
33
hardware/mvp/GreenSCSI.pro
Normal file
|
@ -0,0 +1,33 @@
|
|||
update=22/05/2015 07:44:53
|
||||
version=1
|
||||
last_client=kicad
|
||||
[general]
|
||||
version=1
|
||||
RootSch=
|
||||
BoardNm=
|
||||
[pcbnew]
|
||||
version=1
|
||||
LastNetListRead=
|
||||
UseCmpFile=1
|
||||
PadDrill=0.600000000000
|
||||
PadDrillOvalY=0.600000000000
|
||||
PadSizeH=1.500000000000
|
||||
PadSizeV=1.500000000000
|
||||
PcbTextSizeV=1.500000000000
|
||||
PcbTextSizeH=1.500000000000
|
||||
PcbTextThickness=0.300000000000
|
||||
ModuleTextSizeV=1.000000000000
|
||||
ModuleTextSizeH=1.000000000000
|
||||
ModuleTextSizeThickness=0.150000000000
|
||||
SolderMaskClearance=0.000000000000
|
||||
SolderMaskMinWidth=0.000000000000
|
||||
DrawSegmentWidth=0.200000000000
|
||||
BoardOutlineThickness=0.100000000000
|
||||
ModuleOutlineThickness=0.150000000000
|
||||
[cvpcb]
|
||||
version=1
|
||||
NetIExt=net
|
||||
[eeschema]
|
||||
version=1
|
||||
LibDir=
|
||||
[eeschema/libraries]
|
374
hardware/mvp/GreenSCSI.sch
Normal file
374
hardware/mvp/GreenSCSI.sch
Normal file
|
@ -0,0 +1,374 @@
|
|||
EESchema Schematic File Version 4
|
||||
EELAYER 30 0
|
||||
EELAYER END
|
||||
$Descr A4 11693 8268
|
||||
encoding utf-8
|
||||
Sheet 1 1
|
||||
Title ""
|
||||
Date ""
|
||||
Rev ""
|
||||
Comp ""
|
||||
Comment1 ""
|
||||
Comment2 ""
|
||||
Comment3 ""
|
||||
Comment4 ""
|
||||
$EndDescr
|
||||
$Comp
|
||||
L Connector_Generic:Conn_02x25_Odd_Even P4
|
||||
U 1 1 61981AC2
|
||||
P 2900 4150
|
||||
F 0 "P4" H 2950 5567 50 0000 C CNN
|
||||
F 1 "SCSI" H 2950 5476 50 0000 C CNN
|
||||
F 2 "Connector_PinHeader_2.54mm:PinHeader_2x25_P2.54mm_Horizontal" H 2900 4150 50 0001 C CNN
|
||||
F 3 "~" H 2900 4150 50 0001 C CNN
|
||||
1 2900 4150
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Connector_Generic:Conn_01x04 P3
|
||||
U 1 1 6198359E
|
||||
P 7950 4800
|
||||
F 0 "P3" H 7950 5050 50 0000 C CNN
|
||||
F 1 "Teensy" H 7950 4450 50 0000 C CNN
|
||||
F 2 "Connector_PinHeader_2.54mm:PinHeader_1x04_P2.54mm_Vertical" H 7950 4800 50 0001 C CNN
|
||||
F 3 "~" H 7950 4800 50 0001 C CNN
|
||||
1 7950 4800
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Connector_Generic:Conn_01x22 P1
|
||||
U 1 1 61983D48
|
||||
P 6700 4100
|
||||
F 0 "P1" H 6700 5250 50 0000 C CNN
|
||||
F 1 "Teensy" H 6700 2850 50 0000 C CNN
|
||||
F 2 "Connector_PinHeader_2.54mm:PinHeader_1x22_P2.54mm_Vertical" H 6700 4100 50 0001 C CNN
|
||||
F 3 "~" H 6700 4100 50 0001 C CNN
|
||||
1 6700 4100
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Connector_Generic:Conn_01x22 P2
|
||||
U 1 1 61984761
|
||||
P 8250 4100
|
||||
F 0 "P2" H 8250 5250 50 0000 C CNN
|
||||
F 1 "Teensy" H 8250 2850 50 0000 C CNN
|
||||
F 2 "Connector_PinHeader_2.54mm:PinHeader_1x22_P2.54mm_Vertical" H 8250 4100 50 0001 C CNN
|
||||
F 3 "~" H 8250 4100 50 0001 C CNN
|
||||
1 8250 4100
|
||||
-1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
2700 2950 2450 2950
|
||||
Wire Wire Line
|
||||
2450 2950 2450 3050
|
||||
Wire Wire Line
|
||||
2450 4050 2700 4050
|
||||
Wire Wire Line
|
||||
2700 4250 2450 4250
|
||||
Wire Wire Line
|
||||
2450 4250 2450 4350
|
||||
Wire Wire Line
|
||||
2450 5350 2700 5350
|
||||
Wire Wire Line
|
||||
2700 5250 2450 5250
|
||||
Connection ~ 2450 5250
|
||||
Wire Wire Line
|
||||
2450 5250 2450 5350
|
||||
Wire Wire Line
|
||||
2700 5150 2450 5150
|
||||
Connection ~ 2450 5150
|
||||
Wire Wire Line
|
||||
2450 5150 2450 5250
|
||||
Wire Wire Line
|
||||
2700 5050 2450 5050
|
||||
Connection ~ 2450 5050
|
||||
Wire Wire Line
|
||||
2450 5050 2450 5150
|
||||
Wire Wire Line
|
||||
2700 4950 2450 4950
|
||||
Connection ~ 2450 4950
|
||||
Wire Wire Line
|
||||
2450 4950 2450 5050
|
||||
Wire Wire Line
|
||||
2700 4850 2450 4850
|
||||
Connection ~ 2450 4850
|
||||
Wire Wire Line
|
||||
2450 4850 2450 4950
|
||||
Wire Wire Line
|
||||
2700 4750 2450 4750
|
||||
Connection ~ 2450 4750
|
||||
Wire Wire Line
|
||||
2450 4750 2450 4850
|
||||
Wire Wire Line
|
||||
2700 4650 2450 4650
|
||||
Connection ~ 2450 4650
|
||||
Wire Wire Line
|
||||
2450 4650 2450 4750
|
||||
Wire Wire Line
|
||||
2700 4550 2450 4550
|
||||
Connection ~ 2450 4550
|
||||
Wire Wire Line
|
||||
2450 4550 2450 4650
|
||||
Wire Wire Line
|
||||
2700 4450 2450 4450
|
||||
Connection ~ 2450 4450
|
||||
Wire Wire Line
|
||||
2450 4450 2450 4550
|
||||
Wire Wire Line
|
||||
2700 4350 2450 4350
|
||||
Connection ~ 2450 4350
|
||||
Wire Wire Line
|
||||
2450 4350 2450 4450
|
||||
Wire Wire Line
|
||||
2700 3050 2450 3050
|
||||
Connection ~ 2450 3050
|
||||
Wire Wire Line
|
||||
2450 3050 2450 3150
|
||||
Wire Wire Line
|
||||
2700 3150 2450 3150
|
||||
Connection ~ 2450 3150
|
||||
Wire Wire Line
|
||||
2450 3150 2450 3250
|
||||
Wire Wire Line
|
||||
2700 3250 2450 3250
|
||||
Connection ~ 2450 3250
|
||||
Wire Wire Line
|
||||
2450 3250 2450 3350
|
||||
Wire Wire Line
|
||||
2700 3350 2450 3350
|
||||
Connection ~ 2450 3350
|
||||
Wire Wire Line
|
||||
2450 3350 2450 3450
|
||||
Wire Wire Line
|
||||
2700 3450 2450 3450
|
||||
Connection ~ 2450 3450
|
||||
Wire Wire Line
|
||||
2450 3450 2450 3550
|
||||
Wire Wire Line
|
||||
2700 3550 2450 3550
|
||||
Connection ~ 2450 3550
|
||||
Wire Wire Line
|
||||
2450 3550 2450 3650
|
||||
Wire Wire Line
|
||||
2700 3650 2450 3650
|
||||
Connection ~ 2450 3650
|
||||
Wire Wire Line
|
||||
2450 3650 2450 3750
|
||||
Wire Wire Line
|
||||
2700 3750 2450 3750
|
||||
Connection ~ 2450 3750
|
||||
Wire Wire Line
|
||||
2450 3750 2450 3850
|
||||
Wire Wire Line
|
||||
2700 3850 2450 3850
|
||||
Connection ~ 2450 3850
|
||||
Wire Wire Line
|
||||
2450 3850 2450 3950
|
||||
Wire Wire Line
|
||||
2700 3950 2450 3950
|
||||
Connection ~ 2450 3950
|
||||
Wire Wire Line
|
||||
2450 3950 2450 4050
|
||||
Wire Wire Line
|
||||
2150 4150 2700 4150
|
||||
Wire Wire Line
|
||||
3200 2950 3750 2950
|
||||
Wire Wire Line
|
||||
3200 3050 3750 3050
|
||||
Wire Wire Line
|
||||
3200 3150 3750 3150
|
||||
Wire Wire Line
|
||||
3200 3250 3750 3250
|
||||
Wire Wire Line
|
||||
3200 3350 3750 3350
|
||||
Wire Wire Line
|
||||
3200 3450 3750 3450
|
||||
Wire Wire Line
|
||||
3200 3550 3750 3550
|
||||
Wire Wire Line
|
||||
3200 3650 3750 3650
|
||||
Wire Wire Line
|
||||
3200 3750 3750 3750
|
||||
Wire Wire Line
|
||||
3200 5350 3750 5350
|
||||
Wire Wire Line
|
||||
3200 5250 3750 5250
|
||||
Wire Wire Line
|
||||
3200 5150 3750 5150
|
||||
Wire Wire Line
|
||||
3200 5050 3750 5050
|
||||
Wire Wire Line
|
||||
3200 4950 3750 4950
|
||||
Wire Wire Line
|
||||
3200 4850 3750 4850
|
||||
Wire Wire Line
|
||||
3200 4750 3750 4750
|
||||
Wire Wire Line
|
||||
3200 4650 3750 4650
|
||||
Wire Wire Line
|
||||
3200 4450 3750 4450
|
||||
Wire Wire Line
|
||||
3450 4350 3200 4350
|
||||
Wire Wire Line
|
||||
3450 3850 3200 3850
|
||||
Wire Wire Line
|
||||
3450 3950 3200 3950
|
||||
Wire Wire Line
|
||||
3450 4050 3200 4050
|
||||
Wire Wire Line
|
||||
3450 4250 3200 4250
|
||||
Wire Wire Line
|
||||
3450 4350 3450 4250
|
||||
Wire Wire Line
|
||||
3450 4250 3450 4050
|
||||
Connection ~ 3450 4250
|
||||
Wire Wire Line
|
||||
3450 4050 3450 3950
|
||||
Connection ~ 3450 4050
|
||||
Wire Wire Line
|
||||
3450 3950 3450 3850
|
||||
Connection ~ 3450 3950
|
||||
Text Label 2500 4050 0 50 ~ 0
|
||||
GND
|
||||
Text Label 2500 5350 0 50 ~ 0
|
||||
GND
|
||||
Text Label 3250 4050 0 50 ~ 0
|
||||
GND
|
||||
Text Label 2150 4150 0 50 ~ 0
|
||||
TERMPWR
|
||||
Text Label 3750 2950 2 50 ~ 0
|
||||
~DB0
|
||||
Text Label 3750 3050 2 50 ~ 0
|
||||
~DB1
|
||||
Text Label 3750 3150 2 50 ~ 0
|
||||
~DB2
|
||||
Text Label 3750 3250 2 50 ~ 0
|
||||
~DB3
|
||||
Text Label 3750 3350 2 50 ~ 0
|
||||
~DB4
|
||||
Text Label 3750 3450 2 50 ~ 0
|
||||
~DB5
|
||||
Text Label 3750 3550 2 50 ~ 0
|
||||
~DB6
|
||||
Text Label 3750 3650 2 50 ~ 0
|
||||
~DB7
|
||||
Text Label 3750 3750 2 50 ~ 0
|
||||
~DBP
|
||||
Text Label 3750 4450 2 50 ~ 0
|
||||
~ATN
|
||||
Text Label 3750 4650 2 50 ~ 0
|
||||
~BSY
|
||||
Text Label 3750 4750 2 50 ~ 0
|
||||
~ACK
|
||||
Text Label 3750 4850 2 50 ~ 0
|
||||
~RST
|
||||
Text Label 3750 4950 2 50 ~ 0
|
||||
~MSG
|
||||
Text Label 3750 5050 2 50 ~ 0
|
||||
~SEL
|
||||
Text Label 3750 5150 2 50 ~ 0
|
||||
~C~\D
|
||||
Text Label 3750 5250 2 50 ~ 0
|
||||
~REQ
|
||||
Text Label 3750 5350 2 50 ~ 0
|
||||
~I~\O
|
||||
Wire Wire Line
|
||||
6500 3500 5950 3500
|
||||
Wire Wire Line
|
||||
6500 3600 5950 3600
|
||||
Wire Wire Line
|
||||
6500 3700 5950 3700
|
||||
Wire Wire Line
|
||||
6500 3800 5950 3800
|
||||
Wire Wire Line
|
||||
6500 3900 5950 3900
|
||||
Wire Wire Line
|
||||
6500 4000 5950 4000
|
||||
Wire Wire Line
|
||||
6500 4100 5950 4100
|
||||
Wire Wire Line
|
||||
6500 4200 5950 4200
|
||||
Wire Wire Line
|
||||
6500 4400 5950 4400
|
||||
Text Label 5950 4400 0 50 ~ 0
|
||||
~ATN
|
||||
Text Label 5950 4200 0 50 ~ 0
|
||||
~BSY
|
||||
Text Label 5950 4100 0 50 ~ 0
|
||||
~ACK
|
||||
Text Label 5950 4000 0 50 ~ 0
|
||||
~RST
|
||||
Text Label 5950 3900 0 50 ~ 0
|
||||
~MSG
|
||||
Text Label 5950 3800 0 50 ~ 0
|
||||
~SEL
|
||||
Text Label 5950 3700 0 50 ~ 0
|
||||
~C~\D
|
||||
Text Label 5950 3600 0 50 ~ 0
|
||||
~REQ
|
||||
Text Label 5950 3500 0 50 ~ 0
|
||||
~I~\O
|
||||
Wire Wire Line
|
||||
6500 3100 5950 3100
|
||||
Text Label 5950 3100 0 50 ~ 0
|
||||
GND
|
||||
Wire Wire Line
|
||||
6500 3200 5950 3200
|
||||
Wire Wire Line
|
||||
6500 3300 5950 3300
|
||||
Text Label 5950 3200 0 50 ~ 0
|
||||
~DB0
|
||||
Text Label 5950 3300 0 50 ~ 0
|
||||
~DB1
|
||||
Wire Wire Line
|
||||
6500 4900 5950 4900
|
||||
Wire Wire Line
|
||||
6500 5000 5950 5000
|
||||
Text Label 5950 4900 0 50 ~ 0
|
||||
~DB2
|
||||
Text Label 5950 5000 0 50 ~ 0
|
||||
~DB3
|
||||
Wire Wire Line
|
||||
6500 5200 5950 5200
|
||||
Text Label 5950 5200 0 50 ~ 0
|
||||
~DBP
|
||||
Wire Wire Line
|
||||
7750 4700 7200 4700
|
||||
Wire Wire Line
|
||||
7750 5000 7200 5000
|
||||
Wire Wire Line
|
||||
7750 4800 7200 4800
|
||||
Wire Wire Line
|
||||
7750 4900 7200 4900
|
||||
Text Label 7200 4700 0 50 ~ 0
|
||||
~DB4
|
||||
Text Label 7200 5000 0 50 ~ 0
|
||||
~DB5
|
||||
Text Label 7200 4800 0 50 ~ 0
|
||||
~DB6
|
||||
Text Label 7200 4900 0 50 ~ 0
|
||||
~DB7
|
||||
$Comp
|
||||
L Connector_Generic:Conn_01x02 J1
|
||||
U 1 1 619D027D
|
||||
P 6700 2150
|
||||
F 0 "J1" H 6780 2142 50 0000 L CNN
|
||||
F 1 "Conn_01x02" H 6780 2051 50 0000 L CNN
|
||||
F 2 "Connector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_Vertical" H 6700 2150 50 0001 C CNN
|
||||
F 3 "~" H 6700 2150 50 0001 C CNN
|
||||
1 6700 2150
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
5950 2150 6500 2150
|
||||
Text Label 5950 2150 0 50 ~ 0
|
||||
TERMPWR
|
||||
Wire Wire Line
|
||||
5950 2250 6500 2250
|
||||
Text Label 5950 2250 0 50 ~ 0
|
||||
+5V
|
||||
Wire Wire Line
|
||||
9000 3100 8450 3100
|
||||
Text Label 9000 3100 2 50 ~ 0
|
||||
+5V
|
||||
$EndSCHEMATC
|
BIN
hardware/mvp/GreenSCSI_MVP_Gerbers.zip
Normal file
BIN
hardware/mvp/GreenSCSI_MVP_Gerbers.zip
Normal file
Binary file not shown.
BIN
hardware/mvp/Schematic.pdf
Normal file
BIN
hardware/mvp/Schematic.pdf
Normal file
Binary file not shown.
1947
hardware/mvp/fp-info-cache
Normal file
1947
hardware/mvp/fp-info-cache
Normal file
File diff suppressed because it is too large
Load Diff
321
src/cmd.ino
321
src/cmd.ino
|
@ -24,6 +24,7 @@ int scriptlevel = -1;
|
|||
char cmd_prefix[256] = "/";
|
||||
|
||||
extern uint8_t mbr_bin[];
|
||||
uint8_t zero[512];
|
||||
|
||||
void cmdDisplay() {
|
||||
if(cmd_prefix[0] != 0) {
|
||||
|
@ -723,7 +724,7 @@ void changeDirectory(int argc, char **argv) {
|
|||
goto e_invalidpath;
|
||||
}
|
||||
|
||||
if(!strcmp(new_prefix, "/") || !strcmp(new_prefix, "/tgts") || !strcmp(new_prefix, "/vdevs")
|
||||
if(!strcmp(new_prefix, "/") || !strcmp(new_prefix, "/tgts") || !strcmp(new_prefix, "/vdevs") || !strcmp(new_prefix, "/nv") || !strcmp(new_prefix, "/raw")
|
||||
|| !strcmp(new_prefix, "/sd") || !strcmp(new_prefix, "/diag")|| !strcmp(new_prefix, "/diag/sd")
|
||||
) {
|
||||
strcpy(cmd_prefix, new_prefix);
|
||||
|
@ -863,6 +864,7 @@ void showDirectory(int argc, char **argv) {
|
|||
printDirectory(0, 0, "/ ", " [...]");
|
||||
printDirectory(1, 0, "diag/ ", " [...]");
|
||||
printDirectory(1, 0, "sd/ ", " [...]");
|
||||
printDirectory(1, 0, "raw/ ", " [...]");
|
||||
sprintf(tmp_right, " [%d Target%s]", NUM_SCSIID, (NUM_SCSIID != 1) ? "s" : "");
|
||||
printDirectory(1, 0, "tgts/ ", tmp_right);
|
||||
sprintf(tmp_right, " [%d Storage Object%s]", m_vdevcnt, (m_vdevcnt != 1) ? "s" : "");
|
||||
|
@ -874,6 +876,33 @@ void showDirectory(int argc, char **argv) {
|
|||
printDirectory(1, 0, "sd/ ", " [...]");
|
||||
return;
|
||||
}
|
||||
if(!strcmp(local_prefix, "/raw")) {
|
||||
mbr_t *mbr = (mbr_t *)cardMBR;
|
||||
printDirectory(0, 0, "/raw/ ", " [...]");
|
||||
|
||||
sd.card()->readSector(0, cardMBR);
|
||||
|
||||
for(uint8_t partIndex = 0; partIndex < 4; partIndex++) {
|
||||
sprintf(tmp_left, "part%d", partIndex);
|
||||
switch(mbr->part[partIndex].type) {
|
||||
case 0x04:
|
||||
case 0x06:
|
||||
case 0x0B:
|
||||
case 0x0C:
|
||||
case 0x0E:
|
||||
printDirectory(1, 0, tmp_left, "[FAT Filesystem]");
|
||||
break;
|
||||
case 0x07:
|
||||
printDirectory(1, 0, tmp_left, "[EXFAT/NTFS Filesystem]");
|
||||
break;
|
||||
case 0x87:
|
||||
sprintf(tmp_right, "[Emulated %dMB Drive]", (int)(mbr->part[partIndex].totalSectors / 2048));
|
||||
printDirectory(1, 0, tmp_left, tmp_right);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(!strcmp(local_prefix, "/diag/sd")) {
|
||||
printDirectory(0, 0, "/diag/sd/ ", " [...]");
|
||||
|
||||
|
@ -996,6 +1025,31 @@ void showDirectory(int argc, char **argv) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
if(!strcmp(local_prefix, "/nv") || !strncmp(local_prefix, "/nv/", 4)) {
|
||||
File root = lfs.open("/");
|
||||
while(true) {
|
||||
File entry = root.openNextFile();
|
||||
|
||||
if(! entry) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(!entry.isDirectory()) {
|
||||
sprintf(tmp_left, "%s ", entry.name());
|
||||
if(entry.size() >= 8192) {
|
||||
sprintf(tmp_right, " [%llu KB]", entry.size() >> 10);
|
||||
} else {
|
||||
sprintf(tmp_right, " [%llu Bytes]", entry.size());
|
||||
}
|
||||
printDirectory(1, 0, tmp_left, tmp_right);
|
||||
|
||||
}
|
||||
|
||||
entry.close();
|
||||
}
|
||||
|
||||
root.close();
|
||||
}
|
||||
if(!strcmp(local_prefix, "/sd") || !strncmp(local_prefix, "/sd/", 4)) {
|
||||
char name[MAX_FILE_PATH+1];
|
||||
SdFile root;
|
||||
|
@ -1135,85 +1189,132 @@ void makeimagecmd(int argc, char **argv) {
|
|||
FsFile file;
|
||||
char tmp_path[MAX_FILE_PATH+1];
|
||||
uint64_t fileSize = 0;
|
||||
int i;
|
||||
bool write_mbr = 0;
|
||||
uint64_t cylinders = 0;
|
||||
uint64_t heads = 16;
|
||||
uint64_t sectors = 63;
|
||||
uint64_t blocksize = 512;
|
||||
|
||||
if(argc < 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
fixupPath(tmp_path, argv[1]);
|
||||
if(strncmp(tmp_path, "/sd/", 4)) {
|
||||
errorlevel = -1;
|
||||
Serial.print("ERROR");
|
||||
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
|
||||
Serial.printf(": Can only create images on the SD Card.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!strcmp(argv[2], "msdos") || !strcmp(argv[2], "generic")) {
|
||||
char *suffix = NULL;
|
||||
fileSize = strtoul(argv[3], &suffix, 0);
|
||||
if(suffix && suffix[0] != 0) {
|
||||
if(!strcmp(suffix, "KB")) fileSize *= 1000ull;
|
||||
if(!strcmp(suffix, "KiB")) fileSize *= 1024ull;
|
||||
if(!strcmp(suffix, "MB")) fileSize *= 1000000ull;
|
||||
if(!strcmp(suffix, "MiB")) fileSize *= 1024ull * 1024ull;
|
||||
if(!strcmp(suffix, "GB")) fileSize *= 1000000000ull;
|
||||
if(!strcmp(suffix, "GiB")) fileSize *= 1024ull * 1024ull * 1024ull;
|
||||
}
|
||||
|
||||
if(sd.exists(tmp_path+3)) {
|
||||
errorlevel = -1;
|
||||
Serial.print("ERROR");
|
||||
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
|
||||
Serial.printf(": file '%s' already exists.\r\n", tmp_path);
|
||||
return;
|
||||
}
|
||||
if(fileSize < (5ull * 1024ull * 1024ull)) {
|
||||
errorlevel = -1;
|
||||
Serial.print("ERROR");
|
||||
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
|
||||
Serial.printf(": Image would be less than 5 MiB.\r\n");
|
||||
return;
|
||||
}
|
||||
if(fileSize > (2048ull * 1024ull * 1024ull)) {
|
||||
errorlevel = -1;
|
||||
Serial.print("ERROR");
|
||||
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
|
||||
Serial.printf(": Image would be larger than 2 GiB.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Fixup image size to our 64 Head 32 Sector X Cylinders formula
|
||||
uint64_t cyl = fileSize / (512ull * 64ull * 32ull);
|
||||
if(fileSize & 0xFFFFF) cyl++;
|
||||
if(cyl > 2048) cyl = 2048;
|
||||
fileSize = cyl * (512ull * 64ull * 32ull);
|
||||
|
||||
if(!file.open(tmp_path+3, O_WRONLY | O_CREAT | O_TRUNC)) {
|
||||
errorlevel = -1;
|
||||
Serial.print("ERROR");
|
||||
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
|
||||
Serial.printf(": Unable to open '%s'.\r\n", tmp_path);
|
||||
} else {
|
||||
// Take advantage of our cylinders being 1MB
|
||||
if(!file.preAllocate(fileSize)) {
|
||||
file.close();
|
||||
sd.remove(tmp_path+3);
|
||||
tmp_path[0] = 0;
|
||||
|
||||
for(i = 1; i < argc; i++) {
|
||||
if(argv[i][0] == '/') {
|
||||
fixupPath(tmp_path, argv[i]);
|
||||
if(strncmp(tmp_path, "/sd/", 4)) {
|
||||
errorlevel = -1;
|
||||
Serial.print("ERROR");
|
||||
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
|
||||
Serial.printf(": Pre-allocate failed, SD Card must be formatted as ExFat.\r\n");
|
||||
Serial.printf(": Can only create images on the SD Card.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!strcmp(argv[2], "msdos")) {
|
||||
file.write(mbr_bin, 512);
|
||||
}
|
||||
file.close();
|
||||
|
||||
return;
|
||||
}
|
||||
if(!strcmp(argv[i], "-msdos")) {
|
||||
write_mbr = 1;
|
||||
} else
|
||||
if(!strcmp(argv[i], "-b") && (i+1 < argc)) {
|
||||
i++;
|
||||
blocksize = strtoul(argv[i], NULL, 0);
|
||||
} else
|
||||
if(!strcmp(argv[i], "-c") && (i+1 < argc)) {
|
||||
i++;
|
||||
cylinders = strtoul(argv[i], NULL, 0);
|
||||
} else
|
||||
if(!strcmp(argv[i], "-h") && (i+1 < argc)) {
|
||||
i++;
|
||||
heads = strtoul(argv[i], NULL, 0);
|
||||
} else
|
||||
if(!strcmp(argv[i], "-s") && (i+1 < argc)) {
|
||||
i++;
|
||||
sectors = strtoul(argv[i], NULL, 0);
|
||||
} else
|
||||
{
|
||||
char *suffix = NULL;
|
||||
fileSize = strtoul(argv[i], &suffix, 0);
|
||||
if(suffix && suffix[0] != 0) {
|
||||
if(!strcmp(suffix, "KB")) fileSize *= 1000ull;
|
||||
if(!strcmp(suffix, "KiB")) fileSize *= 1024ull;
|
||||
if(!strcmp(suffix, "MB")) fileSize *= 1000000ull;
|
||||
if(!strcmp(suffix, "MiB")) fileSize *= 1024ull * 1024ull;
|
||||
if(!strcmp(suffix, "GB")) fileSize *= 1000000000ull;
|
||||
if(!strcmp(suffix, "GiB")) fileSize *= 1024ull * 1024ull * 1024ull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(tmp_path[0] == 0) {
|
||||
errorlevel = -1;
|
||||
Serial.print("ERROR");
|
||||
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
|
||||
Serial.printf(": no path specified.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if((fileSize == 0) && (cylinders != 0)) {
|
||||
fileSize = cylinders * heads * sectors * blocksize;
|
||||
} else if(fileSize != 0){
|
||||
// Fixup image size to our CHS formula
|
||||
// Capping out at ~2GB
|
||||
cylinders = fileSize / (blocksize * heads * sectors);
|
||||
if(fileSize & 0xFFFFF) cylinders++;
|
||||
if(cylinders > 4095) cylinders = 4095;
|
||||
fileSize = cylinders * (blocksize * heads * sectors);
|
||||
} else {
|
||||
errorlevel = -1;
|
||||
Serial.print("ERROR");
|
||||
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
|
||||
Serial.printf(": no image size specified.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(sd.exists(tmp_path+3)) {
|
||||
errorlevel = -1;
|
||||
Serial.print("ERROR");
|
||||
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
|
||||
Serial.printf(": file '%s' already exists.\r\n", tmp_path);
|
||||
return;
|
||||
}
|
||||
if(fileSize < (5ull * 1024ull * 1024ull)) {
|
||||
errorlevel = -1;
|
||||
Serial.print("ERROR");
|
||||
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
|
||||
Serial.printf(": Image would be less than 5 MiB.\r\n");
|
||||
return;
|
||||
}
|
||||
if(fileSize > (2048ull * 1024ull * 1024ull)) {
|
||||
errorlevel = -1;
|
||||
Serial.print("ERROR");
|
||||
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
|
||||
Serial.printf(": Image would be larger than 2 GiB.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!file.open(tmp_path+3, O_WRONLY | O_CREAT | O_TRUNC)) {
|
||||
errorlevel = -1;
|
||||
Serial.print("ERROR");
|
||||
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
|
||||
Serial.printf(": Unable to open '%s'.\r\n", tmp_path);
|
||||
} else {
|
||||
if(write_mbr) {
|
||||
file.write(mbr_bin, 512);
|
||||
fileSize -= 512;
|
||||
}
|
||||
|
||||
memset(zero, 0, 512);
|
||||
|
||||
while(fileSize) {
|
||||
if((fileSize & 0x1FFF) == 0)
|
||||
Serial.printf(".");
|
||||
if((fileSize & 0x7FFFF) == 0)
|
||||
Serial.printf("\r\n");
|
||||
file.write(zero, (fileSize < 512) ? fileSize : 512);
|
||||
fileSize -= (fileSize < 512) ? fileSize : 512;
|
||||
}
|
||||
Serial.printf("\r\n");
|
||||
|
||||
file.close();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
errorlevel = -1;
|
||||
|
@ -1234,7 +1335,9 @@ void catcmd(int argc, char **argv) {
|
|||
}
|
||||
|
||||
fixupPath(tmp_path, argv[1]);
|
||||
if(!strncmp(filename, "/sd/", 4)) {
|
||||
if(!strncmp(filename, "/nv/", 4)) {
|
||||
filename += 3;
|
||||
} else if(!strncmp(filename, "/sd/", 4)) {
|
||||
filename += 3;
|
||||
} else {
|
||||
errorlevel = -1;
|
||||
|
@ -1375,9 +1478,44 @@ void setcmd(int argc, char **argv) {
|
|||
return;
|
||||
}
|
||||
|
||||
if((param_name) && !strcasecmp(param_name, "/sectors")) {
|
||||
if(argc<3) {
|
||||
Serial.printf("%d\r\n", h->m_sectors);
|
||||
} else {
|
||||
h->m_blocksize = strtol(argv[2], NULL, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if((param_name) && !strcasecmp(param_name, "/heads")) {
|
||||
if(argc<3) {
|
||||
Serial.printf("%d\r\n", h->m_heads);
|
||||
} else {
|
||||
h->m_blocksize = strtol(argv[2], NULL, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if((param_name) && !strcasecmp(param_name, "/cylinders")) {
|
||||
if(argc<3) {
|
||||
Serial.printf("%d\r\n", h->m_cylinders);
|
||||
} else {
|
||||
h->m_blocksize = strtol(argv[2], NULL, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if((param_name) && !strcasecmp(param_name, "/quirks")) {
|
||||
if(argc<3) {
|
||||
Serial.printf("0x%02x\r\n", h->m_quirks);
|
||||
} if(!strcasecmp(argv[2], "SASI") || !strcasecmp(argv[2], "+SASI")) {
|
||||
h->m_quirks |= QUIRKS_SASI;
|
||||
} if(!strcasecmp(argv[2], "-SASI")) {
|
||||
h->m_quirks &= ~QUIRKS_SASI;
|
||||
} if(!strcasecmp(argv[2], "APPLE") || !strcasecmp(argv[2], "+APPLE")) {
|
||||
h->m_quirks |= QUIRKS_APPLE;
|
||||
} if(!strcasecmp(argv[2], "-APPLE")) {
|
||||
h->m_quirks &= ~QUIRKS_APPLE;
|
||||
} else {
|
||||
h->m_quirks = strtol(argv[2], NULL, 0);
|
||||
}
|
||||
|
@ -1577,6 +1715,14 @@ void mountcmd(int argc, char **argv) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
if(!strncmp(tmp_path, "/raw/", 5)) {
|
||||
if(OpenDiskImage(h, tmp_path, 512)) {
|
||||
strcpy(h->m_filename, tmp_path);
|
||||
h->m_enabled = true;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
h->m_fileSize = 0;
|
||||
h->m_blocksize = 0;
|
||||
|
@ -1754,6 +1900,14 @@ void saveconfig(int argc, char **argv) {
|
|||
config_file.close();
|
||||
}
|
||||
|
||||
char helponSelfTest[] =
|
||||
"\r\n"
|
||||
"selftest\r\n"
|
||||
"\r\n"
|
||||
" Use the selftest command to check for miswired boards and shorts.\r\n"
|
||||
"\r\n"
|
||||
;
|
||||
|
||||
char helponSave[] =
|
||||
"\r\n"
|
||||
"saveconfig\r\n"
|
||||
|
@ -1868,15 +2022,21 @@ char helponVar[] =
|
|||
|
||||
char helponMkImg[] =
|
||||
"\r\n"
|
||||
"mkimg <file> <type> <size>\r\n"
|
||||
"mkimg <file> [-msdos] [-b blocksize] [-c cylinders] [-h heads] [-s sectors] [size]\r\n"
|
||||
"\r\n"
|
||||
" The mkimg command creates image files on ExFat volumes.\r\n"
|
||||
" The mkimg command creates image files on FAT or ExFat volumes.\r\n"
|
||||
"This command is limited to 4095 cylinders or approximately 2GB.\r\n"
|
||||
"To create larger images, use a USB card reader.\r\n"
|
||||
"\r\n"
|
||||
"<type> specifies the partitioning scheme to preload the image with.\r\n"
|
||||
" generic creates a blank disk ready for partitioning.\r\n"
|
||||
" msdos preloads an MBR boot menu, and in the future may pre-partition and format.\r\n"
|
||||
" -msdos preloads an msdos compatible MBR.\r\n"
|
||||
" -b sets the sector size (default=512).\r\n"
|
||||
" -c sets the number of cylinders.\r\n"
|
||||
" -h sets the heads (default=16).\r\n"
|
||||
" -s sets the sectors per track (default=63).\r\n"
|
||||
"\r\n"
|
||||
"<size> specifies file size and supports a KB,MB,GB (1000) or KiB,MiB,GiB (1024) suffix.\r\n"
|
||||
"You can specify the size either via the combination of -c -h -s parameters, or\r\n"
|
||||
"specify the file size with optional KB,MB,GB (1000) or KiB,MiB,GiB (1024) suffix\r\n"
|
||||
"and a cylinder count close to your desired size will be chosen for you.\r\n"
|
||||
"\r\n"
|
||||
;
|
||||
|
||||
|
@ -1891,6 +2051,7 @@ char helponHelp[] =
|
|||
|
||||
Commands_t GlobalCommands[] = {
|
||||
// Command Valid From Path Req. Params Short Help Long Help Handler Dispatch
|
||||
{ "selftest", "/", 0, "Execute Self Test.", helponSelfTest, SelfTest, NULL },
|
||||
{ "cd", "/", 1, "change current directory", NULL, changeDirectory, NULL },
|
||||
{ "sl", "/", 0, NULL, NULL, slcmd, NULL },
|
||||
{ "dir", "/", 0, NULL, NULL, punishDirectory, NULL },
|
||||
|
@ -1903,7 +2064,7 @@ Commands_t GlobalCommands[] = {
|
|||
{ "mount", "/vdevs/vdev", 1, "<path>", helponMount, mountcmd, NULL },
|
||||
{ "map", "/vdevs/vdev", 1, "<lun>", helponMapV, mapcmd, NULL },
|
||||
{ "cat", "/sd", 1, "<file>", helponCat, catcmd, NULL },
|
||||
{ "mkimg", "/sd", 1, "<file>", helponMkImg, makeimagecmd, NULL },
|
||||
{ "mkimg", "/sd", 1, "<file> <size>", helponMkImg, makeimagecmd, NULL },
|
||||
{ "unlink", "/", 1, "<path>", helponUnlink, unlinkcmd, NULL },
|
||||
{ "exec", "/", 1, "<script>", helponExec, execcmd, NULL },
|
||||
{ "goto", "/", 1, NULL, NULL, gotocmd, NULL },
|
||||
|
|
|
@ -9,12 +9,14 @@
|
|||
#define ACK_INTERRUPTS false
|
||||
#define READ_SPEED_OPTIMIZE true //
|
||||
#define WRITE_SPEED_OPTIMIZE true //
|
||||
#define READ_SPEED_OPTIMIZE_RAW true //
|
||||
#define WRITE_SPEED_OPTIMIZE_RAW true //
|
||||
#define USE_DB2ID_TABLE true // Use table to get ID from SEL-DB
|
||||
|
||||
// SCSI config
|
||||
#define NUM_SCSIID 8 // Maximum number of supported SCSI-IDs (The minimum is 1)
|
||||
#define NUM_SCSILUN 8 // Maximum number of LUNs supported (The minimum is 1)
|
||||
#define NUM_VDEV 8 // Maximum number of VDEVs supported (The minimum is 1)
|
||||
#define NUM_VDEV 16 // Maximum number of VDEVs supported (The minimum is 1)
|
||||
|
||||
#define READ_PARITY_CHECK 0 // Perform read parity check (unverified)
|
||||
|
||||
|
|
26
src/disk.ino
26
src/disk.ino
|
@ -10,7 +10,7 @@ byte checkBlockCommand(uint32_t adds, uint32_t len)
|
|||
if(!m_sel) {
|
||||
return STATUS_CHECK;
|
||||
}
|
||||
if(!m_sel->m_file.isOpen()) {
|
||||
if(!m_sel->m_rawPart && !m_sel->m_file.isOpen()) {
|
||||
m_sel->m_sense.m_key = NOT_READY; // Not ready
|
||||
m_sel->m_sense.m_code = LUN_NOT_READY; // Logical Unit Not Ready, Manual Intervention Required
|
||||
m_sel->m_sense.m_key_specific[0] = 0x03;
|
||||
|
@ -53,7 +53,7 @@ void ReadCapacityCommandHandler() {
|
|||
m_phase = PHASE_STATUSIN;
|
||||
return;
|
||||
}
|
||||
if(!m_sel->m_file.isOpen()) {
|
||||
if(!m_sel->m_rawPart && !m_sel->m_file.isOpen()) {
|
||||
m_sts |= STATUS_CHECK;
|
||||
m_sel->m_sense.m_key = NOT_READY; // Not ready
|
||||
m_sel->m_sense.m_code = LUN_NOT_READY; // Logical Unit Not Ready, Manual Intervention Required
|
||||
|
@ -111,7 +111,11 @@ uint8_t onReadCommand(uint32_t adds, uint32_t len)
|
|||
if(sts) return sts;
|
||||
|
||||
LED_ON();
|
||||
writeDataPhaseSD(adds, len);
|
||||
if(m_sel->m_rawPart) {
|
||||
writeDataPhaseRaw(adds, len);
|
||||
} else {
|
||||
writeDataPhaseSD(adds, len);
|
||||
}
|
||||
LED_OFF();
|
||||
return 0x00; //sts
|
||||
}
|
||||
|
@ -132,7 +136,11 @@ uint8_t onWriteCommand(uint32_t adds, uint32_t len)
|
|||
if(sts) return sts;
|
||||
|
||||
LED_ON();
|
||||
readDataPhaseSD(adds, len);
|
||||
if(m_sel->m_rawPart) {
|
||||
readDataPhaseRaw(adds, len);
|
||||
} else {
|
||||
readDataPhaseSD(adds, len);
|
||||
}
|
||||
LED_OFF();
|
||||
return 0; //sts
|
||||
}
|
||||
|
@ -153,7 +161,11 @@ uint8_t onVerifyCommand(uint32_t adds, uint32_t len)
|
|||
if(sts) return sts;
|
||||
|
||||
LED_ON();
|
||||
verifyDataPhaseSD(adds, len);
|
||||
if(m_sel->m_rawPart) {
|
||||
verifyDataPhaseRaw(adds, len);
|
||||
} else {
|
||||
verifyDataPhaseSD(adds, len);
|
||||
}
|
||||
LED_OFF();
|
||||
return 0; //sts
|
||||
}
|
||||
|
@ -207,6 +219,10 @@ void ConfigureDisk(VirtualDevice_t *vdev, const char *image_name) {
|
|||
}
|
||||
}
|
||||
|
||||
vdev->m_sectors = 63;
|
||||
vdev->m_heads = 16;
|
||||
vdev->m_cylinders = (uint32_t)((uint64_t)vdev->m_fileSize / ((uint64_t)vdev->m_blocksize * (uint64_t)vdev->m_heads * (uint64_t)vdev->m_sectors));
|
||||
|
||||
if(image_name) {
|
||||
char configname[MAX_FILE_PATH+1];
|
||||
memcpy(configname, image_name, MAX_FILE_PATH+1);
|
||||
|
|
112
src/general.ino
112
src/general.ino
|
@ -40,15 +40,16 @@ void RequestSenseCommandHandler() {
|
|||
};
|
||||
|
||||
if(!m_sel) {
|
||||
// Image file absent
|
||||
buf[2] = 0x02; // NOT_READY
|
||||
buf[12] = 0x25; // Logical Unit Not Supported
|
||||
buf[2] = 2; // Not ready
|
||||
buf[12] = LUN_NOT_READY; // Logical Unit Not Ready, Manual Intervention Required
|
||||
buf[13] = 0x03;
|
||||
} else {
|
||||
buf[2] = m_sel->m_sense.m_key;
|
||||
buf[12] = m_sel->m_sense.m_code;
|
||||
buf[13] = m_sel->m_sense.m_key_specific[0];
|
||||
buf[14] = m_sel->m_sense.m_key_specific[1];
|
||||
buf[15] = m_sel->m_sense.m_key_specific[2];
|
||||
|
||||
m_sel->m_sense.m_key = 0;
|
||||
m_sel->m_sense.m_code = 0;
|
||||
m_sel->m_sense.m_key_specific[0] = 0;
|
||||
|
@ -66,7 +67,7 @@ void TestUnitCommandHandler() {
|
|||
m_sts |= STATUS_CHECK;
|
||||
return;
|
||||
}
|
||||
if(!m_sel->m_file.isOpen()) {
|
||||
if(!m_sel->m_rawPart && !m_sel->m_file.isOpen()) {
|
||||
m_sts |= STATUS_CHECK;
|
||||
m_sel->m_sense.m_key = NOT_READY; // Not ready
|
||||
m_sel->m_sense.m_code = LUN_NOT_READY; // Logical Unit Not Ready, Manual Intervention Required
|
||||
|
@ -83,13 +84,14 @@ void RezeroUnitCommandHandler() {
|
|||
m_sts |= STATUS_CHECK;
|
||||
return;
|
||||
}
|
||||
if(!m_sel->m_file.isOpen()) {
|
||||
if(!m_sel->m_rawPart && !m_sel->m_file.isOpen()) {
|
||||
m_sts |= STATUS_CHECK;
|
||||
m_sel->m_sense.m_key = NOT_READY; // Not ready
|
||||
m_sel->m_sense.m_code = LUN_NOT_READY; // Logical Unit Not Ready, Manual Intervention Required
|
||||
m_sel->m_sense.m_key_specific[0] = 0x03;
|
||||
return;
|
||||
}
|
||||
|
||||
m_phase = PHASE_STATUSIN;
|
||||
}
|
||||
|
||||
|
@ -99,7 +101,7 @@ void FormatUnitCommandHandler() {
|
|||
m_sts |= STATUS_CHECK;
|
||||
return;
|
||||
}
|
||||
if(!m_sel->m_file.isOpen()) {
|
||||
if(!m_sel->m_rawPart && !m_sel->m_file.isOpen()) {
|
||||
m_sts |= STATUS_CHECK;
|
||||
m_sel->m_sense.m_key = NOT_READY; // Not ready
|
||||
m_sel->m_sense.m_code = LUN_NOT_READY; // Logical Unit Not Ready, Manual Intervention Required
|
||||
|
@ -116,7 +118,7 @@ void ReassignBlocksCommandHandler() {
|
|||
m_sts |= STATUS_CHECK;
|
||||
return;
|
||||
}
|
||||
if(!m_sel->m_file.isOpen()) {
|
||||
if(!m_sel->m_rawPart && !m_sel->m_file.isOpen()) {
|
||||
m_sts |= STATUS_CHECK;
|
||||
m_sel->m_sense.m_key = NOT_READY; // Not ready
|
||||
m_sel->m_sense.m_code = LUN_NOT_READY; // Logical Unit Not Ready, Manual Intervention Required
|
||||
|
@ -165,7 +167,7 @@ void ModeSenseCommandHandler()
|
|||
m_phase = PHASE_STATUSIN;
|
||||
return;
|
||||
}
|
||||
if(!m_sel->m_file.isOpen()) {
|
||||
if(!m_sel->m_rawPart && !m_sel->m_file.isOpen()) {
|
||||
m_sts |= STATUS_CHECK;
|
||||
m_sel->m_sense.m_key = NOT_READY; // Not ready
|
||||
m_sel->m_sense.m_code = LUN_NOT_READY; // Logical Unit Not Ready, Manual Intervention Required
|
||||
|
@ -175,84 +177,7 @@ void ModeSenseCommandHandler()
|
|||
}
|
||||
|
||||
memset(m_responsebuffer, 0, sizeof(m_responsebuffer));
|
||||
#if 0
|
||||
if(m_sel->m_quirks & QUIRKS_SASI) {
|
||||
int pageCode = cmd2 & 0x3F;
|
||||
|
||||
// Assuming sector size 512, number of sectors 25, number of heads 8 as default settings
|
||||
int size = m_sel->m_fileSize;
|
||||
int cylinders = (int)(size >> 9);
|
||||
cylinders >>= 3;
|
||||
cylinders /= 25;
|
||||
int sectorsize = 512;
|
||||
int sectors = 25;
|
||||
int heads = 8;
|
||||
// Sector size
|
||||
int disksize = 0;
|
||||
for(disksize = 16; disksize > 0; --(disksize)) {
|
||||
if ((1 << disksize) == sectorsize)
|
||||
break;
|
||||
}
|
||||
// Number of blocks
|
||||
uint32_t diskblocks = (uint32_t)(size >> disksize);
|
||||
int a = 4;
|
||||
if(dbd == 0) {
|
||||
uint32_t bl = m_sel->m_blocksize;
|
||||
uint32_t bc = m_sel->m_fileSize / bl;
|
||||
uint8_t c[8] = {
|
||||
0,// Density code
|
||||
bc >> 16, bc >> 8, bc,
|
||||
0, //Reserve
|
||||
bl >> 16, bl >> 8, bl
|
||||
};
|
||||
memcpy(&m_responsebuffer[4], c, 8);
|
||||
a += 8;
|
||||
m_responsebuffer[3] = 0x08;
|
||||
}
|
||||
switch(pageCode) {
|
||||
case 0x3F:
|
||||
{
|
||||
m_responsebuffer[len + 0] = 0x01;
|
||||
m_responsebuffer[len + 1] = 0x06;
|
||||
a += 8;
|
||||
}
|
||||
case 0x03: // drive parameters
|
||||
{
|
||||
m_responsebuffer[len + 0] = 0x80 | 0x03; // Page code
|
||||
m_responsebuffer[len + 1] = 0x16; // Page length
|
||||
m_responsebuffer[len + 2] = (uint8_t)(heads >> 8);// number of sectors / track
|
||||
m_responsebuffer[len + 3] = (uint8_t)(heads);// number of sectors / track
|
||||
m_responsebuffer[len + 10] = (uint8_t)(sectors >> 8);// number of sectors / track
|
||||
m_responsebuffer[len + 11] = (uint8_t)(sectors);// number of sectors / track
|
||||
int size = 1 << disksize;
|
||||
m_responsebuffer[len + 12] = (uint8_t)(size >> 8);// number of sectors / track
|
||||
m_responsebuffer[len + 13] = (uint8_t)(size);// number of sectors / track
|
||||
a += 24;
|
||||
if(pageCode != 0x3F) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 0x04: // drive parameters
|
||||
{
|
||||
LOGN("AddDrive");
|
||||
m_responsebuffer[len + 0] = 0x04; // Page code
|
||||
m_responsebuffer[len + 1] = 0x12; // Page length
|
||||
m_responsebuffer[len + 2] = (cylinders >> 16);// Cylinder length
|
||||
m_responsebuffer[len + 3] = (cylinders >> 8);
|
||||
m_responsebuffer[len + 4] = cylinders;
|
||||
m_responsebuffer[len + 5] = heads; // Number of heads
|
||||
a += 20;
|
||||
if(pageCode != 0x3F) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_responsebuffer[0] = a - 1;
|
||||
writeDataPhase(len < a ? len : a, m_responsebuffer);
|
||||
} else
|
||||
#endif
|
||||
|
||||
{
|
||||
/* Default medium type */
|
||||
m_responsebuffer[len++] = (m_sel->m_type == DEV_OPTICAL) ? 0xf0 : 0x00;
|
||||
|
@ -280,7 +205,7 @@ void ModeSenseCommandHandler()
|
|||
m_responsebuffer[len++] = 0x04;
|
||||
m_responsebuffer[len++] = 0x00;
|
||||
} else {
|
||||
uint32_t capacity = (m_sel->m_fileSize / m_sel->m_blocksize);
|
||||
uint32_t capacity = (m_sel->m_fileSize / m_sel->m_blocksize) - 1;
|
||||
m_responsebuffer[len++] = 8; /* Block descriptor length */
|
||||
m_responsebuffer[len++] = (capacity >> 24) & 0xff;
|
||||
m_responsebuffer[len++] = (capacity >> 16) & 0xff;
|
||||
|
@ -409,11 +334,14 @@ void ModeSenseCommandHandler()
|
|||
m_responsebuffer[len + 0] = MODEPAGE_RIGID_GEOMETRY; //Page code
|
||||
m_responsebuffer[len + 1] = 0x16; // Page length
|
||||
if((m_cmd[2] >> 6) != 1) {
|
||||
uint32_t bc = m_sel->m_fileSize / m_sel->m_file;
|
||||
m_responsebuffer[len + 2] = bc >> 16;// Cylinder length
|
||||
m_responsebuffer[len + 3] = bc >> 8;
|
||||
m_responsebuffer[len + 4] = bc;
|
||||
m_responsebuffer[len + 5] = 1; // Number of heads
|
||||
m_responsebuffer[len + 2] = m_sel->m_cylinders >> 16; // Number of cylinders
|
||||
m_responsebuffer[len + 3] = m_sel->m_cylinders >> 8;
|
||||
m_responsebuffer[len + 4] = m_sel->m_cylinders;
|
||||
m_responsebuffer[len + 5] = m_sel->m_heads; // Number of heads
|
||||
memcpy(&m_responsebuffer[len + 6], &m_responsebuffer[len + 2], 3); // Write Precomp Cyl
|
||||
memcpy(&m_responsebuffer[len + 9], &m_responsebuffer[len + 2], 3); // Reduced Write Current Cyl
|
||||
m_responsebuffer[len + 20] = 0x1C; // 7200 RPM
|
||||
m_responsebuffer[len + 21] = 0x20;
|
||||
}
|
||||
len += 24;
|
||||
break;
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
#include <Arduino.h> // For Platform.IO
|
||||
#include <SPI.h>
|
||||
#include <LittleFS.h>
|
||||
#include <SdFat.h>
|
||||
#include "sdios.h"
|
||||
#include "config.h"
|
||||
|
@ -48,6 +49,25 @@
|
|||
|
||||
// SDFAT
|
||||
SdFs sd;
|
||||
LittleFS_Program lfs;
|
||||
|
||||
|
||||
struct part_s {
|
||||
uint8_t boot;
|
||||
uint8_t beginCHS[3];
|
||||
uint8_t type;
|
||||
uint8_t endCHS[3];
|
||||
uint32_t firstSector;
|
||||
uint32_t totalSectors;
|
||||
} __attribute__((packed));
|
||||
typedef struct part_s part_t;
|
||||
//-----------------------------------------------------------------------------
|
||||
struct mbr_s {
|
||||
uint8_t bootCode[446];
|
||||
part_t part[4];
|
||||
uint8_t signature[2];
|
||||
} __attribute__((packed));
|
||||
typedef struct mbr_s mbr_t;
|
||||
|
||||
boolean debuglog = 0;
|
||||
|
||||
|
@ -193,7 +213,12 @@ typedef struct VirtualDevice_s
|
|||
char m_filename[MAX_FILE_PATH+1];
|
||||
FsFile m_file; // File object
|
||||
uint64_t m_fileSize; // File size
|
||||
uint8_t m_sectors;
|
||||
uint8_t m_heads;
|
||||
uint32_t m_cylinders;
|
||||
size_t m_blocksize; // SCSI BLOCK size
|
||||
uint32_t m_firstSector; // First sector for partition
|
||||
boolean m_rawPart; // Raw Partition (True) or Image File (False)
|
||||
#if SUPPORT_TAPE
|
||||
size_t m_filemarks; // Tape position counter (file marks since BOM)
|
||||
#endif
|
||||
|
@ -225,6 +250,8 @@ uint16_t default_quirks = (SUPPORT_SASI_DEFAULT ? QUIRKS_SASI : 0) | (SUPPO
|
|||
uint16_t ledbits = 0;
|
||||
uint8_t ledbit = 0;
|
||||
|
||||
uint8_t cardMBR[512];
|
||||
|
||||
typedef enum {
|
||||
PHASE_BUSFREE = 0,
|
||||
PHASE_SELECTION,
|
||||
|
@ -236,7 +263,7 @@ typedef enum {
|
|||
phase_t m_phase = PHASE_BUSFREE;
|
||||
|
||||
// Log File
|
||||
#define VERSION "1.2-20211204"
|
||||
#define VERSION "1.4-20230529"
|
||||
#if DEBUG == 2
|
||||
#define LOG_FILENAME "LOG.txt"
|
||||
FsFile LOG_FILE;
|
||||
|
@ -269,6 +296,8 @@ boolean OpenImage(VirtualDevice_t *h, const char *image_name)
|
|||
h->m_file = sd.open(image_name, O_RDWR);
|
||||
if(h->m_file.isOpen()) {
|
||||
h->m_fileSize = h->m_file.size();
|
||||
h->m_cylinders = (uint32_t)((uint64_t)h->m_fileSize / ((uint64_t)h->m_blocksize * (uint64_t)h->m_heads * (uint64_t)h->m_sectors));
|
||||
|
||||
return true; // File opened
|
||||
}
|
||||
return false;
|
||||
|
@ -280,6 +309,60 @@ boolean OpenImage(VirtualDevice_t *h, const char *image_name)
|
|||
*/
|
||||
boolean OpenDiskImage(VirtualDevice_t *h, const char *image_name, int blocksize)
|
||||
{
|
||||
if(!strncmp(image_name, "/tgts/", 6)) {
|
||||
LOGN("/tgts/ path is not supported for disk images.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!strncmp(image_name, "/vdevs/", 7)) {
|
||||
LOGN("/vdevs/ path is not supported for disk images.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!strncmp(image_name, "/diag/", 6)) {
|
||||
LOGN("/diag/ path is not supported for disk images.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!strncmp(image_name, "/nv/", 4)) {
|
||||
LOGN("/nv/ path is not supported for disk images.");
|
||||
return false;
|
||||
}
|
||||
|
||||
h->m_rawPart = false;
|
||||
|
||||
if(!strncmp(image_name, "/raw/part", 9)) {
|
||||
int partIndex = image_name[9] - '0';
|
||||
mbr_t *mbr = (mbr_t *)cardMBR;
|
||||
if((partIndex < 0) || (partIndex > 3)) {
|
||||
LOGN("partition index is outside the allowed range.");
|
||||
return false;
|
||||
}
|
||||
|
||||
sd.card()->readSector(0, cardMBR);
|
||||
if(mbr->part[partIndex].type != 0x87) {
|
||||
LOGN("partition is of the wrong type.");
|
||||
return false;
|
||||
}
|
||||
|
||||
h->m_blocksize = blocksize;
|
||||
h->m_fileSize = ((uint64_t)mbr->part[partIndex].totalSectors) * ((uint64_t)512);
|
||||
h->m_cylinders = (uint32_t)((uint64_t)h->m_fileSize / ((uint64_t)h->m_blocksize * (uint64_t)h->m_heads * (uint64_t)h->m_sectors));
|
||||
h->m_rawPart = true;
|
||||
h->m_firstSector = mbr->part[partIndex].firstSector;
|
||||
|
||||
LOG(" Imagefile: ");
|
||||
LOG(image_name);
|
||||
LOG(" / ");
|
||||
LOG(h->m_fileSize / h->m_blocksize);
|
||||
LOG(" sectors / ");
|
||||
LOG(h->m_fileSize / 1024);
|
||||
LOG(" KiB / ");
|
||||
LOG(h->m_fileSize / 1024 / 1024);
|
||||
LOGN(" MiB");
|
||||
return true; // File opened
|
||||
}
|
||||
|
||||
if(!strncmp(image_name, "/sd/", 4))
|
||||
image_name += 3;
|
||||
|
||||
|
@ -289,6 +372,7 @@ boolean OpenDiskImage(VirtualDevice_t *h, const char *image_name, int blocksize)
|
|||
if(h->m_file.isOpen())
|
||||
{
|
||||
h->m_fileSize = h->m_file.size();
|
||||
h->m_cylinders = (uint32_t)((uint64_t)h->m_fileSize / ((uint64_t)h->m_blocksize * (uint64_t)h->m_heads * (uint64_t)h->m_sectors));
|
||||
LOG(" Imagefile: ");
|
||||
LOG(image_name);
|
||||
if(h->m_fileSize>0)
|
||||
|
@ -320,6 +404,29 @@ boolean OpenDiskImage(VirtualDevice_t *h, const char *image_name, int blocksize)
|
|||
*/
|
||||
boolean OpenTapeImage(VirtualDevice_t *h, const char *image_name)
|
||||
{
|
||||
if(!strncmp(image_name, "/tgts/", 6)) {
|
||||
LOGN("/tgts/ path is not supported for tape images.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!strncmp(image_name, "/vdevs/", 7)) {
|
||||
LOGN("/vdevs/ path is not supported for tape images.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!strncmp(image_name, "/diag/", 6)) {
|
||||
LOGN("/diag/ path is not supported for tape images.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!strncmp(image_name, "/nv/", 4)) {
|
||||
LOGN("/nv/ path is not supported for tape images.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!strncmp(image_name, "/sd/", 4))
|
||||
image_name += 3;
|
||||
|
||||
h->m_fileSize = 0;
|
||||
h->m_blocksize = 0;
|
||||
h->m_filemarks = 0;
|
||||
|
@ -406,6 +513,9 @@ void setup()
|
|||
|
||||
LED_ON();
|
||||
|
||||
// Filesystems
|
||||
lfs.begin(256 * 1024); // 256KB of program memory to be used as nonvolatile storage
|
||||
|
||||
if(!sd.begin(SdioConfig(FIFO_SDIO))) {
|
||||
#if DEBUG > 0
|
||||
Serial.println("SD initialization failed!");
|
||||
|
@ -420,10 +530,14 @@ void setup()
|
|||
//HD image file open
|
||||
scsi_id_mask = 0x00;
|
||||
|
||||
// If greenscsi.cfg exists, run it
|
||||
// If greenscsi.cfg exists, run it (try first from SD, otherwise from flash)
|
||||
if(sd.exists("/greenscsi.cfg")) {
|
||||
execscript((char*)"/sd/greenscsi.cfg");
|
||||
execLoop();
|
||||
} else
|
||||
if(lfs.exists("/greenscsi.cfg")) {
|
||||
execscript((char*)"/nv/greenscsi.cfg");
|
||||
execLoop();
|
||||
}
|
||||
|
||||
// Scan for images if we haven't defined any targets yet.
|
||||
|
@ -911,3 +1025,235 @@ void BusFreePhaseHandler() {
|
|||
// Reset back to waiting for selection phase.
|
||||
m_phase = PHASE_SELECTION;
|
||||
}
|
||||
|
||||
typedef struct SelfTestPins_s {
|
||||
int A;
|
||||
int B;
|
||||
int pA;
|
||||
int pB;
|
||||
char nA[4];
|
||||
char nB[4];
|
||||
} SelfTestPins_t;
|
||||
|
||||
SelfTestPins_t SelfTestPins[] = {
|
||||
{ IO, DB0, 50, 2, "I/O", "DB0" },
|
||||
{ IO, DB0, 48, 4, "REQ", "DB1" },
|
||||
{ IO, DB0, 46, 6, "C/D", "DB2" },
|
||||
{ IO, DB0, 44, 8, "SEL", "DB3" },
|
||||
{ IO, DB0, 42, 10, "MSG", "DB4" },
|
||||
{ IO, DB0, 50, 12, "RST", "DB5" },
|
||||
{ IO, DB0, 38, 14, "ACK", "DB6" },
|
||||
{ IO, DB0, 36, 16, "BSY", "DB7" },
|
||||
{ IO, DB0, 32, 18, "ATN", "DBP" },
|
||||
};
|
||||
|
||||
void SelfTest(int argc, char **argv) {
|
||||
int i, x;
|
||||
char c;
|
||||
|
||||
Serial.printf("Are you sure you wish to run the self test? ");
|
||||
for(;;) {
|
||||
if (Serial.available()) {
|
||||
c = Serial.read();
|
||||
switch(c) {
|
||||
default:
|
||||
return;
|
||||
case 'y': case 'Y':
|
||||
goto ConnectHarness;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConnectHarness:
|
||||
// Clear any extra characters
|
||||
while (Serial.available()) {
|
||||
c = Serial.read();
|
||||
}
|
||||
|
||||
// Disable normal operation and prepare the self test.
|
||||
detachInterrupt(RST);
|
||||
detachInterrupt(SEL);
|
||||
|
||||
Serial.printf("Self Test starting...\r\n");
|
||||
|
||||
// Delay for 3 seconds
|
||||
delay(3000);
|
||||
|
||||
while (Serial.available()) {
|
||||
c = Serial.read();
|
||||
}
|
||||
|
||||
Serial.printf("Connect the Loopback test adapter and press Enter.");
|
||||
for(;;) {
|
||||
if (Serial.available()) {
|
||||
c = Serial.read();
|
||||
switch(c) {
|
||||
case 0xA: case 0xD:
|
||||
goto ExecuteSelfTest;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExecuteSelfTest:
|
||||
// Clear any extra characters
|
||||
while (Serial.available()) {
|
||||
c = Serial.read();
|
||||
}
|
||||
|
||||
// All pins input
|
||||
for(i = 0; i < 9; i++) {
|
||||
pinMode(SelfTestPins[i].A, INPUT_PULLUP);
|
||||
pinMode(SelfTestPins[i].B, INPUT_PULLUP);
|
||||
}
|
||||
|
||||
for(i = 0; i < 9; i++) {
|
||||
// Test A -> B
|
||||
pinMode(SelfTestPins[i].A, OUTPUT_OPENDRAIN);
|
||||
digitalWrite(SelfTestPins[i].A, LOW);
|
||||
|
||||
delay(10);
|
||||
|
||||
if(digitalRead(SelfTestPins[i].B) != LOW) {
|
||||
Serial.printf("Self Test Failed. Pin %d (%s) was unable to pull Pin %d (%s) LOW.\r\n", SelfTestPins[i].pA, SelfTestPins[i].nA, SelfTestPins[i].pB, SelfTestPins[i].nB);
|
||||
pinMode(SelfTestPins[i].A, INPUT_PULLUP);
|
||||
return;
|
||||
}
|
||||
|
||||
for(x = 0; x < 9; x++) {
|
||||
if(x != i) {
|
||||
if(digitalRead(SelfTestPins[x].A) == LOW) {
|
||||
Serial.printf("Self Test Failed. Pin %d (%s) is shorted to Pin %d (%s).\r\n", SelfTestPins[i].pA, SelfTestPins[i].nA, SelfTestPins[x].pA, SelfTestPins[x].nA);
|
||||
pinMode(SelfTestPins[i].A, INPUT_PULLUP);
|
||||
return;
|
||||
}
|
||||
if(digitalRead(SelfTestPins[x].B) == LOW) {
|
||||
Serial.printf("Self Test Failed. Pin %d (%s) is shorted to Pin %d (%s).\r\n", SelfTestPins[i].pA, SelfTestPins[i].nA, SelfTestPins[x].pB, SelfTestPins[x].nB);
|
||||
pinMode(SelfTestPins[i].A, INPUT_PULLUP);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pinMode(SelfTestPins[i].A, INPUT_PULLUP);
|
||||
|
||||
delay(10);
|
||||
|
||||
// Test B -> A
|
||||
pinMode(SelfTestPins[i].B, OUTPUT_OPENDRAIN);
|
||||
digitalWrite(SelfTestPins[i].B, LOW);
|
||||
|
||||
delay(10);
|
||||
|
||||
if(digitalRead(SelfTestPins[i].A) != LOW) {
|
||||
Serial.printf("Self Test Failed. Pin %d (%s) was unable to pull Pin %d (%s) LOW.\r\n", SelfTestPins[i].pB, SelfTestPins[i].nB, SelfTestPins[i].pA, SelfTestPins[i].nA);
|
||||
pinMode(SelfTestPins[i].B, INPUT_PULLUP);
|
||||
return;
|
||||
}
|
||||
|
||||
for(x = 0; x < 9; x++) {
|
||||
if(x != i) {
|
||||
if(digitalRead(SelfTestPins[x].A) == LOW) {
|
||||
Serial.printf("Self Test Failed. Pin %d (%s) is shorted to Pin %d (%s).\r\n", SelfTestPins[i].pB, SelfTestPins[i].nB, SelfTestPins[x].pA, SelfTestPins[x].nA);
|
||||
pinMode(SelfTestPins[i].B, INPUT_PULLUP);
|
||||
return;
|
||||
}
|
||||
if(digitalRead(SelfTestPins[x].B) == LOW) {
|
||||
Serial.printf("Self Test Failed. Pin %d (%s) is shorted to Pin %d (%s).\r\n", SelfTestPins[i].pB, SelfTestPins[i].nB, SelfTestPins[x].pB, SelfTestPins[x].nB);
|
||||
pinMode(SelfTestPins[i].B, INPUT_PULLUP);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pinMode(SelfTestPins[i].B, INPUT_PULLUP);
|
||||
|
||||
delay(10);
|
||||
}
|
||||
|
||||
while (Serial.available()) {
|
||||
c = Serial.read();
|
||||
}
|
||||
|
||||
Serial.printf("Disconnect the Loopback test adapter and press Enter.");
|
||||
for(;;) {
|
||||
if (Serial.available()) {
|
||||
c = Serial.read();
|
||||
switch(c) {
|
||||
case 0xA: case 0xD:
|
||||
goto DisconnectHarness;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DisconnectHarness:
|
||||
// Clear any extra characters
|
||||
while (Serial.available()) {
|
||||
c = Serial.read();
|
||||
}
|
||||
|
||||
for(i = 0; i < 9; i++) {
|
||||
// Test A -> B
|
||||
pinMode(SelfTestPins[i].A, OUTPUT_OPENDRAIN);
|
||||
digitalWrite(SelfTestPins[i].A, LOW);
|
||||
|
||||
delay(10);
|
||||
|
||||
if(digitalRead(SelfTestPins[i].B) == LOW) {
|
||||
Serial.printf("Self Test Failed. Pin %d (%s) is shorted to Pin %d (%s).\r\n", SelfTestPins[i].pA, SelfTestPins[i].nA, SelfTestPins[i].pB, SelfTestPins[i].nB);
|
||||
pinMode(SelfTestPins[i].A, INPUT_PULLUP);
|
||||
return;
|
||||
}
|
||||
|
||||
// Test B -> A
|
||||
pinMode(SelfTestPins[i].B, OUTPUT_OPENDRAIN);
|
||||
digitalWrite(SelfTestPins[i].B, LOW);
|
||||
|
||||
delay(10);
|
||||
|
||||
if(digitalRead(SelfTestPins[i].A) == LOW) {
|
||||
Serial.printf("Self Test Failed. Pin %d (%s) is shorted to Pin %d (%s).\r\n", SelfTestPins[i].pB, SelfTestPins[i].nB, SelfTestPins[i].pA, SelfTestPins[i].nA);
|
||||
pinMode(SelfTestPins[i].B, INPUT_PULLUP);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//SelfTestComplete:
|
||||
// Clear any extra characters
|
||||
while (Serial.available()) {
|
||||
c = Serial.read();
|
||||
}
|
||||
|
||||
Serial.printf("Self Test Passed.\r\n");
|
||||
|
||||
// On success, restore normal operation
|
||||
// Input port
|
||||
pinMode(ATN, INPUT_PULLUP);
|
||||
pinMode(ACK, INPUT_PULLUP);
|
||||
pinMode(RST, INPUT_PULLUP);
|
||||
pinMode(SEL, INPUT_PULLUP);
|
||||
|
||||
// Output port
|
||||
pinModeFastSlew(BSY, OUTPUT_OPENDRAIN);
|
||||
pinModeFastSlew(MSG, OUTPUT_OPENDRAIN);
|
||||
pinModeFastSlew(CD, OUTPUT_OPENDRAIN);
|
||||
pinModeFastSlew(IO, OUTPUT_OPENDRAIN);
|
||||
pinModeFastSlew(REQ, OUTPUT_OPENDRAIN);
|
||||
|
||||
pinModeFastSlew(DB0, OUTPUT_OPENDRAIN);
|
||||
pinModeFastSlew(DB1, OUTPUT_OPENDRAIN);
|
||||
pinModeFastSlew(DB2, OUTPUT_OPENDRAIN);
|
||||
pinModeFastSlew(DB3, OUTPUT_OPENDRAIN);
|
||||
pinModeFastSlew(DB4, OUTPUT_OPENDRAIN);
|
||||
pinModeFastSlew(DB5, OUTPUT_OPENDRAIN);
|
||||
pinModeFastSlew(DB6, OUTPUT_OPENDRAIN);
|
||||
pinModeFastSlew(DB7, OUTPUT_OPENDRAIN);
|
||||
pinModeFastSlew(DB8, OUTPUT_OPENDRAIN);
|
||||
|
||||
// Turn off the output port
|
||||
SCSI_TARGET_INACTIVE();
|
||||
|
||||
attachInterrupt(RST, onBusReset, FALLING);
|
||||
attachInterrupt(SEL, SelectionPhaseISR, FALLING);
|
||||
|
||||
LED_OFF();
|
||||
}
|
|
@ -497,6 +497,10 @@ void OpticalReadCapacityCommandHandler() {
|
|||
LOGN("[ReadCapacity]");
|
||||
if(!m_sel) {
|
||||
m_sts |= STATUS_CHECK; // Image file absent
|
||||
m_sel->m_sense.m_key_specific[0] = 0x04;
|
||||
m_sel->m_sense.m_key_specific[1] = 0x03;
|
||||
m_sel->m_sense.m_key_specific[2] = 0x00;
|
||||
m_sel->m_sense.m_key_specific[3] = 0x00;
|
||||
m_phase = PHASE_STATUSIN;
|
||||
return;
|
||||
}
|
||||
|
|
135
src/scsibus.ino
135
src/scsibus.ino
|
@ -211,6 +211,55 @@ void writeDataPhaseSD(uint32_t adds, uint32_t len)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Data in phase.
|
||||
* Send len block while reading from SD card.
|
||||
*/
|
||||
void writeDataPhaseRaw(uint32_t adds, uint32_t len)
|
||||
{
|
||||
#if READ_SPEED_OPTIMIZE_RAW
|
||||
uint32_t bigread = (MAX_BLOCKSIZE / m_sel->m_blocksize);
|
||||
#endif
|
||||
uint32_t i = 0;
|
||||
|
||||
//LOGN("DATAIN PHASE(RAW)");
|
||||
uint32_t pos = ((adds * m_sel->m_blocksize) / 512) + m_sel->m_firstSector;
|
||||
|
||||
SET_MSG_INACTIVE();
|
||||
SET_CD_INACTIVE();
|
||||
SET_IO_ACTIVE();
|
||||
|
||||
while(i < len) {
|
||||
// Asynchronous reads will make it faster ...
|
||||
#if READ_SPEED_OPTIMIZE_RAW
|
||||
if((len-i) >= bigread) {
|
||||
sd.card()->readSectors(pos, m_buf, (MAX_BLOCKSIZE / 512));
|
||||
writeHandshakeBlock(m_buf, MAX_BLOCKSIZE);
|
||||
i += bigread;
|
||||
pos += (MAX_BLOCKSIZE / 512);
|
||||
} else {
|
||||
sd.card()->readSectors(pos, m_buf, ((m_sel->m_blocksize * (len-i)) / 512));
|
||||
writeHandshakeBlock(m_buf, m_sel->m_blocksize * (len-i));
|
||||
i = len;
|
||||
}
|
||||
#else
|
||||
sd.card()->readSectors(pos, m_buf, (m_sel->m_blocksize / 512));
|
||||
pos++;
|
||||
for(unsigned int j = 0; j < m_sel->m_blocksize; j++) {
|
||||
if(m_isBusReset) {
|
||||
m_phase = PHASE_BUSFREE;
|
||||
return;
|
||||
}
|
||||
writeHandshake(m_buf[j]);
|
||||
}
|
||||
#endif
|
||||
if(m_isBusReset) {
|
||||
m_phase = PHASE_BUSFREE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Data out phase.
|
||||
* len block read
|
||||
|
@ -275,6 +324,50 @@ void readDataPhaseSD(uint32_t adds, uint32_t len)
|
|||
m_sel->m_file.flush();
|
||||
}
|
||||
|
||||
/*
|
||||
* Data out phase.
|
||||
* Write to SD card while reading len block.
|
||||
*/
|
||||
void readDataPhaseRaw(uint32_t adds, uint32_t len)
|
||||
{
|
||||
#if WRITE_SPEED_OPTIMIZE_RAW
|
||||
uint32_t bigread = (MAX_BLOCKSIZE / m_sel->m_blocksize);
|
||||
#endif
|
||||
uint32_t i = 0;
|
||||
|
||||
//LOGN("DATAOUT PHASE(RAW)");
|
||||
uint32_t pos = ((adds * m_sel->m_blocksize) / 512) + m_sel->m_firstSector;
|
||||
|
||||
SET_MSG_INACTIVE();
|
||||
SET_CD_INACTIVE();
|
||||
SET_IO_INACTIVE();
|
||||
|
||||
while(i < len) {
|
||||
#if WRITE_SPEED_OPTIMIZE_RAW
|
||||
if((len-i) >= bigread) {
|
||||
readHandshakeBlock(m_buf, MAX_BLOCKSIZE);
|
||||
sd.card()->writeSectors(pos, m_buf, (MAX_BLOCKSIZE / 512));
|
||||
i += bigread;
|
||||
pos += (MAX_BLOCKSIZE / 512);
|
||||
} else {
|
||||
readHandshakeBlock(m_buf, m_sel->m_blocksize * (len-i));
|
||||
sd.card()->writeSectors(pos, m_buf, ((m_sel->m_blocksize * (len-i)) / 512));
|
||||
i = len;
|
||||
}
|
||||
#else
|
||||
for(unsigned int j = 0; j < m_sel->m_blocksize; j++) {
|
||||
if(m_isBusReset) {
|
||||
return;
|
||||
}
|
||||
m_buf[j] = readHandshake();
|
||||
}
|
||||
sd.card()->writeSectors(pos, m_buf, (m_sel->m_blocksize / 512));
|
||||
i++;
|
||||
pos += (m_sel->m_blocksize / 512);
|
||||
#endif
|
||||
}
|
||||
m_sel->m_file.flush();
|
||||
}
|
||||
|
||||
/*
|
||||
* Data out phase.
|
||||
|
@ -287,6 +380,7 @@ void verifyDataPhaseSD(uint32_t adds, uint32_t len)
|
|||
#endif
|
||||
uint32_t i = 0;
|
||||
|
||||
//LOGN("DATAOUT PHASE(SD)");
|
||||
uint32_t pos = adds * m_sel->m_blocksize;
|
||||
m_sel->m_file.seek(pos);
|
||||
SET_MSG_INACTIVE();
|
||||
|
@ -295,6 +389,47 @@ void verifyDataPhaseSD(uint32_t adds, uint32_t len)
|
|||
|
||||
while(i < len) {
|
||||
#if WRITE_SPEED_OPTIMIZE
|
||||
if((len-i) >= bigread) {
|
||||
readHandshakeBlock(m_buf, MAX_BLOCKSIZE);
|
||||
//m_sel->m_file.verify(m_buf, MAX_BLOCKSIZE);
|
||||
i += bigread;
|
||||
} else {
|
||||
readHandshakeBlock(m_buf, m_sel->m_blocksize * (len-i));
|
||||
//m_sel->m_file.verify(m_buf, m_sel->m_blocksize * (len-i));
|
||||
i = len;
|
||||
}
|
||||
#else
|
||||
for(unsigned int j = 0; j < m_sel->m_blocksize; j++) {
|
||||
if(m_isBusReset) {
|
||||
return;
|
||||
}
|
||||
m_buf[j] = readHandshake();
|
||||
}
|
||||
//m_sel->m_file.verify(m_buf, m_sel->m_blocksize);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Data out phase.
|
||||
* Verify SD card while reading len block.
|
||||
*/
|
||||
void verifyDataPhaseRaw(uint32_t adds, uint32_t len)
|
||||
{
|
||||
#if WRITE_SPEED_OPTIMIZE_RAW
|
||||
uint32_t bigread = (MAX_BLOCKSIZE / m_sel->m_blocksize);
|
||||
#endif
|
||||
uint32_t i = 0;
|
||||
|
||||
//LOGN("DATAOUT PHASE(RAW)");
|
||||
//uint32_t pos = ((adds * m_sel->m_blocksize) / 512) + m_sel->m_firstSector;
|
||||
SET_MSG_INACTIVE();
|
||||
SET_CD_INACTIVE();
|
||||
SET_IO_INACTIVE();
|
||||
|
||||
while(i < len) {
|
||||
#if WRITE_SPEED_OPTIMIZE_RAW
|
||||
if((len-i) >= bigread) {
|
||||
readHandshakeBlock(m_buf, MAX_BLOCKSIZE);
|
||||
i += bigread;
|
||||
|
|
Loading…
Reference in New Issue
Block a user