Compare commits

...

12 Commits

Author SHA1 Message Date
David Kuder
8012d85d23 CHS Settings 2023-05-29 19:51:19 -04:00
David Kuder
a09d5dbf13 Update scsibus.ino 2023-05-13 03:01:20 -04:00
David Kuder
d420244da9 RAW disk support and LittleFS support 2023-05-13 02:49:13 -04:00
David Kuder
c5c4c51667
preAllocate fail
preAllocate has angered the TrackZero and must be punished, out with preAllocate, in with writing zeros 512 bytes at a time.
2022-10-14 22:40:33 -04:00
David Kuder
bc114096ac
Update README.md 2022-09-16 12:43:09 -04:00
David Kuder
41455971d4 Update GreenSCSI Manual.pdf 2022-06-12 01:44:36 -04:00
David Kuder
1205f4ad6e Schematic for MVP 2022-06-11 23:29:39 -04:00
David Kuder
382052a5a0 MVP Edition Hardware
Minimum Viable Product schematic, PCB layout & Gerbers.
2022-06-11 23:09:38 -04:00
David Kuder
1714acb3a2 Merge branch 'main' of https://github.com/dkgrizzly/GreenSCSI 2022-06-11 23:06:51 -04:00
David Kuder
8d84bc8ece 3D Printed Case 2022-06-11 23:06:47 -04:00
David Kuder
0abf96bd82
Update README.md 2022-06-11 15:32:06 -04:00
David Kuder
4ab58d0fff
Reference Manual First Draft 2022-06-11 15:31:30 -04:00
18 changed files with 10993 additions and 185 deletions

BIN
GreenSCSI Manual.pdf Normal file

Binary file not shown.

View File

@ -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

File diff suppressed because it is too large Load Diff

1402
case/GreenSCSI-top.stl Normal file

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View 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
View 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

Binary file not shown.

BIN
hardware/mvp/Schematic.pdf Normal file

Binary file not shown.

1947
hardware/mvp/fp-info-cache Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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 },

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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;