Skip to content

Commit

Permalink
0.2.rev.A. Add new comm opcodes (firmware and software) for device pr…
Browse files Browse the repository at this point in the history
…ogramming
  • Loading branch information
robsonsmartins committed Jan 17, 2024
1 parent e22fa9f commit afc6460
Show file tree
Hide file tree
Showing 19 changed files with 897 additions and 449 deletions.
Binary file modified docs/specs.odt
Binary file not shown.
Binary file modified docs/specs.pdf
Binary file not shown.
2 changes: 2 additions & 0 deletions firmware/usbflashprog/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,7 @@ constexpr uint32_t kCommTimeOut = 50;

/** @brief GENERAL : Time for stabilization, in microseconds. */
constexpr uint32_t kStabilizationTime = 150;
/** @brief GENERAL : Erase pulse duration, in milliseconds. */
constexpr uint32_t kErasePulseDuration = 100;

#endif // CONFIG_HPP_
74 changes: 63 additions & 11 deletions firmware/usbflashprog/modules/opcodes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ enum kCmdOpCodeEnum {
kCmdDeviceSetTwc = 0x82,
/**
* @brief OPCODE / DEVICE : Opcode Device Set Flags.
* @details The parameter (one byte) that represents the flags
* @details The parameter (one byte) represents the flags, and
* follows the table:
* <pre>
* +----------------------+
Expand All @@ -141,23 +141,71 @@ enum kCmdOpCodeEnum {
* </pre>
*/
kCmdDeviceSetFlags = 0x83,
/** @brief OPCODE / DEVICE : Opcode Device Read and Increment Address. */
kCmdDeviceRead = 0x84,
/**
* @brief OPCODE / DEVICE : Opcode Device Setup Bus.
* @details The first parameter (one byte) represents the operation, and
* follows the table:
* <pre>
* +------------------------------+
* |Operation| Description |
* | 0x00 | Reset Bus |
* | 0x01 | Prepare to Read |
* | 0x02 | Prepare to Program |
* +------------------------------+
* </pre>
* @see kCmdDeviceOperationEnum
*/
kCmdDeviceSetupBus = 0x84,
/** @brief OPCODE / DEVICE : Opcode Device Read Word and
* Increment Address. */
kCmdDeviceRead = 0x85,
/** @brief OPCODE / DEVICE : Opcode Device Read Byte and
* Increment Address. */
kCmdDeviceReadB = 0x85,
/** @brief OPCODE / DEVICE : Opcode Device Write, Verify and
kCmdDeviceReadB = 0x86,
/** @brief OPCODE / DEVICE : Opcode Device Write Word, Verify and
* Increment Address. */
kCmdDeviceWrite = 0x86,
kCmdDeviceWrite = 0x87,
/** @brief OPCODE / DEVICE : Opcode Device Write Byte, Verify and
* Increment Address. */
kCmdDeviceWriteB = 0x87,
/** @brief OPCODE / DEVICE : Opcode Device Verify and
kCmdDeviceWriteB = 0x88,
/** @brief OPCODE / DEVICE : Opcode Device Verify Word and
* Increment Address. */
kCmdDeviceVerify = 0x88,
kCmdDeviceVerify = 0x89,
/** @brief OPCODE / DEVICE : Opcode Device Verify Byte and
* Increment Address. */
kCmdDeviceVerifyB = 0x89
kCmdDeviceVerifyB = 0x8A,
/**
* @brief OPCODE / DEVICE : Opcode Device Get ID.
* @details The result (two bytes) represents Manufacturer/Device ID,
* following the table:
* <pre>
* +-------------------------------+
* |Response | Description |
* | First (MSB) | Manufacurer ID |
* | Second (LSB) | Device ID |
* +-------------------------------+
* </pre>
*/
kCmdDeviceGetId = 0x8B,
/** @brief OPCODE / DEVICE : Opcode Device Erase. */
kCmdDeviceErase = 0x8C
};

// ---------------------------------------------------------------------------

/**
* @brief Enumeration of the Device Operations.
* @see kCmdDeviceSetupBus
*/
enum kCmdDeviceOperationEnum {
/** @brief CMD / DEVICE : Defines a operation Reset. */
kCmdDeviceOperationReset = 0x00,
/** @brief CMD / DEVICE : Defines a operation Read. */
kCmdDeviceOperationRead = 0x01,
/** @brief CMD / DEVICE : Defines a operation Program. */
kCmdDeviceOperationProg = 0x02,
/** @brief CMD / DEVICE : Defines a operation Get ID. */
kCmdDeviceOperationGetId = 0x03
};

// ---------------------------------------------------------------------------
Expand Down Expand Up @@ -245,12 +293,16 @@ static const TCmdOpCodeMap kCmdOpCodes = {
{kCmdDeviceSetTwp , {kCmdDeviceSetTwp , "Device Set Twp" , 4, 0}},
{kCmdDeviceSetTwc , {kCmdDeviceSetTwc , "Device Set Twc" , 4, 0}},
{kCmdDeviceSetFlags, {kCmdDeviceSetFlags, "Device Set Flags" , 1, 0}},
{kCmdDeviceSetupBus, {kCmdDeviceSetupBus, "Device Setup Bus" , 1, 0}},
{kCmdDeviceRead , {kCmdDeviceRead , "Device Read" , 0, 2}},
{kCmdDeviceReadB , {kCmdDeviceReadB , "Device ReadByte" , 0, 1}},
{kCmdDeviceWrite , {kCmdDeviceWrite , "Device Write" , 2, 0}},
{kCmdDeviceWriteB , {kCmdDeviceWriteB , "Device WriteByte" , 1, 0}},
{kCmdDeviceVerify , {kCmdDeviceVerify , "Device Verify" , 2, 0}},
{kCmdDeviceVerifyB , {kCmdDeviceVerifyB , "Device VerifyByte", 1, 0}}
{kCmdDeviceVerifyB , {kCmdDeviceVerifyB , "Device VerifyByte", 1, 0}},
{kCmdDeviceGetId , {kCmdDeviceGetId , "Device Get ID" , 0, 2}},
{kCmdDeviceErase , {kCmdDeviceErase , "Device Erase" , 0, 0}}

};
// clang-format on

Expand Down
205 changes: 192 additions & 13 deletions firmware/usbflashprog/modules/runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ void Runner::runCommand_() {
runDeviceReadCommand_(code->first);
runDeviceWriteCommand_(code->first);
runDeviceVerifyCommand_(code->first);
runDeviceGetIdCommand_(code->first);
runDeviceEraseCommand_(code->first);
}
}

Expand Down Expand Up @@ -289,7 +291,6 @@ void Runner::runVppCommand_(uint8_t opcode) {

void Runner::runCtrlBusCommand_(uint8_t opcode) {
bool b;
TByteArray response;
switch (opcode) {
case kCmdBusCE:
b = getParamAsBool_();
Expand Down Expand Up @@ -359,7 +360,6 @@ void Runner::runDataBusCommand_(uint8_t opcode) {

void Runner::runAddrBusCommand_(uint8_t opcode) {
uint32_t dw;
TByteArray response;
switch (opcode) {
case kCmdBusAddrClr:
if (addrBus_.writeByte(0)) {
Expand Down Expand Up @@ -406,7 +406,6 @@ void Runner::runAddrBusCommand_(uint8_t opcode) {

void Runner::runDeviceSettingsCommand_(uint8_t opcode) {
uint32_t dw;
TByteArray response;
switch (opcode) {
case kCmdDeviceSetTwp:
dw = getParamAsDWord_();
Expand All @@ -426,14 +425,22 @@ void Runner::runDeviceSettingsCommand_(uint8_t opcode) {
// 3 = ~PGM/~CE Pin
// 4 = PGM positive
// clang-format off
settings_.skipFF = (dw & 0x01 != 0);
settings_.progWithVpp = (dw & 0x02 != 0);
settings_.vppOePin = (dw & 0x04 != 0);
settings_.pgmCePin = (dw & 0x08 != 0);
settings_.pgmPositive = (dw & 0x10 != 0);
settings_.skipFF = (dw & 0x01) != 0;
settings_.progWithVpp = (dw & 0x02) != 0;
settings_.vppOePin = (dw & 0x04) != 0;
settings_.pgmCePin = (dw & 0x08) != 0;
settings_.pgmPositive = (dw & 0x10) != 0;
// clang-format on
serial_.putChar(kCmdResponseOk);
break;
case kCmdDeviceSetupBus:
dw = getParamAsByte_();
if (deviceSetupBus_(dw)) {
serial_.putChar(kCmdResponseOk);
} else {
serial_.putChar(kCmdResponseNok);
}
break;
default:
break;
}
Expand Down Expand Up @@ -474,8 +481,6 @@ void Runner::runDeviceReadCommand_(uint8_t opcode) {

void Runner::runDeviceWriteCommand_(uint8_t opcode) {
uint16_t w;
TByteArray response;
bool success = false;
switch (opcode) {
case kCmdDeviceWrite:
if (deviceWriteAndVerify_(w, true) && addrBus_.increment()) {
Expand All @@ -498,8 +503,6 @@ void Runner::runDeviceWriteCommand_(uint8_t opcode) {

void Runner::runDeviceVerifyCommand_(uint8_t opcode) {
uint16_t w;
TByteArray response;
bool success = false;
switch (opcode) {
case kCmdDeviceVerify:
if (deviceVerify_(w, true) && addrBus_.increment()) {
Expand All @@ -520,6 +523,41 @@ void Runner::runDeviceVerifyCommand_(uint8_t opcode) {
}
}

void Runner::runDeviceGetIdCommand_(uint8_t opcode) {
uint16_t w;
TByteArray response;
switch (opcode) {
case kCmdDeviceGetId:
if (deviceGetId_(w)) {
// response
response.resize(3);
response[0] = kCmdResponseOk;
createParamsFromWord_(&response, w);
serial_.putBuf(response.data(), response.size());
} else {
serial_.putChar(kCmdResponseNok);
}
break;
default:
break;
}
}

void Runner::runDeviceEraseCommand_(uint8_t opcode) {
switch (opcode) {
case kCmdDeviceErase:
if (deviceErase_()) {
// response
serial_.putChar(kCmdResponseOk);
} else {
serial_.putChar(kCmdResponseNok);
}
break;
default:
break;
}
}

void Runner::deviceRead_(uint16_t &data, bool is16bit) {
// ~OE/VPP is LO
if (settings_.vppOePin) vgen_.vdd.onVpp(false);
Expand Down Expand Up @@ -623,6 +661,147 @@ bool Runner::deviceWriteAndVerify_(uint16_t &data, bool is16bit) {
return (rd == wr);
}

bool Runner::deviceSetupBus_(uint8_t operation) {
bool success = true;
// reset bus
// VDD off and VPP off
vgen_.vdd.off();
vgen_.vpp.off();
vgen_.vdd.onVpp(false);
// Clear AddrBus
if (!addrBus_.writeDWord(0)) success = false;
// ~OE is HI
ctrlBus_.setOE(false);
// ~CE is HI
ctrlBus_.setCE(false);
if (settings_.pgmPositive) {
// PGM is LO (no prog pulse)
ctrlBus_.setWE(true);
} else {
// ~PGM is HI (no prog pulse)
ctrlBus_.setWE(false);
}
// VPP on xx disabled
vgen_.vpp.onA9(false);
vgen_.vpp.onA18(false);
vgen_.vpp.onCE(false);
vgen_.vpp.onOE(false);
vgen_.vpp.onWE(false);
// Clear DataBus
if (!dataBus_.writeWord(0)) success = false;

// setupbus
switch (operation) {
case kCmdDeviceOperationRead:
// VDD Rd on
vgen_.vdd.on();
// VDD Rd on VPP
vgen_.vdd.onVpp();
if (settings_.pgmCePin) {
// PGM/~CE is LO
ctrlBus_.setWE(true);
} else {
// ~PGM is HI
ctrlBus_.setWE(false);
}
// ~CE is LO (if pin connected)
ctrlBus_.setCE(true);
break;
case kCmdDeviceOperationProg:
// VDD Wr on
vgen_.vdd.on();
if (settings_.pgmPositive) {
// PGM is LO
ctrlBus_.setWE(true);
} else {
// ~PGM is HI
ctrlBus_.setWE(false);
}
// ~CE is LO (if pin connected)
ctrlBus_.setCE(true);
break;
case kCmdDeviceOperationGetId:
// VDD Rd on
vgen_.vdd.on();
if (settings_.pgmCePin) {
// PGM/~CE is LO
ctrlBus_.setWE(true);
} else {
// ~PGM is HI
ctrlBus_.setWE(false);
}
// ~CE is LO (if pin connected)
ctrlBus_.setCE(true);
if (!settings_.vppOePin) {
// VDD Rd on VPP
vgen_.vdd.onVpp(true);
}
// ~OE is LO
ctrlBus_.setOE(true);
// VPP on A9
vgen_.vpp.onA9(true);
break;
case kCmdDeviceOperationReset:
default:
break;
}
sleep_us(kStabilizationTime);
return success;
}

bool Runner::deviceGetId_(uint16_t &data) {
// Setup bus
if (!deviceSetupBus_(kCmdDeviceOperationGetId)) return false;
bool success = true;
uint8_t manufacturer, device;
// Get manufacturer data (byte)
manufacturer = dataBus_.readByte();
// Increment Address (0x01)
if (!addrBus_.increment()) success = false;
// Get device data (byte)
device = dataBus_.readByte();
// If success, return data
if (success) {
data = manufacturer;
data <<= 8;
data |= device;
}
// Close resources
deviceSetupBus_(kCmdDeviceOperationReset);
return success;
}

bool Runner::deviceErase_() {
bool success = true;
// Erase entire chip
// 27E Algorithm
// Addr = 0
if (!addrBus_.writeDWord(0)) success = false;
// Data = 0xFF
if (!dataBus_.writeWord(0xFFFF)) success = false;
// VPP on A9
vgen_.vpp.onA9(true);
if (settings_.pgmPositive) {
// PGM is HI (start erase pulse)
ctrlBus_.setWE(false);
sleep_ms(kErasePulseDuration); // Erase Pulse
// PGM is LO (end erase pulse)
ctrlBus_.setWE(true);
} else {
// ~PGM is LO (start erase pulse)
ctrlBus_.setWE(true);
sleep_ms(kErasePulseDuration); // Erase Pulse
// ~PGM is HI (end erase pulse)
ctrlBus_.setWE(false);
}
sleep_us(settings_.twc); // tWC uS
// VPP on A9 off
vgen_.vpp.onA9(false);
// PGM/~CE is LO
if (settings_.pgmCePin) ctrlBus_.setWE(true);
return success;
}

bool Runner::getParamAsBool_() {
return (OpCode::getValueAsBool(command_.data(), command_.size()));
}
Expand Down Expand Up @@ -657,4 +836,4 @@ void Runner::createParamsFromWord_(TByteArray *response, u_int16_t src) {

void Runner::createParamsFromDWord_(TByteArray *response, u_int32_t src) {
OpCode::setDWord(response->data(), response->size(), src);
}
}
Loading

0 comments on commit afc6460

Please sign in to comment.