Skip to content

Commit

Permalink
Merge pull request #9 from 1a2m3/1a2m3-patch-20211201
Browse files Browse the repository at this point in the history
1a2m3 patch 20211206
  • Loading branch information
1a2m3 authored Dec 7, 2021
2 parents 54f283f + d36895d commit 0a2d144
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 60 deletions.
108 changes: 73 additions & 35 deletions firmware/SpdReaderWriter.ino
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include <EEPROM.h>
#include "SpdReaderWriterSettings.h" // Settings

#define VERSION 20211202 // Version number (YYYYMMDD)
#define VERSION 20211206 // Version number (YYYYMMDD)

// RSWP RAM support bitmasks
#define DDR5 (1 << 5) // Offline mode control
Expand Down Expand Up @@ -60,12 +60,12 @@
#define RPS2 0x6B // Read SWP2 status (addresses 100h to 17Fh) (256-383) (DDR4)
#define RPS3 0x61 // Read SWP3 status (addresses 180h to 1FFh) (384-511) (DDR4)

#define SWP0 0x62 // Set RSWP for block 0 (addresses 00h to 7Fh) ( 0-127) (DDR4/DDR3/DDR2)
#define SWP0 0x62 // Set RSWP for block 0 (addresses 00h to 7Fh) ( 0-127) (DDR4/DDR3/DDR2) *
#define SWP1 0x68 // Set RSWP for block 1 (addresses 80h to FFh) (128-255) (DDR4)
#define SWP2 0x6A // Set RSWP for block 2 (addresses 100h to 17Fh) (256-383) (DDR4)
#define SWP3 0x60 // Set RSWP for block 3 (addresses 180h to 1FFh) (384-511) (DDR4)
#define SWP3 0x60 // Set RSWP for block 3 (addresses 180h to 1FFh) (384-511) (DDR4) *

#define CWP 0x66 // Clear RSWP (DDR4/DDR3/DDR2)
#define CWP 0x66 // Clear RSWP (DDR4/DDR3/DDR2) *
#pragma endregion

// EEPROM PSWP commands
Expand Down Expand Up @@ -123,11 +123,15 @@
#define GET (char) '?' // Suffix added to commands to return current state

// Device responses
#define SUCCESS (byte) 0x01
#define ERROR (byte) 0xFF
#define ZERO (byte) 0x00
#define WELCOME (char) '!'
#define UNKNOWN (char) '?'
#define SUCCESS (byte) 0x01
#define ENABLED (byte) 0x01
#define ACK (byte) 0x01
#define ZERO (byte) 0x00
#define DISABLED (byte) 0x00
#define NACK (byte) 0xFF
#define ERROR (byte) 0xFF
#define WELCOME (char) '!'
#define UNKNOWN (char) '?'

// Device name settings
#define NAMELENGTH 16
Expand Down Expand Up @@ -179,7 +183,7 @@ void setup() {
while (!PORT) {}

// Send a welcome byte when the device is ready
PORT.write(WELCOME);
cmdTest();
}

void loop() {
Expand Down Expand Up @@ -366,7 +370,11 @@ void cmdScanBus() {
}

void cmdTest() {
#ifdef __AVR__
PORT.write(WELCOME);
#else
PORT.write(UNKNOWN);
#endif
}

void cmdRswpReport() {
Expand Down Expand Up @@ -483,13 +491,13 @@ void cmdRSWP() {
if (state == ENABLE) {
PORT.write(setRswp(block) ? SUCCESS : ERROR);
}
// clear RSWP (block number is ignored)
// clear RSWP (all blocks)
else if (state == DISABLE) {
PORT.write(clearRswp() ? SUCCESS : ERROR);
}
// get RSWP status
else if (state == GET) {
PORT.write(getRswp(block) ? SUCCESS : ERROR);
PORT.write(getRswp(block) ? ENABLED : DISABLED);
}
// unrecognized RSWP command
else {
Expand All @@ -514,7 +522,7 @@ void cmdPSWP() {
}
// read PSWP
else if (state == GET) {
PORT.write(getPswp(address) ? SUCCESS : ERROR);
PORT.write(getPswp(address) ? ENABLED : DISABLED);
}
// unknown state
else {
Expand Down Expand Up @@ -553,7 +561,7 @@ void cmdPinControl() {
// Toggle SA1 state
if (state == ENABLE || state == DISABLE) {
setConfigPin(pins[pin], state);
PORT.write(digitalRead(pins[pin]) == state ? SUCCESS : ERROR);
PORT.write(getConfigPin(pins[pin]) == state ? SUCCESS : ERROR);
}
// Get SA1 state
else if (state == GET) {
Expand Down Expand Up @@ -658,9 +666,17 @@ bool setRswp(uint8_t block) {
byte commands[] = { SWP0, SWP1, SWP2, SWP3 };
byte cmd = (block > 0 || block <= 3) ? commands[block] : commands[0];

bool ddr4 = ddr4Detect();
bool result;

if (setHighVoltage(ON)) {
setConfigPin(SA1_EN, OFF); // Required for pre-DDR4
bool result = probeDeviceTypeId(cmd);
if (block > 0 && !ddr4) {
result = false;
}
else {
result = probeDeviceTypeId(cmd);
}
resetPins();

return result;
Expand All @@ -680,18 +696,22 @@ bool getRswp(uint8_t block) {
setHighVoltage(ON);
}

bool status = probeDeviceTypeId(cmd);
bool status = probeDeviceTypeId(cmd); // true/ack = not protected

resetPins();

return status; // true = unprotected; false = protected or rswp not supported
return !status; // true = protected or rswp not supported; false = unprotected
}

// Clears reversible software write protection
bool clearRswp() {

if (setHighVoltage(ON)) {
setConfigPin(SA1_EN, ON); // Required for pre-DDR4
if (!ddr4Detect()) {
// Required for pre-DDR4
setConfigPin(SA1_EN, ON);
}

if (setHighVoltage(ON)) {
bool result = probeDeviceTypeId(CWP);
resetPins();

Expand Down Expand Up @@ -761,7 +781,7 @@ bool setHighVoltage(bool state) {

// Returns HV status by reading HV_FB
bool getHighVoltage() {
return digitalRead(HV_EN) && digitalRead(HV_FB);
return getConfigPin(HV_EN) && getConfigPin(HV_FB);
}


Expand All @@ -771,7 +791,7 @@ bool getHighVoltage() {
bool setPswp(uint8_t deviceAddress) {

if (ddr4Detect(deviceAddress) || ddr5Detect(deviceAddress)) {
return ERROR;
return false;
}

// Keep address bits (SA0-SA2) intact and change bits 7-4 to '0110'
Expand All @@ -782,7 +802,6 @@ bool setPswp(uint8_t deviceAddress) {
Wire.write(DNC);
Wire.write(DNC);
int status = Wire.endTransmission();
delay(10);

return status == 0;

Expand All @@ -800,8 +819,7 @@ bool getPswp(uint8_t deviceAddress) {
// Write 1 DNC byte to force LSB to set to 1
Wire.write(DNC);
int status = Wire.endTransmission();
delay(10);


return status == 0; // returns true if PSWP is not set

//uint8_t cmd = (deviceAddress & 0b111) << 1 | (PWPB << 4);
Expand All @@ -818,7 +836,7 @@ uint8_t getPageAddress(bool lowLevel = false) {
return eepromPageAddress;
}

#ifdef __AVR__
//#ifdef __AVR__

uint8_t status = ERROR;

Expand Down Expand Up @@ -862,7 +880,7 @@ uint8_t getPageAddress(bool lowLevel = false) {
default: return status;
}

#endif
//#endif

// Non-AVR response
return ERROR;
Expand All @@ -882,10 +900,11 @@ bool setPageAddress(uint8_t pageNumber) {
// Adjusts page address according to byte offset specified
void adjustPageAddress(uint8_t address, uint16_t offset) {

// Assume DDR4 is present, do not call ddr4Detect() for performance reasons
if (offset < 512) {
// Get offset MSB to see if it is below 0x100 or above 0xFF
uint8_t page = offset >> 8; // DDR4 page
uint8_t page;

// Assume DDR4 is present
if (offset <= 256) {
page = offset >> 8; // DDR4 page
if (getPageAddress() != page) {
setPageAddress(page);
}
Expand All @@ -897,7 +916,7 @@ void adjustPageAddress(uint8_t address, uint16_t offset) {
setLegacyModeAddress(address, false);

// Write page address to MR11[2:0]
uint8_t page = offset >> 7; // DDR5 page
page = offset >> 7; // DDR5 page

writeByte((MEMREG & address), (uint8_t)(MR11), (byte)(page));
// TODO: TBT
Expand Down Expand Up @@ -986,11 +1005,21 @@ byte scanBus() {
// Control config pins
bool setConfigPin(uint8_t pin, bool state) {
digitalWrite(pin, state);
return digitalRead(pin) == state;
if (pin == SA1_SWITCH) {
delay(5);
}

return getConfigPin(pin) == state;
}

// Get config pin state
bool getConfigPin(uint8_t pin) {
// SA1 state check
if (pin == SA1_SWITCH) {
byte _a1 = 0b11001100; // valid addresses bitmask when SA1 is high: 82-83, 86-87
return (digitalRead(pin) ? ((scanBus() & _a1)) : (scanBus() & ~_a1));
}

return digitalRead(pin);
}

Expand All @@ -1003,7 +1032,12 @@ void resetPins() {

// Toggle DDR5 offline mode
bool ddr5SetOfflineMode(bool state) {
digitalWrite(OFF_EN, state);
setConfigPin(OFF_EN, state);
if (state) {
// Set SDR-DDR4 to address 82-83 to avoid conflicts
setConfigPin(SA1_EN, state);
}

return ddr5GetOfflineMode() == state;
}

Expand Down Expand Up @@ -1046,13 +1080,17 @@ bool probeDeviceTypeId(uint8_t deviceSelectCode) {

// DDR4 detection test (address)
bool ddr4Detect(uint8_t address) {
if (address == 0) {
return ddr4Detect();
}

return probeBusAddress(address) && ddr4Detect();
}

// DDR4 detection test (generic)
bool ddr4Detect() {
return ((setPageAddress(0) ^ getPageAddress(true)) !=
(setPageAddress(1) ^ getPageAddress(true)));
// Only SPA0 is tested, RPA returns NACK after SPA1 regardless of RAM type
return setPageAddress(0) && getPageAddress(true) == 0;
}

// DDR5 detection test
Expand Down
2 changes: 1 addition & 1 deletion src/SpdReaderWriterDll/Device.cs
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ private UInt8[] ScanPrivate() {
lock (PortLock) {
try {
if (IsConnected) {
byte _response = Scan(true);
byte _response = ScanPrivate(true);

if (_response == Response.NULL) {
return new byte[0];
Expand Down
6 changes: 3 additions & 3 deletions src/SpdReaderWriterDll/Eeprom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ public static bool SetRswp(Device device) {
public static bool GetRswp(Device device) {
try {
for (UInt8 i = 0; i <= 3; i++) {
if (device.ExecuteCommand(new[] { RSWP, i, GET }) == Response.NACK) {
if (device.ExecuteCommand(new[] { RSWP, i, GET }) == Response.ENABLED) {
return true;
}
}
Expand All @@ -262,7 +262,7 @@ public static bool GetRswp(Device device) {
/// <returns><see langword="true" /> if the block is write protected (or RSWP is not supported) or <see langword="false" /> when the block is writable</returns>
public static bool GetRswp(Device device, UInt8 block) {
try {
return device.ExecuteCommand(new[] { RSWP, block, GET }) == Response.NACK;
return device.ExecuteCommand(new[] { RSWP, block, GET }) == Response.ENABLED;
}
catch {
throw new Exception($"Unable to get block {block} RSWP status on {device.PortName}");
Expand Down Expand Up @@ -304,7 +304,7 @@ public static bool SetPswp(Device device) {
/// <returns><see langword="true" /> when PSWP is enabled or <see langword="false" /> if when PSWP has NOT been set and EEPROM is writable</returns>
public static bool GetPswp(Device device) {
try {
return device.ExecuteCommand(new[] { PSWP, device.I2CAddress, GET }) == Response.NACK;
return device.ExecuteCommand(new[] { PSWP, device.I2CAddress, GET }) == Response.ENABLED;
}
catch {
throw new Exception($"Unable to get PSWP status on {device.PortName}");
Expand Down
30 changes: 16 additions & 14 deletions src/SpdReaderWriterDll/Response.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@ namespace SpdReaderWriterDll {
/// Class describing different responses received from the device
/// </summary>
public struct Response {
/// <summary>
/// Indicates the operation was executed successfully
/// </summary>
public const byte SUCCESS = 0x01;
/// <summary>
/// Indicates the operation has failed
/// </summary>
public const byte ERROR = 0xFF;
/// <summary>
/// Boolean True response
/// </summary>
Expand All @@ -20,12 +12,20 @@ public struct Response {
/// </summary>
public const byte FALSE = 0x00;
/// <summary>
/// Indicates the operation has failed
/// </summary>
public const byte ERROR = 0xFF;
/// <summary>
/// Indicates the operation was executed successfully
/// </summary>
public const byte SUCCESS = 0x01;
/// <summary>
/// A response used to indicate an error when normally a numeric non-zero answer is expected if the operation was executed successfully
/// </summary>
public const byte NULL = 0;
/// <summary>
/// A response used to describe when SA pin is tied to VCC
/// </summary>
/// </summary>
public const byte ON = 1;
/// <summary>
/// A response used to describe when SA pin is tied to GND
Expand All @@ -41,10 +41,12 @@ public struct Response {
public const char UNKNOWN = '?';

// Aliases
public const byte ACK = SUCCESS;
public const byte NACK = ERROR;
public const byte NOACK = ERROR;
public const byte FAIL = ERROR;
public const byte ZERO = NULL;
public const byte ACK = SUCCESS;
public const byte ENABLED = TRUE;
public const byte DISABLED = FALSE;
public const byte NACK = ERROR;
public const byte NOACK = ERROR;
public const byte FAIL = ERROR;
public const byte ZERO = NULL;
}
}
4 changes: 2 additions & 2 deletions src/SpdReaderWriterDll/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ public class Settings {
/// <summary>
/// DLL version
/// </summary>
public const int DLLVERSION = 20211202;
public const int DLLVERSION = 20211206;

/// <summary>
/// Minimum device's firmware version required
/// </summary>
public static int MINVERSION = 20211202;
public static int MINVERSION = 20211206;
}
}
Loading

0 comments on commit 0a2d144

Please sign in to comment.