HF-TMC9660 Driver 0.1.0-dev
Hardware Agnostic C++ Driver for the TMC9660
Loading...
Searching...
No Matches
bootloader_protocol.hpp
Go to the documentation of this file.
1
6#pragma once
8#include <array>
9#include <cstddef>
10#include <cstdint>
11
12namespace tmc9660 {
13
24enum class BootloaderStatus : uint8_t {
25 OK = 0,
26 CMD_NOT_FOUND = 1,
27 INVALID_ADDR = 3,
28 INVALID_VALUE = 4,
29 INVALID_BANK = 14,
30 BUSY = 15,
31 MEM_UNCONFIGURED = 17,
32 OTP_ERROR = 18,
33 SESSION_START = 19,
36 21
37};
38
49enum class BootloaderCommand : uint8_t {
50 GET_INFO = 0,
51 GET_BANK = 8,
52 SET_BANK = 9,
53 GET_ADDRESS = 10,
54 SET_ADDRESS = 11,
55 READ_32 = 12,
56 READ_32_INC = 13,
57 READ_16 = 14,
58 READ_16_INC = 15,
59 READ_8 = 16,
60 READ_8_INC = 17,
61 WRITE_32 = 18,
62 WRITE_32_INC = 19,
63 WRITE_16 = 20,
64 WRITE_16_INC = 21,
65 WRITE_8 = 22,
66 WRITE_8_INC = 23,
67 NO_OP = 29,
68 OTP_LOAD = 30,
69 OTP_BURN = 31,
71 MEM_IS_CONNECTED = 33,
72 FLASH_SEND_CMD = 36,
74 MEM_IS_BUSY = 40,
75 BOOTSTRAP_RS485 = 255
76};
77
86enum class MemoryBank : uint8_t {
87 RAM = 0,
88 OTP = 1,
89 SPI_FLASH = 2,
90 I2C_EEPROM = 3,
91 RESERVED = 4,
92 CONFIG = 5
93};
94
105enum class InfoQuery : uint32_t {
106 CHIP_TYPE = 0,
107 BL_VERSION = 1,
108 FEATURES = 2,
109 GIT_INFO = 12,
110 CHIP_VERSION = 13,
111 CHIP_FREQUENCY = 14,
112 CONFIG_MEM_START = 17,
113 CONFIG_MEM_SIZE = 18,
114 OTP_MEM_SIZE = 19,
115 I2C_MEM_SIZE = 20,
116 SPI_MEM_SIZE = 21,
117 PARTITION_VERSION = 22,
118 SPI_MEM_PARTITIONS = 25,
119 I2C_MEM_PARTITIONS = 26,
120 CHIP_VARIANT = 28
121};
122
133 uint16_t major;
134 uint16_t minor;
135
137 static BootloaderVersion fromValue(uint32_t value) noexcept {
139 v.major = static_cast<uint16_t>(value >> 16);
140 v.minor = static_cast<uint16_t>(value & 0xFFFF);
141 return v;
142 }
143};
144
153 bool rom;
154 bool otp;
157
159 static BootloaderFeatures fromValue(uint32_t value) noexcept {
161 f.sram_support = (value & (1u << 0)) != 0;
162 f.rom = (value & (1u << 1)) != 0;
163 f.otp = (value & (1u << 2)) != 0;
164 f.spi_flash = (value & (1u << 3)) != 0;
165 f.i2c_eeprom = (value & (1u << 4)) != 0;
166 return f;
167 }
168};
169
177struct GitInfo {
178 bool dirty;
179 uint32_t commit_hash;
180
182 static GitInfo fromValue(uint32_t value) noexcept {
183 GitInfo g;
184 g.dirty = (value & (1u << 28)) != 0;
185 g.commit_hash = value & 0x0FFFFFFF;
186 return g;
187 }
188};
189
198 uint8_t major;
199 uint8_t minor;
200
202 static PartitionVersion fromValue(uint32_t value) noexcept {
204 v.major = static_cast<uint8_t>((value >> 8) & 0xFF);
205 v.minor = static_cast<uint8_t>(value & 0xFF);
206 return v;
207 }
208};
209
218 uint8_t errorCount;
219 uint8_t pageTag;
220
222 static OtpLoadResult fromValue(uint32_t value) noexcept {
223 OtpLoadResult result;
224 result.errorCount = static_cast<uint8_t>((value >> 8) & 0xFF);
225 result.pageTag = static_cast<uint8_t>(value & 0xFF);
226 return result;
227 }
228};
229
239enum class OtpBurnError : int8_t {
240 INVALID_PAGE = -1,
241 NO_MORE_BURNS = -2,
242 CHARGE_PUMP_FAILED = -3,
244 CLOCK_SETUP_FAILED = -5,
246};
247
258 const char* errorDescription;
259
261 static OtpBurnResult createSuccess() noexcept {
262 OtpBurnResult result;
263 result.isSuccess = true;
264 result.errorCode = static_cast<OtpBurnError>(0);
265 result.errorDescription = "Success";
266 return result;
267 }
268
270 static OtpBurnResult createError(OtpBurnError code) noexcept {
271 OtpBurnResult result;
272 result.isSuccess = false;
273 result.errorCode = code;
274
275 switch (code) {
277 result.errorDescription = "Invalid OTP page number";
278 break;
280 result.errorDescription = "Last OTP page burnt, no more burns possible";
281 break;
283 result.errorDescription = "Setting up internal OTP charge pump failed";
284 break;
286 result.errorDescription = "The burn procedure failed";
287 break;
289 result.errorDescription = "Internal clock setup for OTP operation failed";
290 break;
292 result.errorDescription = "Restoring original clock setup after OTP operation failed";
293 break;
294 default:
295 result.errorDescription = "Unknown error";
296 break;
297 }
298
299 return result;
300 }
301};
302
313 uint8_t command;
314 uint32_t value;
315
317 void toBuffer(std::array<uint8_t, 5>& out) const noexcept {
318 out[0] = command;
319 out[1] = static_cast<uint8_t>(value >> 24);
320 out[2] = static_cast<uint8_t>(value >> 16);
321 out[3] = static_cast<uint8_t>(value >> 8);
322 out[4] = static_cast<uint8_t>(value);
323 }
324};
325
336 uint8_t deviceAddr;
337 uint8_t command;
338 uint32_t value;
339
341 void toBuffer(std::array<uint8_t, 8>& out) const noexcept {
342 out[0] = 0x55; // Sync byte
343 out[1] = deviceAddr;
344 out[2] = command;
345 out[3] = static_cast<uint8_t>(value >> 24); // MSB first
346 out[4] = static_cast<uint8_t>(value >> 16);
347 out[5] = static_cast<uint8_t>(value >> 8);
348 out[6] = static_cast<uint8_t>(value);
349 out[7] = crc8Bootloader(out.data(), 7); // CRC over first 7 bytes
350 }
351};
352
363 uint8_t status;
364 uint32_t value;
365
367 static BootloaderReplySPI fromBuffer(const std::array<uint8_t, 5>& in) noexcept {
369 r.status = in[0];
370 r.value = (static_cast<uint32_t>(in[1]) << 24) | (static_cast<uint32_t>(in[2]) << 16) |
371 (static_cast<uint32_t>(in[3]) << 8) | static_cast<uint32_t>(in[4]);
372 return r;
373 }
374
376 bool isOK() const noexcept {
377 return status == static_cast<uint8_t>(BootloaderStatus::OK) ||
378 status == static_cast<uint8_t>(BootloaderStatus::SESSION_START) ||
379 status == static_cast<uint8_t>(BootloaderStatus::BOOTLOADER_RESUMED);
380 }
381
383 BootloaderStatus getStatus() const noexcept {
384 return static_cast<BootloaderStatus>(status);
385 }
386};
387
398 uint8_t hostAddr;
399 uint8_t deviceAddr;
400 uint8_t status;
401 uint32_t value;
402
404 static BootloaderReplyUART fromBuffer(const std::array<uint8_t, 8>& in) noexcept {
406 // UART protocol: [HOST_ADDR] [DEVICE_ADDR] [STATUS] [VALUE(32)] [CRC8]
407 // (No SYNC byte in reply, unlike the request which has 0x55 as first byte)
408 r.hostAddr = in[0];
409 r.deviceAddr = in[1];
410 r.status = in[2];
411 r.value = (static_cast<uint32_t>(in[3]) << 24) | // MSB first
412 (static_cast<uint32_t>(in[4]) << 16) | (static_cast<uint32_t>(in[5]) << 8) |
413 static_cast<uint32_t>(in[6]);
414 // Note: in[7] is CRC8, should be verified
415 return r;
416 }
417
419 bool verifyCRC(const std::array<uint8_t, 8>& in) const noexcept {
420 uint8_t calculatedCRC = crc8Bootloader(in.data(), 7);
421 return calculatedCRC == in[7];
422 }
423
425 bool isOK() const noexcept {
426 return status == static_cast<uint8_t>(BootloaderStatus::OK);
427 }
428
430 BootloaderStatus getStatus() const noexcept {
431 return static_cast<BootloaderStatus>(status);
432 }
433};
434
435} // namespace tmc9660
TMC9660 bootloader utility functions and helpers.
Definition bootloader_config.hpp:9
OtpBurnError
OTP burn operation error codes.
Definition bootloader_protocol.hpp:239
@ CHARGE_PUMP_FAILED
Setting up internal OTP charge pump failed.
@ BURN_PROCEDURE_FAILED
The burn procedure failed.
@ CLOCK_RESTORE_FAILED
Restoring original clock setup after OTP operation failed.
@ INVALID_PAGE
The OTP page number is invalid.
@ CLOCK_SETUP_FAILED
Internal clock setup for OTP operation failed.
@ NO_MORE_BURNS
Last OTP page burnt, no more burns possible.
static constexpr uint8_t crc8Bootloader(const uint8_t *data, size_t len) noexcept
CRC-8 calculation for UART protocol (TMC9660 datasheet method).
Definition bootloader_utils.hpp:54
MemoryBank
Memory bank identifiers for bootloader operations.
Definition bootloader_protocol.hpp:86
@ SPI_FLASH
External SPI Flash.
@ CONFIG
Configuration memory (runtime reconfiguration)
@ OTP
OTP memory.
@ RAM
Internal RAM.
@ I2C_EEPROM
External I2C EEPROM.
BootloaderCommand
Bootloader command codes for memory and configuration operations.
Definition bootloader_protocol.hpp:49
@ READ_32_INC
Read 32-bit data and increment address.
@ BOOTSTRAP_RS485
Set up RS485 settings.
@ NO_OP
No operation (for retrieving previous reply in SPI)
@ WRITE_8
Write 8-bit data to selected memory bank/address.
@ OTP_BURN
Burn an OTP page.
@ READ_16
Read 16-bit data from selected memory bank/address.
@ GET_ADDRESS
Get the current memory address.
@ READ_16_INC
Read 16-bit data and increment address.
@ MEM_IS_BUSY
Check whether an external memory is busy.
@ WRITE_16_INC
Write 16-bit data and increment address.
@ SET_ADDRESS
Set the memory address.
@ MEM_IS_CONNECTED
Check whether an external memory is connected.
@ FLASH_SEND_CMD
Send arbitrary commands to an external flash.
@ READ_32
Read 32-bit data from selected memory bank/address.
@ MEM_IS_CONFIGURED
Check whether an external memory bank is configured.
@ GET_BANK
Get the currently selected memory bank.
@ WRITE_32
Write 32-bit data to selected memory bank/address.
@ FLASH_ERASE_SECTOR
Send a sector erase command to an external flash.
@ WRITE_16
Write 16-bit data to selected memory bank/address.
@ OTP_LOAD
Read a programmed OTP page.
@ WRITE_32_INC
Write 32-bit data and increment address.
@ GET_INFO
Get various basic information about the connected TMC9660.
@ SET_BANK
Set the memory bank.
@ WRITE_8_INC
Write 8-bit data and increment address.
@ READ_8
Read 8-bit data from selected memory bank/address.
@ READ_8_INC
Read 8-bit data and increment address.
BootloaderStatus
Bootloader status codes returned by command replies.
Definition bootloader_protocol.hpp:24
@ BOOTLOADER_RESUMED
First SPI datagram after returning to bootloader from motor control (SPI only)
@ SESSION_START
First SPI datagram after power-on (SPI only)
@ MEM_UNCONFIGURED
The external memory is not configured.
@ INVALID_BANK
The memory bank is not valid for the requested command.
@ INVALID_ADDR
The memory address is not valid for the requested command.
@ CMD_NOT_FOUND
The request has an invalid command number.
@ BUSY
Bootloader has not yet finished processing the last command (SPI only)
@ INVALID_VALUE
The request has an invalid value.
@ CMD_NOT_AVAILABLE
The command is currently not available.
@ OTP_ERROR
The OTP command has failed.
@ OK
Command executed successfully.
InfoQuery
GET_INFO query types for retrieving system information.
Definition bootloader_protocol.hpp:105
@ CHIP_TYPE
Get the Chip type (returns 0x544D0001)
@ CONFIG_MEM_SIZE
Get size of CONFIG memory.
@ CONFIG_MEM_START
Get starting address of CONFIG memory.
@ SPI_MEM_SIZE
Get memory size of connected SPI memory.
@ OTP_MEM_SIZE
Get size of one OTP memory page.
@ PARTITION_VERSION
Get version of external memory partition format.
@ GIT_INFO
Get Git version control information.
@ SPI_MEM_PARTITIONS
Get number of SPI memory partitions.
@ BL_VERSION
Get bootloader version (major in upper 16 bits, minor in lower 16 bits)
@ FEATURES
Get available feature groups (bit flags)
@ CHIP_VARIANT
Get chip variant (TMC9660 reports value 2)
@ I2C_MEM_SIZE
Get memory size of connected I2C memory.
@ I2C_MEM_PARTITIONS
Get number of I2C memory partitions.
@ CHIP_FREQUENCY
Get system frequency in MHz.
@ CHIP_VERSION
Get silicon revision (TMC9660 reports revision 1)
Bootloader command structure for SPI (40-bit / 5-byte protocol).
Definition bootloader_protocol.hpp:312
void toBuffer(std::array< uint8_t, 5 > &out) const noexcept
Serialize to 5-byte buffer for SPI transmission.
Definition bootloader_protocol.hpp:317
uint8_t command
Command byte.
Definition bootloader_protocol.hpp:313
uint32_t value
32-bit data value
Definition bootloader_protocol.hpp:314
Bootloader command structure for UART (64-bit / 8-byte protocol).
Definition bootloader_protocol.hpp:335
void toBuffer(std::array< uint8_t, 8 > &out) const noexcept
Serialize to 8-byte buffer for UART transmission.
Definition bootloader_protocol.hpp:341
uint8_t command
Command byte.
Definition bootloader_protocol.hpp:337
uint8_t deviceAddr
Device address.
Definition bootloader_protocol.hpp:336
uint32_t value
32-bit data value
Definition bootloader_protocol.hpp:338
Feature flags indicating available bootloader capabilities.
Definition bootloader_protocol.hpp:151
static BootloaderFeatures fromValue(uint32_t value) noexcept
Parse from 32-bit value.
Definition bootloader_protocol.hpp:159
bool rom
Bit 1: ROM.
Definition bootloader_protocol.hpp:153
bool sram_support
Bit 0: SRAM support.
Definition bootloader_protocol.hpp:152
bool otp
Bit 2: OTP.
Definition bootloader_protocol.hpp:154
bool spi_flash
Bit 3: SPI flash external memory.
Definition bootloader_protocol.hpp:155
bool i2c_eeprom
Bit 4: I2C EEPROM external memory.
Definition bootloader_protocol.hpp:156
Bootloader reply structure for SPI (40-bit / 5-byte protocol).
Definition bootloader_protocol.hpp:362
bool isOK() const noexcept
Check if reply indicates success.
Definition bootloader_protocol.hpp:376
static BootloaderReplySPI fromBuffer(const std::array< uint8_t, 5 > &in) noexcept
Deserialize from 5-byte SPI buffer.
Definition bootloader_protocol.hpp:367
BootloaderStatus getStatus() const noexcept
Get status as enum.
Definition bootloader_protocol.hpp:383
uint8_t status
Status byte.
Definition bootloader_protocol.hpp:363
uint32_t value
32-bit data value
Definition bootloader_protocol.hpp:364
Bootloader reply structure for UART (64-bit / 8-byte protocol).
Definition bootloader_protocol.hpp:397
uint8_t hostAddr
Host address.
Definition bootloader_protocol.hpp:398
static BootloaderReplyUART fromBuffer(const std::array< uint8_t, 8 > &in) noexcept
Deserialize from 8-byte UART buffer.
Definition bootloader_protocol.hpp:404
uint32_t value
32-bit data value
Definition bootloader_protocol.hpp:401
bool verifyCRC(const std::array< uint8_t, 8 > &in) const noexcept
Verify CRC8 checksum.
Definition bootloader_protocol.hpp:419
BootloaderStatus getStatus() const noexcept
Get status as enum.
Definition bootloader_protocol.hpp:430
uint8_t deviceAddr
Device address.
Definition bootloader_protocol.hpp:399
bool isOK() const noexcept
Check if reply indicates success.
Definition bootloader_protocol.hpp:425
uint8_t status
Status byte.
Definition bootloader_protocol.hpp:400
Bootloader version information structure.
Definition bootloader_protocol.hpp:132
uint16_t major
Major version number.
Definition bootloader_protocol.hpp:133
uint16_t minor
Minor version number.
Definition bootloader_protocol.hpp:134
static BootloaderVersion fromValue(uint32_t value) noexcept
Parse from 32-bit value (major in upper 16 bits, minor in lower 16 bits)
Definition bootloader_protocol.hpp:137
Git version control information from bootloader firmware.
Definition bootloader_protocol.hpp:177
uint32_t commit_hash
Bits 27-0: 7-digit hex commit hash.
Definition bootloader_protocol.hpp:179
static GitInfo fromValue(uint32_t value) noexcept
Parse from 32-bit value.
Definition bootloader_protocol.hpp:182
bool dirty
Bit 28: Dirty bit - uncommitted changes.
Definition bootloader_protocol.hpp:178
OTP burn operation result information.
Definition bootloader_protocol.hpp:255
static OtpBurnResult createSuccess() noexcept
Create success result.
Definition bootloader_protocol.hpp:261
const char * errorDescription
Human-readable error description.
Definition bootloader_protocol.hpp:258
bool isSuccess
Whether the burn operation succeeded.
Definition bootloader_protocol.hpp:256
OtpBurnError errorCode
Error code if operation failed.
Definition bootloader_protocol.hpp:257
static OtpBurnResult createError(OtpBurnError code) noexcept
Create error result.
Definition bootloader_protocol.hpp:270
OTP load operation result information.
Definition bootloader_protocol.hpp:217
uint8_t pageTag
OTP page tag (bits 7-0)
Definition bootloader_protocol.hpp:219
uint8_t errorCount
OTP bit error count (bits 15-8)
Definition bootloader_protocol.hpp:218
static OtpLoadResult fromValue(uint32_t value) noexcept
Parse from 32-bit value.
Definition bootloader_protocol.hpp:222
External memory partition version information.
Definition bootloader_protocol.hpp:197
uint8_t minor
Bits 7-0: Minor version.
Definition bootloader_protocol.hpp:199
uint8_t major
Bits 15-8: Major version.
Definition bootloader_protocol.hpp:198
static PartitionVersion fromValue(uint32_t value) noexcept
Parse from 32-bit value.
Definition bootloader_protocol.hpp:202