diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/AvrIspCommandFrame.hpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/AvrIspCommandFrame.hpp new file mode 100644 index 00000000..157253df --- /dev/null +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/AvrIspCommandFrame.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "src/Exceptions/Exception.hpp" +#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/Avr8Generic.hpp" +#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AvrCommandFrame.hpp" +#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/ResponseFrames/AVRISP/AvrIspResponseFrame.hpp" + +namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames::AvrIsp +{ + template + class AvrIspCommandFrame: public AvrCommandFrame + { + public: + using ExpectedResponseFrameType = ResponseFrames::AvrIsp::AvrIspResponseFrame; + + AvrIspCommandFrame(): AvrCommandFrame(ProtocolHandlerId::AVRISP) {} + }; +} diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/EnterProgrammingMode.hpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/EnterProgrammingMode.hpp new file mode 100644 index 00000000..bdb2276a --- /dev/null +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/EnterProgrammingMode.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include + +#include "AvrIspCommandFrame.hpp" + +namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames::AvrIsp +{ + class EnterProgrammingMode: public AvrIspCommandFrame> + { + public: + EnterProgrammingMode( + std::uint8_t timeout, + std::uint8_t stabDelay, + std::uint8_t commandExecutionDelay, + std::uint8_t syncLoops, + std::uint8_t byteDelay, + std::uint8_t pollValue, + std::uint8_t pollIndex + ) { + /* + * The enter programming mode command consists of 12 bytes: + * + * 1. Command ID (0x10) + * + * -- The fields from this point are taken from the AVR8 TDFs -- + * + * 2. Command timeout in milliseconds + * 3. Pin stabilization delay in milliseconds + * 4. Command execution delay in milliseconds + * 5. Number of synchronisation loops + * 6. Millisecond delay between each byte in the command + * 7. Poll value + * 8. Poll index + * + * -- The fields from this point are the four bytes of the low-level SPI command -- + * + * 9. CMD1 - For the enter programming mode command, this appears to always be 0xAC + * 10. CMD2 - For AVR8 targets, this also appears to be a fixed value of 0x53 + * 11. CMD3 - 0x00 + * 12. CMD4 - 0x00 + */ + this->payload = { + 0x10, + timeout, + stabDelay, + commandExecutionDelay, + syncLoops, + byteDelay, + pollValue, + pollIndex, + 0xAC, + 0x53, + 0x00, + 0x00, + }; + } + }; +} diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/LeaveProgrammingMode.hpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/LeaveProgrammingMode.hpp new file mode 100644 index 00000000..e65e1dae --- /dev/null +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/LeaveProgrammingMode.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include + +#include "AvrIspCommandFrame.hpp" + +namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames::AvrIsp +{ + class LeaveProgrammingMode: public AvrIspCommandFrame> + { + public: + LeaveProgrammingMode( + std::uint8_t preDelay, + std::uint8_t postDelay + ) { + /* + * The leave programming mode command consists of 3 bytes: + * + * 1. Command ID (0x11) + * + * -- The fields from this point are taken from the AVR8 TDFs -- + * + * 2. Pre-delay + * 3. Post-delay + */ + this->payload = { + 0x11, + preDelay, + postDelay, + }; + } + }; +} diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/ReadFuse.hpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/ReadFuse.hpp new file mode 100644 index 00000000..3500da83 --- /dev/null +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/ReadFuse.hpp @@ -0,0 +1,65 @@ +#pragma once + +#include +#include + +#include "AvrIspCommandFrame.hpp" + +#include "src/Targets/Microchip/AVR/Fuse.hpp" + +namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames::AvrIsp +{ + class ReadFuse: public AvrIspCommandFrame> + { + public: + ReadFuse( + Targets::Microchip::Avr::FuseType fuseType, + std::uint8_t returnAddress + ) { + using Targets::Microchip::Avr::FuseType; + + /* + * The read fuse command consists of 6 bytes: + * + * 1. Command ID (0x18) + * 2. Return Address + * 3. CMD1 + * 4. CMD2 + * 5. CMD3 + * 6. CMD4 + */ + this->payload = { + 0x18, + returnAddress, + 0x00, + 0x00, + 0x00, + 0x00, + }; + + switch (fuseType) { + case FuseType::LOW: { + this->payload[2] = 0x50; + this->payload[3] = 0x00; + this->payload[4] = 0x00; + this->payload[5] = 0x00; + break; + } + case FuseType::HIGH: { + this->payload[2] = 0x58; + this->payload[3] = 0x08; + this->payload[4] = 0x00; + this->payload[5] = 0x00; + break; + } + case FuseType::EXTENDED: { + this->payload[2] = 0x50; + this->payload[3] = 0x08; + this->payload[4] = 0x00; + this->payload[5] = 0x00; + break; + } + } + } + }; +} diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/ReadSignature.hpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/ReadSignature.hpp new file mode 100644 index 00000000..e01cadc4 --- /dev/null +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVRISP/ReadSignature.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +#include "AvrIspCommandFrame.hpp" + +#include "src/Targets/Microchip/AVR/Fuse.hpp" + +namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames::AvrIsp +{ + class ReadSignature: public AvrIspCommandFrame> + { + public: + ReadSignature( + std::uint8_t signatureByteAddress, + std::uint8_t returnAddress + ) { + using Targets::Microchip::Avr::FuseType; + + /* + * The read signature command consists of 6 bytes: + * + * 1. Command ID (0x1B) + * 2. Return Address + * 3. CMD1 + * 4. CMD2 + * 5. CMD3 + * 6. CMD4 + */ + this->payload = { + 0x1B, + returnAddress, + 0x30, + 0x00, + static_cast(signatureByteAddress & 0x03), + 0x00, + }; + } + }; +} diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/Edbg.hpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/Edbg.hpp index 6fb3532e..a73e3895 100644 --- a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/Edbg.hpp +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/Edbg.hpp @@ -6,6 +6,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg { DISCOVERY = 0x00, HOUSE_KEEPING = 0x01, + AVRISP = 0x11, AVR8_GENERIC = 0x12, AVR32_GENERIC = 0x13, };