Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Four new commands & some Sense #114

Merged
merged 7 commits into from
May 25, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 42 additions & 27 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -32,50 +32,65 @@ board_build.core = maple

[env:STM32F1-XCVR]
extends = env:STM32F1
build_flags = ${env.build_flags}
build_flags = ${env.build_flags}
-DXCVR
-D BUILD_TAGS="\"-XCVR\""

[env:STM32F1-USB]
extends = env:STM32F1
build_flags = ${env.build_flags}
-D BUILD_TAGS="\"-USB\""
[env:STM32F1-USB-128MHz]
# Max overclock for STM32
# Can use for APM32F1 as well.
extends = env:STM32F1-USB
board_build.f_cpu = 128000000L
build_flags = ${env.build_flags}
-D BUILD_TAGS="\"-USB-128MHz\""

[env:STM32F1-USB-96MHz]
# Slight overclock for STM32
# Use for APM32F1's - it's default clock is 96MHz and runs unstable at 72MHz(STM32F1's default)
extends = env:STM32F1-USB
# Explicilty define the multiplier as maple only handles a few cases.
build_flags = ${env.build_flags}
-D BUILD_TAGS="\"-USB-96MHz\""
-D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
-D USBCON
-D USBD_VID=0x0483
-D USB_MANUFACTURER="Unknown"
-D USB_PRODUCT="\"BLUEPILL_F103C8\""
-D HAL_PCD_MODULE_ENABLED

[env:STM32F1-USB-128MHZ]
extends = env:STM32F1
board_build.f_cpu = 128000000L
build_flags = ${env.build_flags}
-D BUILD_TAGS="\"-USB-128MHZ\""

[env:APM32F1]
# The APM32F1's default clock is 96MHz and runs unstable at 72MHz(STM32F1's default)
extends = env:STM32F1
# Explicilty define the multiplier as maple only handles a few cases.
build_flags = ${env.build_flags}
-D BUILD_TAGS="\"-APM32\""
-DBOARD_RCC_PLLMUL=RCC_PLLMUL_12 #96000000L

[env:APM32F1-USB]
# The APM32F1's default clock is 96MHz and runs unstable at 72MHz(STM32F1's default)
extends = env:APM32F1
# Explicilty define the multiplier as maple only handles a few cases.
build_flags = ${env.build_flags}
-D BUILD_TAGS="\"-APM32-USB\""
# TODO: Find out why USB build flags get trampled when extending an extended env.
[env:STM32F1-USB]
platform = ststm32
board = genericSTM32F103C8
board_build.mcu = stm32f103c8t6
board_build.core = maple
board_build.f_cpu = 128000000L
framework = arduino
lib_deps =
greiman/SdFat @ ^2.0.6
upload_protocol = dfu
; Different gcc versions produce much different binaries in terms of speed.
platform_packages = platformio/toolchain-gccarmnoneeabi@1.90301.200702
build_flags =
-D BUILD_TAGS="\"-USB\""
-D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
-D USBCON
-D USBD_VID=0x0483
-D USB_MANUFACTURER="Unknown"
-D USB_PRODUCT="\"BLUEPILL_F103C8\""
-D HAL_PCD_MODULE_ENABLED
-DBOARD_RCC_PLLMUL=RCC_PLLMUL_12 #96000000L
# Or go all out at 128Mhz, your call :)
#board_build.f_cpu = 128000000L
-w
-DARDUINO_GENERIC_STM32F103C
-DARDUINO_LIB_DISCOVERY_PHASE
-DARDUINO=10813
-DARDUINO_ARCH_STM32
-DDEBUG_LEVEL=DEBUG_NONE
-O2
build_unflags =
-Os
-DARDUINO_ARCH_STM32F1
upload_flags = -c set CPUTAPID 0

; [env:debug]
; build_type = debug
Expand Down
142 changes: 121 additions & 21 deletions src/BlueSCSI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "scsi_cmds.h"
#include "scsi_sense.h"
#include "scsi_status.h"
#include "scsi_mode.h"

#ifdef USE_STM32_DMA
#warning "warning USE_STM32_DMA"
Expand Down Expand Up @@ -245,6 +246,7 @@ byte m_sts; // Status byte
byte m_msg; // Message bytes
HDDIMG *m_img; // HDD image for current SCSI-ID, LUN
byte m_buf[MAX_BLOCKSIZE]; // General purpose buffer
byte m_scsi_buf[512]; // Buffer for SCSI READ/WRITE Buffer
byte m_msb[256]; // Command storage bytes

/*
Expand Down Expand Up @@ -276,7 +278,7 @@ uint32_t db_bsrr[256];
//#undef PTY

// Log File
#define VERSION "1.1-SNAPSHOT-20220407"
#define VERSION "1.1-SNAPSHOT-20220522"
#define LOG_FILENAME "LOG.txt"
FsFile LOG_FILE;

Expand Down Expand Up @@ -679,7 +681,7 @@ void initFileLog(int success_mhz) {
LOG_FILE.println(SDFAT_FILE_TYPE);
LOG_FILE.print("SdFat version: ");
LOG_FILE.println(SD_FAT_VERSION_STR);
LOG_FILE.print("SD Format: ");
LOG_FILE.print("Sd Format: ");
switch(SD.vol()->fatType()) {
case FAT_TYPE_EXFAT:
LOG_FILE.println("exFAT");
Expand Down Expand Up @@ -1239,7 +1241,7 @@ byte onModeSenseCommand(byte scsi_cmd, byte dbd, byte cmd2, uint32_t len)
int pageCode = cmd2 & 0x3F;
int pageControl = cmd2 >> 6;
int a = 4;
if(scsi_cmd == 0x5A) a = 8;
if(scsi_cmd == SCSI_MODE_SENSE10) a = 8;

if(dbd == 0) {
byte c[8] = {
Expand All @@ -1252,21 +1254,21 @@ byte onModeSenseCommand(byte scsi_cmd, byte dbd, byte cmd2, uint32_t len)
a += 8;
}
switch(pageCode) {
case 0x3F:
case 0x01: // Read/Write Error Recovery
m_buf[a + 0] = 0x01;
case SCSI_SENSE_MODE_ALL:
case SCSI_SENSE_MODE_READ_WRITE_ERROR_RECOVERY:
m_buf[a + 0] = SCSI_SENSE_MODE_READ_WRITE_ERROR_RECOVERY;
m_buf[a + 1] = 0x0A;
a += 0x0C;
if(pageCode != 0x3F) break;
if(pageCode != SCSI_SENSE_MODE_ALL) break;

case 0x02: // Disconnect-Reconnect page
m_buf[a + 0] = 0x02;
case SCSI_SENSE_MODE_DISCONNECT_RECONNECT:
m_buf[a + 0] = SCSI_SENSE_MODE_DISCONNECT_RECONNECT;
m_buf[a + 1] = 0x0A;
a += 0x0C;
if(pageCode != 0x3f) break;
if(pageCode != SCSI_SENSE_MODE_ALL) break;

case 0x03: //Drive parameters
m_buf[a + 0] = 0x03; //Page code
case SCSI_SENSE_MODE_FORMAT_DEVICE: //Drive parameters
m_buf[a + 0] = SCSI_SENSE_MODE_FORMAT_DEVICE; //Page code
m_buf[a + 1] = 0x16; // Page length
if(pageControl != 1) {
m_buf[a + 11] = 0x3F;//Number of sectors / track
Expand All @@ -1275,10 +1277,10 @@ byte onModeSenseCommand(byte scsi_cmd, byte dbd, byte cmd2, uint32_t len)
m_buf[a + 15] = 0x1; // Interleave
}
a += 0x18;
if(pageCode != 0x3F) break;
if(pageCode != SCSI_SENSE_MODE_ALL) break;

case 0x04: //Drive parameters
m_buf[a + 0] = 0x04; //Page code
case SCSI_SENSE_MODE_DISK_GEOMETRY: //Drive parameters
m_buf[a + 0] = SCSI_SENSE_MODE_DISK_GEOMETRY; //Page code
m_buf[a + 1] = 0x16; // Page length
if(pageControl != 1) {
unsigned cylinders = bc / (16 * 63);
Expand All @@ -1288,19 +1290,19 @@ byte onModeSenseCommand(byte scsi_cmd, byte dbd, byte cmd2, uint32_t len)
m_buf[a + 5] = 16; //Number of heads
}
a += 0x18;
if(pageCode != 0x3F) break;
case 0x30:
if(pageCode != SCSI_SENSE_MODE_ALL) break;
case SCSI_SENSE_MODE_VENDOR_APPLE:
{
const byte page30[0x14] = {0x41, 0x50, 0x50, 0x4C, 0x45, 0x20, 0x43, 0x4F, 0x4D, 0x50, 0x55, 0x54, 0x45, 0x52, 0x2C, 0x20, 0x49, 0x4E, 0x43, 0x20};
m_buf[a + 0] = 0x30; // Page code
m_buf[a + 0] = SCSI_SENSE_MODE_VENDOR_APPLE; // Page code
m_buf[a + 1] = sizeof(page30); // Page length
if(pageControl != 1) {
memcpy(&m_buf[a + 2], page30, sizeof(page30));
}
a += 2 + sizeof(page30);
if(pageCode != 0x3F) break;
if(pageCode != SCSI_SENSE_MODE_ALL) break;
}
break; // Don't want 0x3F falling through to error condition
break; // Don't want SCSI_SENSE_MODE_ALL falling through to error condition

default:
m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
Expand Down Expand Up @@ -1334,10 +1336,12 @@ byte onModeSelectCommand(byte scsi_cmd, byte flags, uint32_t len)
//0 0 0 8 0 0 0 0 0 0 2 0 0 2 10 0 1 6 24 10 8 0 0 0
//I believe mode page 0 set to 10 00 is Disable Unit Attention
//Mode page 1 set to 24 10 08 00 00 00 is TB and PER set, read retry count 16, correction span 8
#if DEBUG > 0
for (unsigned i = 0; i < len; i++) {
LOGHEX(m_buf[i]);LOG(" ");
}
LOGN("");
#endif
return SCSI_STATUS_GOOD;
}

Expand All @@ -1354,6 +1358,93 @@ byte onTestUnitReady()
}
return SCSI_STATUS_GOOD;
}
/*
* ReZero Unit - Move to Logical Block Zero in file.
*/
byte onReZeroUnit() {
LOGN("-ReZeroUnit");
// Make sure we have an image with atleast a first byte.
// Actually seeking to the position wont do anything, so dont.
return checkBlockCommand(0, 0);
}

/*
* WriteBuffer - Used for testing buffer, no change to medium
*/
byte onWriteBuffer(byte mode, uint32_t allocLength)
{
LOGN("-WriteBuffer");
LOGHEXN(mode);
LOGHEXN(allocLength);

if ((mode == MODE_COMBINED_HEADER_DATA || mode == MODE_DATA) && allocLength <= sizeof(m_scsi_buf))
erichelgeson marked this conversation as resolved.
Show resolved Hide resolved
{
readDataPhase(allocLength, m_scsi_buf);
#if DEBUG > 0
for (unsigned i = 0; i < allocLength; i++) {
LOGHEX(m_buf[i]);LOG(" ");
}
LOGN("");
#endif
return SCSI_STATUS_GOOD;
}
else
{
m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
m_addition_sense = SCSI_ASC_INVALID_FIELD_IN_CDB;
return SCSI_STATUS_CHECK_CONDITION;
}
}

/*
* ReadBuffer - Used for testing buffer, no change to medium
*/
byte onReadBuffer(byte mode, uint32_t allocLength)
{
LOGN("-ReadBuffer");
LOGHEXN(mode);
LOGHEXN(allocLength);

if (mode == MODE_COMBINED_HEADER_DATA)
{
uint32_t bufCapacity = sizeof(m_scsi_buf);
byte scsi_buf_response[bufCapacity + 4];
// four byte read buffer header
scsi_buf_response[0] = 0;
scsi_buf_response[1] = (bufCapacity >> 16) & 0xff;
scsi_buf_response[2] = (bufCapacity >> 8) & 0xff;
scsi_buf_response[3] = bufCapacity & 0xff;
// actual data
memcpy((&scsi_buf_response[4]), m_scsi_buf, bufCapacity);

writeDataPhase(sizeof(scsi_buf_response), scsi_buf_response);

#if DEBUG > 0
for (unsigned i = 0; i < allocLength; i++) {
LOGHEX(m_scsi_buf[i]);LOG(" ");
}
LOGN("");
#endif
return SCSI_STATUS_GOOD;
}
else if (mode == MODE_DATA)
{
writeDataPhase(allocLength, m_scsi_buf);
#if DEBUG > 0
for (unsigned i = 0; i < allocLength; i++) {
LOGHEX(m_scsi_buf[i]);LOG(" ");
}
LOGN("");
#endif
return SCSI_STATUS_GOOD;
}
else
{
m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
m_addition_sense = SCSI_ASC_INVALID_FIELD_IN_CDB;
return SCSI_STATUS_CHECK_CONDITION;
}
}

/*
* MsgIn2.
Expand Down Expand Up @@ -1521,8 +1612,9 @@ void loop()
LOGN("[Test Unit Ready]");
m_sts |= onTestUnitReady();
break;
case SCSI_REZERO_UNIT: // TODO: Implement me!
case SCSI_REZERO_UNIT:
LOGN("[Rezero Unit]");
m_sts |= onReZeroUnit();
break;
case SCSI_REQUEST_SENSE:
LOGN("[RequestSense]");
Expand Down Expand Up @@ -1596,6 +1688,14 @@ void loop()
LOGN("[ModeSense10]");
m_sts |= onModeSenseCommand(cmd[0], cmd[1] & 0x80, cmd[2], ((uint32_t)cmd[7] << 8) | cmd[8]);
break;
case SCSI_WRITE_BUFFER:
LOGN("[WriteBuffer]");
m_sts |= onWriteBuffer(cmd[1] & 7, ((uint32_t)cmd[6] << 16) | ((uint32_t)cmd[7] << 8) | cmd[8]);
break;
case SCSI_READ_BUFFER:
LOGN("[ReadBuffer]");
m_sts |= onReadBuffer(cmd[1] & 7, ((uint32_t)cmd[6] << 16) | ((uint32_t)cmd[7] << 8) | cmd[8]);
break;
default:
LOGN("[*Unknown]");
m_sts |= SCSI_STATUS_CHECK_CONDITION;
Expand Down
9 changes: 9 additions & 0 deletions src/scsi_mode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef __SCSI_MODE_H__
#define __SCSI_MODE_H__

#define MODE_COMBINED_HEADER_DATA 0x00
#define MODE_NOT_SUPPORTED 0x01
#define MODE_DATA 0x02
#define MODE_DESCRIPTOR 0x03

#endif
13 changes: 13 additions & 0 deletions src/scsi_sense.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,17 @@
#define SCSI_ASC_CANNOT_READ_MEDIUM_INCOMPATIBLE_FORMAT 0x3002
#define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3A00
#define SCSI_ASC_LUN_NOT_READY_MANUAL_INTERVENTION_REQUIRED 0x0403


// SCSI mode page codes
#define SCSI_SENSE_MODE_VENDOR 0x00
#define SCSI_SENSE_MODE_READ_WRITE_ERROR_RECOVERY 0x01
#define SCSI_SENSE_MODE_DISCONNECT_RECONNECT 0x02
#define SCSI_SENSE_MODE_FORMAT_DEVICE 0x03
#define SCSI_SENSE_MODE_DISK_GEOMETRY 0x04
#define SCSI_SENSE_MODE_VENDOR_APPLE 0x30

#define SCSI_SENSE_MODE_ALL 0x3F


#endif